Getting the average value of multiple input-type range sliders - javascript

I have a div with 5 input-type range silders and a submit button.
<div class="sliders" id="sliderbox">
<input type="range" name="points" min="0" max="100">
<input type="range" name="points1" min="0" max="100">
<input type="range" name="points2" min="0" max="100">
<input type="range" name="points3" min="0" max="100">
<input type="range" name="points4" min="0" max="100">
<input type="submit">
</div>
Under this div, I have four other hidden divs that contain content.
<div id="hidden1">Content</div>
<div id="hidden2">Content</div>
<div id="hidden3">Content</div>
<div id="hidden4">Content</div>
How can I get the average combined value (a number between 0 & 100) of all the rangesliders, and then slidetoggle one of these hidden divs on submit?
For example, if the cumulative average value of these sliders is between 0 to 25 on submit, is it possible for me to display "hidden1"? Or if the value is between 25 to 50, "hidden2" and so on?

So you have 5 sliders all having the same MAX value of 100. So max 500
To get Element index from the current range value:
Floor(current * endMax / (startMax + 1))
Example
const $sliders = $("#sliderbox").find("input[type='range']");
const $cont = $(".cont");
const totSliders = $sliders.length; // 5
const startMax = totSliders * parseInt($sliders.prop("max"), 10); // 500
const endMax = $cont.length; // 4
$sliders.on("input", function() {
// Get accumulated value of 5 sliders: 0...500
const current = $sliders.get().reduce((ac, el) => ac + parseInt(el.value, 10), 0);
// Get index 0...3
const index = Math.floor(current * endMax / (startMax + 1));
$cont.addClass("hide").eq( index ).removeClass("hide");
console.clear(); console.log('Current:' + current + ' Index:'+ index);
}).trigger("input"); // To make immediate effect
.hide {
display: none;
}
<div class="sliders" id="sliderbox">
<input type="range" name="points" min="0" max="100" value="0">
<input type="range" name="points1" min="0" max="100" value="0">
<input type="range" name="points2" min="0" max="100" value="0">
<input type="range" name="points3" min="0" max="100" value="0">
<input type="range" name="points4" min="0" max="100" value="0">
</div>
<div class="cont hide" id="hidden1">1 Content</div>
<div class="cont hide" id="hidden2">2 Content!!!</div>
<div class="cont hide" id="hidden3">3 Content</div>
<div class="cont hide" id="hidden4">4 Content!!!</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Here I put in place some javascript. Probably this is something you want.
let avg = 0;
document.querySelector('.submit').addEventListener('click', event => {
document.querySelectorAll('.range').forEach(item => {
avg = Number(item.value) + avg;
});
avg = avg / 5;
if (avg >= 0 && avg <= 25) {
avg = 0;
document.querySelector('#hidden1').classList.add('show');
document.querySelector('#hidden1').classList.remove('hide');
}
});
JSFiddle

Using plain Javascript: if you utilize [HTMLNode].children, this will give you an array of elements within that node.
So you can gather all your inputs with:
document.getElementById('sliderbox').children
This will give you an HTMLCollection, that you can then iterate through with a for loop to retrieve each item's value, and calculate the average from that.

Related

How to set the limit of 5 input ranges against specific count of max 100

I have five different ranges called myRangeOne, myRangeTwo, myRangeThree... etc. I also have a variable with a count of 100. I am attempting to limit the max value of the five ranges based on the count variable. The consolidated chosen values of all five ranges should sum up to a max count of 100 only. For example if I choose rangeOne or any of the other ranges and change the value to 20 the count variable value should change to 80 and the rest of four ranges should only have access the limit of 80. And Next if I choose rangeThree to and say change value to 40 then the count variable value changes to 40 and rest of the three sliders left will change the range limit to 40 and so on...
this is what I have done so far
$(document).ready(function () {
var initialCount = 100;
var countTracker = initialCount;
$("#myRangeOne").on("change", function (e) {
console.log("this.value", this.value)
var tempCounter = countTracker - parseInt(this.value);
console.log("Counter", tempCounter)
// if(parseInt(this.value) <= countTracker){
$("#" + e.target.dataset.val).html(this.value + "%");
// countTracker = tempCounter;
$("#counter").html(tempCounter)
$("#myRangeTwo").attr("max", tempCounter);
$("#maxTwo").html(tempCounter);
// }
});
$("#myRangeTwo").on("change", function (e) {
if(parseInt(this.value) <= countTracker){
$("#" + e.target.dataset.val).html(this.value + "%");
$("#counter").html(countTracker - parseInt(this.value))
$("#myRangeThree").attr("max", countTracker - parseInt(this.value));
// countTracker = countTracker - parseInt(this.value)
$("#maxthree").html(countTracker - parseInt(this.value));
}else{
return false;
}
});
$("#myRangeThree").on("change", function (e) {
if(parseInt(this.value) <= countTracker){
$("#" + e.target.dataset.val).html(this.value + "%");
$("#counter").html(countTracker - parseInt(this.value))
$("#myRangeFour").attr("max", countTracker - parseInt(this.value));
// countTracker = countTracker - parseInt(this.value)
$("#maxFour").html(countTracker - parseInt(this.value));
}
});
// $(".slider").on("change", function (e) {
// if(parseInt(this.value) <= countTracker){
// $("#" + e.target.dataset.val).html(this.value + "%");
// if (e.target.dataset.id === "one") {
// $("#counter").html(countTracker - parseInt(this.value))
// }
// }
// });
});
<div>Counter: <span id="counter">100</span></div>
<div class="slidecontainer">
<p>One <span id="one">0</span></p>
<span id="minOne">0</span><input type="range" min="1" max="100" value="1" step="1" class="slider" data-val="one" data-id="one" id="myRangeOne"> <span id="maxOne">100</span>
</div>
<div class="slidecontainer">
<p>Two <span id="two">0</span></p>
<span id="minTwo">0</span><input type="range" min="1" max="100" value="1" step="1" class="slider" data-val="two" data-id="two" id="myRangeTwo"><span id="maxTwo">100</span>
</div>
<div class="slidecontainer">
<p>Three <span id="three">0</span></p>
<span id="minThree">0</span><input type="range" min="1" max="100" value="1" step="1" class="slider" data-val="three" data-id="three" id="myRangeThree"><span id="maxThree">100</span>
</div>
<div class="slidecontainer">
<p>Four <span id="four">0</span></p>
<span id="minFour">0</span><input type="range" min="1" max="100" value="1" step="1" class="slider" data-val="four" data-id="four" id="myRangeFour"><span id="maxFour">100</span>
</div>
<div class="slidecontainer">
<p>Five <span id="five">0</span></p>
<span id="minFive">0</span><span id="minOne"></span><input type="range" min="1" max="100" value="1" step="1" class="slider" data-val="five" data-id="five" id="myRangeFive"><span id="maxFive">100</span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
I am not sure how to go about creating it. Any help in making this work is greatly appreciated.
something like this?
const inputs = [...document.querySelectorAll(".slidecontainer input")];
for (let input of inputs) {
input.addEventListener("input", update);
}
update();
function update(e) {
// cap the value to max
if (e && e.target.valueAsNumber > +e.target.dataset.max) {
e.target.value = e.target.dataset.max;
}
let sumOfAllInputs = inputs.reduce((sum, input) => sum + input.valueAsNumber, 0);
document.querySelector("#counter").textContent = 100 - sumOfAllInputs + "%";
for (let input of inputs) {
//const sumOfOtherInputs = sumOfAllInputs - input.valueAsNumber;
//const max = 100 - sumOfOtherInputs;
// or short:
const max = 100 + input.valueAsNumber - sumOfAllInputs;
const container = input.closest(".slidecontainer");
container.querySelector(".max").textContent = input.dataset.max = max;
container.querySelector(".value").textContent = input.valueAsNumber + "%";
// set the break-points for the background to visualize the range
input.style.setProperty("--value", input.valueAsNumber + "%");
input.style.setProperty("--max", max+"%");
}
}
.slidecontainer input[type="range"] {
-webkit-appearance: none;
background: linear-gradient(to right,
#040 var(--value),
#0C0 0,
#0C0 var(--max),
#FDD 0
);
}
.slidecontainer input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 1px;
height: .8em;
}
<div>Counter: <span id="counter"></span></div>
<div class="slidecontainer">
<p>One <span class="value">0%</span></p>
<span class="min">0</span>
<input type="range" class="slider" value="0" min="0" max="100">
<span class="max">100%</span>
</div>
<div class="slidecontainer">
<p>Two <span class="value">0%</span></p>
<span class="min">0</span>
<input type="range" class="slider" value="0" min="0" max="100">
<span class="max">100%</span>
</div>
<div class="slidecontainer">
<p>Three <span class="value">0%</span></p>
<span class="min">0</span>
<input type="range" class="slider" value="0" min="0" max="100">
<span class="max">100%</span>
</div>
<div class="slidecontainer">
<p>Four <span class="value">0%</span></p>
<span class="min">0</span>
<input type="range" class="slider" value="0" min="0" max="100">
<span class="max">100%</span>
</div>
<div class="slidecontainer">
<p>Five <span class="value">0%</span></p>
<span class="min">0</span>
<input type="range" class="slider" value="0" min="0" max="100">
<span class="max">100%</span>
</div>

On input change, get all input values in div and update label

I have the following HTML:
<div class="filters">
<div class="filter-label">6</div>
<div class="filter-inputs">
<input type="number" name="i1" id="i1" value="1" min="0" step="1" />
<input type="number" name="i2" id="i2" value="2" min="0" step="1" />
<input type="number" name="i3" id="i3" value="3" min="0" step="1" />
</div>
</div>
The question:
I'd like to, when any input is changed, I want to get that value and
the value of the other two text boxes and add them all together. Once
I have the total value, I need to then change the text of the label
with the new value.
I also have the following JavaScript (jQuery) to detect when a change has happened, but after that, I can't figure out how to loop through each input in the div and get the value.
$('.filter .filter-inputs input').on('input', function() {
var element = $(this);
// ...
});
I looked at loops like the jQuery each method but I've got no idea how to loop through each input inside the filter-inputs div.
You could create array from inputs using map and get methods and then calculate sum with reduce method.
let inputs = $('.filters input');
let label = $('.filter-label');
inputs.on('input', function() {
let sum = inputs.map(function() {
return $(this).val()
}).get().reduce((r, e) => r + +e, 0);
label.text(sum)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="filters">
<div class="filter-label">6</div>
<div class="filter-inputs">
<input type="number" name="i1" id="i1" value="1" min="0" step="1" />
<input type="number" name="i2" id="i2" value="2" min="0" step="1" />
<input type="number" name="i3" id="i3" value="3" min="0" step="1" />
</div>
</div>
Or you could just create array with Array.from method and then use reduce method to sum values.
let inputs = $('.filters input');
let label = $('.filter-label');
inputs.on('input', function() {
label.text(Array.from(inputs).reduce((r, {value}) => r + +value, 0))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="filters">
<div class="filter-label">6</div>
<div class="filter-inputs">
<input type="number" name="i1" id="i1" value="1" min="0" step="1" />
<input type="number" name="i2" id="i2" value="2" min="0" step="1" />
<input type="number" name="i3" id="i3" value="3" min="0" step="1" />
</div>
</div>
Use this script
$('.filter-inputs input').change(function(){
var total = 0;
$('.filter-inputs input').each(function(){
total += parseInt($(this).val());
});
$('.filter-label').html(total);
});
No problem!
$('.filter .filter-inputs input').on('input', function() {
//not needed:
//var element = $(this);
// Obtain numeric entries
var i1 = Number($("#i1").val());
var i2 = Number($("#i2").val());
var i3 = Number($("#i3").val());
// Calculate sum of entries
var total = i1 + i2 + i3;
// Populate label div with sum
$(".filter-label").html(String(total));
});
Good luck!
You don't need jQuery for this task http://jsfiddle.net/72e3jLc0/
let label = document.querySelector('.filter-label');
let inputs = document.querySelectorAll('.filter-inputs input');
inputs.forEach(input => {
input.addEventListener('change', e => {
label.innerText = parseInt(label.innerText) + parseInt(input.value);
});
});
Try using the following approach:
$(document).ready(function() {
var total=0;
$("input[type='number']").change(function() {
$(".results").html("");
var objects = $(".filters").find("input[type='number']");
for (var i = 0; i < objects.length; i++) {
total += parseInt($(objects[i]).val());
}
$(".filter-label").text(total);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="filters">
<div class="filter-label">6</div>
<div class="filter-inputs">
<input type="number" name="i1" id="i1" value="1" min="0" step="1" />
<input type="number" name="i2" id="i2" value="2" min="0" step="1" />
<input type="number" name="i3" id="i3" value="3" min="0" step="1" />
</div>
</div>
I know this is an old thread, but I would like to give my contribution.
The id can be replaced with document or "body", and input is not necessary if all your inputs have the class .form-control.
$("#id-of-overall-div-element").on("change", "input, .form-control", function () {
// Do something
});

Get a old value of input before change and change total value to + or -

I want to make points distribution form.
I got 4 inputs type number value 0-100 and total = 100 points. So we can put 25 points in each input. I already get it work to validate inputs number min 0 max 100 and it subtracts from total changed input value.
I have a problem with adding to Total. If user change already changed value I need to make Total + value(before change) and then Total - value(after change).
I don't know how to get value before change.
My html
<input type="number" min="0" max="100" name="1" />
<input type="number" min="0" max="100" name="2" />
<input type="number" min="0" max="100" name="3" />
<input type="number" min="0" max="100" name="4" />
<input type="text" id="Total" name="Total" value="100"/>
My script
$("input[type=number]").keyup(function(event) {
max=100;
min=0;
value=( parseInt($(this).val()));
if(value < min || isNaN(parseInt(value)))
$(this).val(0)
else if(value > max)
$(this).val(100);
else return value;
});
var total, myVal;
$("input[type=number]").change(function(event) {
maxPoints = parseInt($('#Total').val());
myVal = ( parseInt($(this).val()) || 0);
total = maxPoints - myVal;
$('#Total').val(total);
});
If i would be able to save old value to some var i would change .onchange script to something like this and i think it should work. But how i can get old value ?
$("input[type=number]").change(function(event) {
oldValue = ???? - how to get this ? :P
if(oldValue>0){
maxPoints = parseInt($('#Total').val()) + oldValue;
}else{
maxPoints = parseInt($('#Total').val());
}
myVal = ( parseInt($(this).val()) || 0);
total = maxPoints - myVal;
$('#Total').val(total);
});
There is js fiddle how it works now.
Fiddle here
Hi just save the old value like this
$("input[type=number]").change(function(event) {
oldValue = $(this).data('oldvalue');
if(oldValue>0){
maxPoints = parseInt($('#Total').val()) + oldValue;
}else{
maxPoints = parseInt($('#Total').val());
}
myVal = ( parseInt($(this).val()) || 0);
total = maxPoints - myVal;
$(this).data('oldvalue',$(this).val()) // update old value to new value
$('#Total').val(total);
});
<input type="number" min="0" data-oldvalue='0' max="100" name="1" />
<input type="number" min="0" data-oldvalue='0' max="100" name="2" />
<input type="number" min="0" data-oldvalue='0' max="100" name="3" />
<input type="number" min="0" data-oldvalue='0' max="100" name="4" />
<input type="text" id="Total" name="Total" value="100"/>

How do I get a slider control with 2 values?

How do I get a slider control with 2 values?
|...........
Value 1: 100
Value 2: 0
......|.....
Value 1: 50
Value 2: 50
...........|
Value 1: 0
Value 2: 100
Edit: these are just examples when dragged there and not 'step'
Example:
Html Slider:
If you need both values regardless the min and max and without knowing their values you can expand #Weedoze answer to reflect this
function updateTextInput(val) {
var value1 = Number(val) - Number(document.getElementById('range').min);
document.getElementById('value1').innerHTML = "value1: "+value1;
var value2 = Number(document.getElementById('range').max) - Number(val);
document.getElementById('value2').innerHTML = "value2: "+value2;
}
0<input id="range" type="range" name="rangeInput" min="0" max="200" onchange="updateTextInput(this.value);">200
<br />
<p id="value1"></p>
<p id="value2"></p>
Just add a "step"-property to the input
<input
type="range"
name="points"
id="points"
step="50"
value="50"
min="0"
max="100">
value1 would be the input value and value2 = 100 - value1
function updateTextInput(val) {
document.getElementById('value').innerHTML = val;
}
0
<input type="range" name="rangeInput" min="0" max="100" onchange="updateTextInput(this.value);">100
<br />
<p id="value"></p>

JS - combine values from two functions

How do I combine outputs of the two functions to do some operations on the two values?
<div class="grid">
<h2>Adjust the level</h2>
<input
type="range"
name="points"
min="0"
max="10"
step="1"
onChange="xLevel(this.value)">
<input
type="range"
name="points"
min="0"
max="10"
step="1"
onChange="yLevel(this.value)">
<div id="output">
<p id="x"></p>
<p id="y"></p>
</div>
</div>
And the JS is:
var output = document.getElementById("output");
var xout = document.getElementById("x");
var yout = document.getElementById("y");
function xLevel(newVal) {
xout.innerHTML = newVal;
}
function yLevel(newVal) {
yout.innerHTML = newVal;
}
So how do I combine the two values, x and y, to eg. multiply them and display them in yet another div?
Thanks
Store the new values in their own variables in the top-level scope, and then manipulate them in a separate function.
var output = document.getElementById("output");
var xout = document.getElementById("x");
var yout = document.getElementById("y");
var multout = document.getElementById('mult');
var xval;
var yval;
function xLevel(newVal) {
xout.innerHTML = newVal;
xval = parseInt(newVal, 10); // casts it to a number
updateMultiplier();
}
function yLevel(newVal) {
yout.innerHTML = newVal;
yval = parseInt(newVal, 10); // casts it to a number
updateMultiplier();
}
function updateMultiplier() {
multout.innerHTML = yval * xval;
}
and then for your markup:
<div class="grid">
<h2>Adjust the level</h2>
<input
type="range"
name="points"
min="0"
max="10"
step="1"
onChange="xLevel(this.value)">
<input
type="range"
name="points"
min="0"
max="10"
step="1"
onChange="yLevel(this.value)">
<div id="output">
<p id="x"></p>
<p id="y"></p>
<p id="mult"></p>
</div>
</div>

Categories