ZombieChowder
ZombieChowder

Reputation: 1204

Change html slider step exponentially

I am trying to change the slider step by the power of 10 on each slide but it's not working correctly. I am unsure if I should use stepUp() or change the value of value of step directly.

This is how I increment by the power of 10:

var increment = (function(n) {
  return function() {
    n = n + 2;
    var x = Math.pow(10, n);
    console.log(x +" " + "Math.Pow thingy");
    return x;
  }

Here is how I try to pass it as an argument:

document.getElementById("something").stepUp(increment);

In case anyone is wondering, here is the stepUp() that I am using.

Also, here is a fiddle of my slider: Slider Fiddle #1

I want my slider to step to change to 10,100,1000,10000 on each slide.

Upvotes: 1

Views: 3409

Answers (3)

Roamer-1888
Roamer-1888

Reputation: 19288

The natural behaviour of <input type="range" /> is linear, so you have to engineer the required mapping of natural values to required values.

What you are looking for is slider with a socalled log-linear action such that the slider is set up to yield the logarithm of the values you ultimately want;

<input id="something" name="something" type="range" min="2" max="5" value="3" step="1" class="form-control slider" />

Here, the critical settings are

  • min="2" - log-base10(100) == 2
  • max="5" - log-base10(100000) == 5
  • value="3" - log-base10(1000) == 3

Then to get back to the values you actually want, you have to do an anti-logarithm, or Math.pow(10, x).

var slider = document.getElementById('something');
var output = document.getElementById('demo');
slider.onchange = function() {
    output.innerHTML = Math.pow(10, this.value);
}
slider.onchange(); // set output for the initial value

DEMO

EDIT:

The behaviour of an <input type="range" /> slider element is inescapably linear. At its current state of development, HTML offers nothing else.

In order to submit the value you actually want, you can use your slider field as the UI for an underlying hidden field, the value of which is maintained to hold a transform of the linear element's value. Providing you can write code to perform the transformation, you are in business. In this case, it's simple - antilogarithm.

So your HTML might be something like this :

<input id="something-ui" type="range" min="2" max="5" value="3" step="1" class="form-control slider" />
<input id="something-hidden" name="something" type="hidden" />

And the corresponding javascript :

var slider = document.getElementById('something-ui');
var hidden = document.getElementById('something-hidden');
var output = document.getElementById('demo');
slider.oninput = function() { // or onChange
    output.innerHTML = hidden.value = Math.pow(10, this.value); // antilogarithm
}
slider.oninput(); // set hidden value and output for the initial value  

So now, the UI control still behaves linearly but is given (by demo) the appearance, and a submit behaviour (by something-hidden), of being exponential.

Upvotes: 1

A. L
A. L

Reputation: 12649

Pretty sure you can't really do it your way, you'll need to do some kind of calculation yourself. Step only works for constant numbers

var input = document.getElementById("input")
var output = document.getElementById("output")

function getValue() {
  let power = input.value
  let result = Math.pow(10, +power)
  output.value = result
}
<input id="input" type="range" min="1" max="10" value="1" oninput="getValue()" />

<input type="text" id="output" value="10"/>

Upvotes: 4

Chirag Ravindra
Chirag Ravindra

Reputation: 4830

This is one way to do this

// Get DOM refs for the required elements
var slider = document.getElementById('myRange');
var res = document.getElementById('res');
var inc = document.getElementById('inc');

// Initialize Div to show starting value
res.innerHTML = slider.value;

// Register on change handler to update div value if slider is changed
slider.onchange = function(){
  res.innerHTML = this.value;
}

// Register a click handler inside a closure to increment exponentially
inc.onclick = (function(){
    // Initial increment value
    var n = 1;
    // Return a click handler function which has access to the variable n because of the closure
    return function(){
      // Button is clicked, increment by n
      slider.stepUp(n);
      // Update div value for display
      res.innerHTML = slider.value;
      // Multilply n by 10 so the next time the increment is 10x
      n *= 10;
    }
})()
<input type="range" id="myRange" value="1000" min="1" max="1000">
<div id="res"></div>

<button id="inc">Increment</button>

Upvotes: 0

Related Questions