Summary
I need a range input with numbers from 1,000 to 10,000,000. Due to the large range it can't be linear. So each time the decimal length increases (e.g. from 1000 to 10000) the steps should also increase.
#--------------------#--------------------#--------------------#--------------------#
0 1000 5000 9000 10,000 56,498 100,000 500,000 1,000,000 10,000,000
Failed attempts
I already tried to create a slider range from 1 to 5 (to have 4 steps) and interpolate the values but I couldn't get it to work so the steps increased at the same time when the decimal increased.
Also I tried this solution: Logarithmic slider It's better than a linear behavior but still the steps in the beginning (left) are too small and too large in the end (right end of range slider).
Additional requirement
This range slider also has to be connected to an input field. So the input value also has to be written back to the slider (so some kind of inverse calculation input <-> range slider).
Adjusted version of the Logarithmic Slider solution linked above:
function LogSlider(options) {
options = options || {};
this.minpos = options.minpos || 0;
this.maxpos = options.maxpos || 100;
this.minlval = Math.log(options.minval || 1);
this.maxlval = Math.log(options.maxval || 100000);
this.scale = (this.maxlval - this.minlval) / (this.maxpos - this.minpos);
}
LogSlider.prototype = {
// Calculate value from a slider position
value: function(position) {
return Math.exp((position - this.minpos) * this.scale + this.minlval);
},
// Calculate slider position from a value
position: function(value) {
return this.minpos + (Math.log(value) - this.minlval) / this.scale;
}
};
// Usage:
var logsl = new LogSlider({maxpos: 300, minval: 1000, maxval: 10000000});
$('#slider').on('change input', function() {
var val = logsl.value(+$(this).val());
// console.log(val);
var rounded = Math.round(val / 1000) * 1000;
var localized = rounded.toLocaleString('DE');
$('#value').val(localized);
});
$('#value').on('keyup', function() {
var val = +($(this).val().toString().replace(/[\D]/g,''));
//console.log(this.value, val);
var pos = logsl.position(val);
//console.log(pos);
$('#slider').val(pos);
});
$('#value').val("10000").trigger("keyup");
#slider {
width: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Input value or use slider:
<input id="value" />
<input id="slider" type="range" min="0" max="300" />
The smallest steps are 1,000. Here you can see, between 1,000 and 2,000 there are around 20 px space. But on very high numbers, the steps are up to over 300,000. So not the best user experience. You should at least be able to input in steps of 100,000 as illustrated above.