Insert Input Value into Label Text Javascript - javascript

I have 3 range inputs:
When the user starts to drag the range thumb, I'd love the of related input value to be printed in the label before main text. For this I wrote a funtion, but nothng works
let rangeForm = document.querySelectorAll('.form-range');
let rangeValue = document.querySelectorAll('.input-value');
window.onload = () => {
rangeForm.forEach((input) => input.value = '0');
}
function findTotal() {
var tot = 0;
rangeForm.forEach((input) => tot += parseInt(input.value, 10));
document.getElementById('total-cost').innerHTML = tot;
}
function changeLabel() {
rangeValue.forEach((label) => label.inhherHTML = `${parseInt(input.value, 10)}`);
}
<label for="storiesNumber" class="form-label"><p class="input-value"></p>some text</label>
<input type="range" oninput="findTotal();changeLabel()" class="form-range" min="0" max="100" id="storiesNumber">
<label for="postsNumber" class="form-label"><p class="input-value"></p>another text</label>
<input type="range" oninput="findTotal();changeLabel()" class="form-range" min="0" max="100" id="postsNumber">
<label for="reelsNumber" class="form-label"><p class="input-value"></p>more text</label>
<input type="range" oninput="findTotal();changeLabel()" class="form-range" min="0" max="100" id="reelsNumber">

Check out this snippet, I guess it fits your purpose:
let rangeForm = document.querySelectorAll('.form-range');
let rangeValue = document.querySelectorAll('.input-value');
window.onload = () => {
rangeForm.forEach((input) => input.value = '0');
}
function findTotal() {
var tot = 0;
rangeForm.forEach((input) => tot += parseInt(input.value, 10));
document.getElementById('total-cost').innerHTML = tot;
}
function changeLabel(input) {
document.querySelector("label[for="+input.id+"] > .input-value").innerText = `${parseInt(input.value, 10)}`
}
<label for="storiesNumber" class="form-label">
some text: <b class="input-value"></b>
</label>
<input type="range" oninput="findTotal();changeLabel(this)" class="form-range" min="0" max="100" id="storiesNumber">
<br>
<label for="postsNumber" class="form-label">
another text: <b class="input-value"></b>
</label>
<input type="range" oninput="findTotal();changeLabel(this)" class="form-range" min="0" max="100" id="postsNumber">
<br>
<label for="reelsNumber" class="form-label">
more text: <b class="input-value"></b>
</label>
<input type="range" oninput="findTotal();changeLabel(this)" class="form-range" min="0" max="100" id="reelsNumber">
<br>
Total: <b id="total-cost">...</b>

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>

Store array into variables in Javascript

I have an array of inputs, after looping through them using a for loop, is it possible to store each value into a variable?
Here's what I am trying to do specifically: I am building a gradient background generator. I have a total of 6 inputs (rgb for the first color of the gradient and rgb for the second one). I loop through the input array and then I stored each value into a variable (r, g, b, r2, g2, b2) and then use them in the linear-gradient css.
My method doesn't seem to be very functional, so I was wondering if it was possible to store all the input[i] values "automatically" into variables.
const inputs = document.querySelectorAll('input')
const body = document.body;
for (var i = 0; i < inputs.length; i++) {
inputs[i].addEventListener('change', changeValue);
inputs[i].addEventListener('mousemove', changeValue);
function changeValue() {
let r = inputs[0].value;
let g = inputs[1].value;
let b = inputs[2].value;
let rgb = r + ',' + g + ',' + b;
let r2 = inputs[3].value;
let g2 = inputs[4].value;
let b2 = inputs[5].value;
let rgb2 = r2 + ',' + g2 + ',' + b2;
body.style.backgroundImage = `linear-gradient(45deg, rgb(${rgb}), rgb(${rgb2}))`;
};
}
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
You can remove all the for loops, by utilizing Array.prototype.forEach and Array.prototype.slice.
I also created a custom shiv (aka polyfill) for EventTarget.prototype.addEventListeners.
EventTarget.prototype.addEventListeners = function(eventNames, listener) {
eventNames.split(' ').forEach(event => this.addEventListener(event, listener, false))
}
const inputs = document.querySelectorAll('input')
inputs.forEach(input => input.addEventListeners('change mousemove', onChangeValue))
function onChangeValue() {
let rgb1 = [].slice.call(inputs, 0, 3).map(x => x.value).join(',')
let rgb2 = [].slice.call(inputs, 3, 6).map(x => x.value).join(',')
document.body.style.backgroundImage = `linear-gradient(45deg, rgb(${rgb1}), rgb(${rgb2}))`;
};
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
You could also try to group the components by classes.
EventTarget.prototype.addEventListeners = function(events, listener) {
events.split(' ').forEach(event => this.addEventListener(event, listener, false));
}
document.querySelectorAll('.color-slider-channel').forEach(input => {
input.addEventListeners('change mousemove', onChangeValue);
})
function onChangeValue(e) {
document.body.style.backgroundImage = `linear-gradient(45deg, ${retrieveGradientStops()})`;
};
function retrieveGradientStops() {
return [...document.querySelectorAll('.color-slider-rgb')].map(s => {
return 'rgb(' + [...s.querySelectorAll('.color-slider-channel')].map(c => c.value).join(',') + ')';
}).join(', ');
}
<div class="color-sliders">
<div class="color-slider-rgb">
<input type="range" class="color-slider-channel" min="0" max="255">
<input type="range" class="color-slider-channel" min="0" max="255">
<input type="range" class="color-slider-channel" min="0" max="255">
</div>
<div class="color-slider-rgb">
<input type="range" class="color-slider-channel" min="0" max="255">
<input type="range" class="color-slider-channel" min="0" max="255">
<input type="range" class="color-slider-channel" min="0" max="255">
</div>
</div>
If you're using ES6 you can use a destructuring assignment.
You would do something like:
let [r, g, b, r2, g2, b2] = Array.from(inputs).map((x) => x.value);
Example:
const arr = [234,124,233, 25,233,21]
let [r, g, b, r2, g2, b2] = arr;
console.log(r, g, b)
console.log(r2, g2, b2)
You can simplify your code by using Array destructuring:
const inputs = [...document.querySelectorAll('input')];
const body = document.body;
for (var i = 0; i < inputs.length; i++) {
inputs[i].addEventListener('change', changeValue);
inputs[i].addEventListener('mousemove', changeValue);
function changeValue() {
let [r, g, b, r2, g2, b2] = inputs.map((x) => x.value);
let rgb = r + ',' + g + ',' + b;
let rgb2 = r2 + ',' + g2 + ',' + b2;
body.style.backgroundImage = `linear-gradient(45deg, rgb(${rgb}), rgb(${rgb2}))`;
};
}
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
<input type="range" min="0" max="255">
You could get the values by their id.
function changeValue() {
const mapId = id => document.getElementById(id).value || 0;
var [rgb, rgb2] = inputs.map(groups => groups.map(mapId).join(','));
document.body.style.backgroundImage = `linear-gradient(45deg, rgb(${rgb}), rgb(${rgb2}))`;
}
var inputs = [['r1', 'g1', 'b2'], ['r2', 'g2', 'b2']];
inputs.forEach(group => group.forEach(id => {
document.getElementById(id).addEventListener('change', changeValue);
document.getElementById(id).addEventListener('mousemove', changeValue);
}));
<input id="r1" type="range" min="0" max="255">
<input id="g1" type="range" min="0" max="255">
<input id="b1" type="range" min="0" max="255"><br>
<input id="r2" type="range" min="0" max="255">
<input id="g2" type="range" min="0" max="255">
<input id="b2" type="range" min="0" max="255">

Getting the average value of multiple input-type range sliders

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.

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
});

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