Change html slider step exponentially - javascript

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.

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"/>

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.

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>

Related

I created a range slider that has a value 1-5. How can I add a warning message alerting the user when they set the value higher than 2

I used a bootstrap range slider and, used JavaScript for the range value to be 1 through 5. Now I need to know how to make some sort of pop up warning message saying the range value is too high if its over than 2.
Html:
<input type="range" class="form-range" name="depth" id="depth_area" value="0" min="0" max="5">
<p>Value: <span id="value"></span></p>
JavaScript:
var slider = document.getElementById("depth_area");
var output = document.getElementById("value");
output.innerHTML = slider.value;
slider.oninput = function () {
output.innerHTML = this.value;
};

when i edit span the range filter updates itself

I am just trying to make range filter can be changeable not by dragging the filter, but by typing the value. The value its self updates in console.log, but visually doesn`t just stays on one place (and then I have a problem to take value by $_POST method.
<input id="range_filter" class="range-slider__range sum" type="range" value="10000" min="5000" max="100000" oninput="editor.value = range_filter.value">
<span contenteditable="true" id="editor" class="range-slider__value">0</span>
function edit() {
//console.log("input event fired");
var val1 = document.getElementById("range_filter").value;
document.getElementById('editor').value = document.getElementById('editor').innerHTML;
var val2 = document.getElementById("editor").value;
val1 = val2;
console.log(val1);
console.log(val2);
}
var el = document.getElementById("editor");
if(el)
{
el.addEventListener('input', edit, false);
}
https://jsfiddle.net/d63sgacn/12/
When you set val to document.getElementById(...).value, then val is not a reference to the element's value anymore - it's just a number stored in a variable, the same as if you had written let x = 5.
Instead of extracting the value, just keep references to the elements.
function edit() {
const slider = document.getElementById("range_filter");
const numberInput = document.getElementById("editor");
slider.value = numberInput.value;
}
var el = document.getElementById("editor");
if (el) {
el.addEventListener('input', edit, false);
}
Also, there's no reason for the input to be a <span>. That doesn't limit user input to numbers only. Just make it a standard <input type="number">.
<input id="range_filter" class="range-slider__range sum" type="range" value="10000" min="5000" max="100000" oninput="editor.value = range_filter.value">
<input type="number" id="editor" class="range-slider__value" value="0" />

HTML/Javascript Only 3 Range Sliders, Sum to 100, 2 Separate Math Interactions

Updated.
Sean Kaat put me in the right direction on how to add input fields. However, I am still unsure of how to do the math relationships between the three ranges.
<!DOCTYPE html>
<html lang='en' class=''>
<head>
<meta charset='UTF-8'>
</head>
<title>Calculator</title>
<h1>Calculator</h1>
<body>
<form>
<Label for="sliderBarOne">Ready</Label>
<input type="range" id="sliderBarOne" min="0" max="100" step="0.01" value="0" oninput="this.form.rangeOne.value=this.value">
<input type="number" id="rangeOne" oninput="this.form.sliderBarOne.value=this.value, updateSum();">
<br>
<Label for="sliderBarTwo">ACW</Label>
<input type="range" id="sliderBarTwo" min="0" max="100" step="0.01" value="0" oninput="this.form.rangeTwo.value=this.value">
<input type="number" id="rangeTwo" oninput="this.form.sliderBarTwo.value=this.value">
<br>
<Label for="sliderBarThree">Extra</Label>
<input type="range" id="sliderBarThree" min="0" max="100" step="0.01" value="0" oninput="this.form.rangeThree.value=this.value">
<input type="number" id="rangeThree" oninput="this.form.sliderBarThree.value=this.value">
<br>Sum: <span id="sum">0</span>
</form>
<script>
document.getElementById("sliderBarOne").addEventListener("input", updateReady);
document.getElementById("sliderBarTwo").addEventListener("input", updateACW);
document.getElementById("sliderBarThree").addEventListener("input", updateExtra);
function updateReady() {
let readyBox = document.getElementById('sliderBarOne').value;
let ACWBox = document.getElementById('sliderBarTwo').value;
let extraBox = document.getElementById('sliderBarThree').value;
updateSum();
}
function updateACW() {
let readyBox = document.getElementById('sliderBarOne').value;
let ACWBox = document.getElementById('sliderBarTwo').value;
let extraBox = document.getElementById('sliderBarThree').value;
updateSum();
}
function updateExtra() {
let readyBox = document.getElementById('sliderBarOne').value;
let ACWBox = document.getElementById('sliderBarTwo').value;
let extraBox = document.getElementById('sliderBarThree').value;
updateSum();
}
function updateSum() {
var sliderOneValue = +document.getElementById('sliderBarOne').value;
var sliderTwoValue = +document.getElementById('sliderBarTwo').value;
var sliderThreeValue = +document.getElementById('sliderBarThree').value;
document.getElementById('sum').innerHTML = sliderOneValue + sliderTwoValue + sliderThreeValue;
}
</script>
</body>
</html>
I want to make two separate math relationships that I am unaware of how to even start working on.
I want Ready to be the first number set with ACW being set to 100-Ready. So, if there is 95 Ready, ACW is automatically set to 5. I want Extra to be set to 0 to start.
Ready = 95.00
ACW = 5.00
Extra = 0.00
So, to demonstrate the impact of Extra Time on Ready and ACW, I want any addition of Extra to adjust both Ready and ACW, while keeping Ready and ACW = 100. Ready + ACW + Extra does not equal 100.
So, the following would occur with Extra inputted at 5.00.
Ready = 90.00
ACW = 10.00
Extra = 5.00
Sean Kaat suggested something that isn't working for me right now, and I don't know why. I have the empty functions of updateReady, updateACW and updateExtra set so that I can use it to handle the three separate mathematical changes.
You are correct that the math amount is going to substantially increase; you want to be sure to set the values in a specific order.
First: set READY equal to PREVIOUS_READY_VALUE - EXTRA (and if the value is below 0, just set it to 0),
Then: set ACW equal to 100 - (EXTRA + READY),
Finally: set the input.value of each slider to the above values
Each onChange event of the sliders should do the math and then change the values of the html accordingly.

How to fix "If statement" from adding variables exponentially?

I am trying to use a set of range sliders to impact each other in various ways. My If the statement is working correctly the first time I change a value, but the second time I change a value, it is adding the entire value instead of the change.
I've tried everything I know so far on how to resolve this, but breaks and continues do not seem to be fixing the problem.
<form>
<Label for="sliderBarOne">Ready</Label>
<input type="range" id="sliderBarOne" min="0" max="100" step="0.01" value="0" onchange="this.form.rangeOne.value=this.value">
<input type="number" id="rangeOne" value="0" onchange="this.form.sliderBarOne.value=this.value">
<br>
<Label for="sliderBarTwo">ACW</Label>
<input type="range" id="sliderBarTwo" min="0" max="100" step="0.01" value="0" onchange="this.form.rangeTwo.value=this.value">
<input type="number" id="rangeTwo" value="0" onchange="this.form.sliderBarTwo.value=this.value">
<br>
<Label for="sliderBarThree">Extra</Label>
<input type="range" id="sliderBarThree" min="0" max="100" step="0.01" value="0" onchange="this.form.rangeThree.value=this.value">
<input type="number" id="rangeThree" value="0" onchange="this.form.sliderBarThree.value=this.value">
<br>Sum: <span id="sum">0</span>
</form>
<script>
document.getElementById("sliderBarOne").addEventListener("change", updateReady);
document.getElementById("sliderBarTwo").addEventListener("change", updateACW);
document.getElementById("sliderBarThree").addEventListener("change", updateExtra);
document.getElementById("rangeOne").addEventListener("change", updateReady);
document.getElementById("rangeTwo").addEventListener("change", updateACW);
document.getElementById("rangeThree").addEventListener("change", updateExtra);
function updateReady() {
var readyBox = document.getElementById('sliderBarOne');
var acwBox = document.getElementById('sliderBarTwo');
var extraBox = document.getElementById('sliderBarThree');
var readyField = document.getElementById('rangeOne');
var acwField = document.getElementById('rangeTwo');
if (readyBox.value < 100 || readyField.value < 100) {
acwBox.value = 100 - parseFloat(readyBox.value);
//Set Slider Values Into Fields
readyField.value = readyBox.value;
acwField.value = acwBox.value;
extraField.value = extraBox.value;
}
updateSum();
}
function updateACW() {
var readyBox = document.getElementById('sliderBarOne');
var acwBox = document.getElementById('sliderBarTwo');
var extraBox = document.getElementById('sliderBarThree');
updateSum();
}
function updateExtra() {
var readyBox = document.getElementById('sliderBarOne');
var acwBox = document.getElementById('sliderBarTwo');
var extraBox = document.getElementById('sliderBarThree');
var readyField = document.getElementById('rangeOne');
var acwField = document.getElementById('rangeTwo');
var extraField = document.getElementById('rangeThree');
if (extraBox.value > 0 || extraField.value > 0) {
readyBox.value = parseFloat(readyBox.value) - parseFloat(extraBox.value);
acwBox.value = parseFloat(acwBox.value) + parseFloat(extraBox.value);
//Set Slider Values Into Fields
readyField.value = readyBox.value;
acwField.value = acwBox.value;
extraField.value = extraBox.value;
}
updateSum();
}
</script>
The first time I enter a value into Ready, it properly subtracts that value from 100 to provide ACW.
Then, when I put a value into Extra, it accurately subtracts that value from Ready and adds to ACW. For instance, Ready 95, ACW 5. Making Extra 1 makes Ready 94 and ACW 6. The problem is, when I change Extra to 2, it makes Ready 92 and ACW 8 instead of Ready 93 and ACW 7.
I'm not sure how to grab the change in the value on each change.
your updatesum() is not defined and your extrafield is not defined in updateready() function
Because the values are changed before. You first change them by 1, and then change them by 2. Hence, it means the extra is 3! Unless you reload the page to reinitialize the values to 95 and 6 and then apply extra 2. It will give you 93 and 7.
To solve the problem you can write an initialize function that initializes the values, and then call the function at the first line of the updateExtra function.
OmG provided the inspiration to create an initial value field. So, I adjusted the code as follows. Thanks OmG!
function updateExtra() {
var readyBox = document.getElementById('sliderBarOne');
var acwBox = document.getElementById('sliderBarTwo');
var extraBox = document.getElementById('sliderBarThree');
var readyField = document.getElementById('rangeOne');
var acwField = document.getElementById('rangeTwo');
var extraField = document.getElementById('rangeThree');
var initialReady = document.getElementById('initialReady');
var initialACW = document.getElementById('initialACW');
if (extraBox.value > 0 || extraField.value > 0) {
readyBox.value = parseFloat(initialReady.value) - parseFloat(extraBox.value);
acwBox.value = parseFloat(initialACW.value) + parseFloat(extraBox.value);
//Set Slider Values Into Fields
readyField.value = readyBox.value;
acwField.value = acwBox.value;
extraField.value = extraBox.value;
}
updateSum();
}

applying onkeyup function simultaneously on multiple textboxes

Suppose I have a column of 1+7 text box. Name of the first box is mm1 and the other boxes are respectively dd1, dd2, ...., dd7. I want to write a javascript function so that all the values in the textboxes dd1, dd2,...,dd7 are multiplied by N if I put N in the first textbox namely mm1. I can write the javascript function , but how to make its effect in all boxes simultaneously? I have tried the following code. But it can effect only one box depending on the value of $i. If we can create a loop for $i taking values 1 to 7, then perhaps the problem will be solved. Any clue please.
<?php $i=3?>
<input type="text" size="1" id="mm1" name="mm1"
maxlength="2" onfocus="this.select()"
onkeyup="gft('dd<?php echo $i?>', 'mm1')"
>
Try this, use class to logically group elements...
$('.mult').each(function(i,v){
var tt = parseFloat($(this).val());
$(this).attr('data-val',$(this).val());
});
$('.myVal').on('keyup',function(e){
var t = $(this).val();
if(!t) t = 0;
$('.mult').each(function(i,v){
if(t>0){
var tt = parseFloat($(this).attr('data-val')) * t;
$(this).val(tt);
}
});
});
Find working fiddle here
function gft(x){
n = 5;
c = x * n;
textInputs[0].value = c;
textInputs[1].value = c;
textInputs[2].value = c;
}
var textInputs = document.querySelectorAll('input[type=text]');
//this eventlistener is made to listen for key movement on all text fields that are of type text
for(i=0;i<textInputs.length;i++){
textInputs[i].addEventListener('keyup',function(){
//gft will execute an equation whenever one of these fields change
//also, it will change all the values inside the textfield simultaneously
gft(this.value);
},false);
}
I made a JSFiddle using only JavaScript (no jQuery):
HTML
<input type="number" onkeyup="multiply(this)"/>
<input type="number" value="1" class="multiply-this"/>
<input type="number" value="2" class="multiply-this"/>
<input type="number" value="3" class="multiply-this"/>
<input type="number" value="4" class="multiply-this"/>
<input type="number" value="5" class="multiply-this"/>
<input type="number" value="6" class="multiply-this"/>
<input type="number" value="7" class="multiply-this"/>
JavaScript
function multiply(first){
var value = +first.value;
var textboxes = document.getElementsByClassName("multiply-this");
for(var i = 0; i < textboxes.length; i++){
var textbox = textboxes[i];
if(textbox.attributes.initialValue){
textbox.value = textbox.attributes.initialValue.value;
} else {
textbox.setAttribute("initialValue", textbox.value);
}
textbox.value = +textbox.value * value;
}
}
window.onload = function(){
var textboxes = document.getElementsByClassName("multiply-this");
for(var i = 0; i < textboxes.length; i++){
var textbox = textboxes[i];
textbox.onkeyup = function(){
this.setAttribute("initialValue", this.value);
}
}
}
I added functionality to remember what value the textboxes had at first. But you can still change it if you specifically change one of the 7 textboxes that gets multiplied.
EDIT
You can also add this if you want it to multiply after changing one of the values:
textbox.onblur = function(){
multiply(document.getElementById("multiplyer"));
}
JSFiddle

Categories

Resources