Linking Event Handlers in forEach Loop Javascript NodeList - javascript

I'm trying to link the event of two input types in a NodeList. I'm able to link a single pair of inputs but once I add more pairs, I'm unable to link them. What am I doing wrong?
var range = document.querySelectorAll(".inputRange");
var field = document.querySelectorAll(".inputNumber");
// console.log(range);
// console.log(field);
range.forEach(input => {
input.addEventListener("input", e => {
// console.log("RANGE EVENT: " +e.type)
field.value = e.target.value;
});
});
field.forEach(input => {
input.addEventListener("input", e => {
range.value = e.target.value;
});
});
<div class="card grd">
<h4 class="r1">Recipe</h4>
<p>Low</p>
<h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="0.75" step=".01" maxlength="8" /></h2>
<div class="sldcon">
<input class="inputRange" id="range" type="range" min="0" max="100" value="0.75" step=".01" />
</div>
<p>Mid</p>
<h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="35" step=".01" maxlength="8" /></h2>
<div class="sldcon">
<input class="inputRange" id="range" type="range" min="0" max="100" value="35" step=".01" />
</div>
<p>High</p>
<h2 class="r2"><input class="inputNumber" id="num1" min="0" max="1000" type="number" value="40" step=".01" maxlength="8" /></h2>
<div class="sldcon">
<input class="inputRange" id="range" type="range" min="0" max="1000" value="40" step=".01" />
</div>
</div>

Iterate over only one of the collections, and inside the loop, get a reference to the linked input by navigating the nearby DOM, then add listeners to both:
document.querySelectorAll(".inputNumber").forEach((field) => {
const range = field.parentElement.nextElementSibling.children[0];
range.oninput = () => field.value = range.value;
field.oninput = () => range.value = field.value;
});
<div class="card grd">
<h4 class="r1">Recipe</h4>
<p>Low</p>
<h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="0.75" step=".01" maxlength="8" /></h2>
<div class="sldcon">
<input class="inputRange" id="range" type="range" min="0" max="100" value="0.75" step=".01" />
</div>
<p>Mid</p>
<h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="35" step=".01" maxlength="8" /></h2>
<div class="sldcon">
<input class="inputRange" id="range" type="range" min="0" max="100" value="35" step=".01" />
</div>
<p>High</p>
<h2 class="r2"><input class="inputNumber" id="num1" min="0" max="1000" type="number" value="40" step=".01" maxlength="8" /></h2>
<div class="sldcon">
<input class="inputRange" id="range" type="range" min="0" max="1000" value="40" step=".01" />
</div>
</div>
Or you could reference the same index on the other collection:
const ranges = document.querySelectorAll(".inputRange");
document.querySelectorAll(".inputNumber").forEach((field, i) => {
const range = ranges[i];
range.oninput = () => field.value = range.value;
field.oninput = () => range.value = field.value;
});
<div class="card grd">
<h4 class="r1">Recipe</h4>
<p>Low</p>
<h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="0.75" step=".01" maxlength="8" /></h2>
<div class="sldcon">
<input class="inputRange" id="range" type="range" min="0" max="100" value="0.75" step=".01" />
</div>
<p>Mid</p>
<h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="35" step=".01" maxlength="8" /></h2>
<div class="sldcon">
<input class="inputRange" id="range" type="range" min="0" max="100" value="35" step=".01" />
</div>
<p>High</p>
<h2 class="r2"><input class="inputNumber" id="num1" min="0" max="1000" type="number" value="40" step=".01" maxlength="8" /></h2>
<div class="sldcon">
<input class="inputRange" id="range" type="range" min="0" max="1000" value="40" step=".01" />
</div>
</div>

Related

Is there a reason why my sliders aren't working with the code I have used?

Is there something wrong with the way I have formatted it or will I have to go the JavaScript route? I'm looking for the code to update automatically to whatever number I have set the slider to or vise versa.
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
It would be better to call a simple function to get the other input and set it's value regardless of ID. This goes to the parent element and then finds the child that doesn't match the same type of the initial input and sets it's value.
Just for future reference, it is not good practice to have elements with the same ID: https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute
function setValue(input) {
let val = input.value;
let selector = `input:not([type=${input.getAttribute('type')}])`;
let otherInput = input.parentElement.querySelectorAll(selector);
otherInput[0].value = val;
}
<div>
<input class="value" type="number" value="10" min="0" max="50" oninput="setValue(this)">
<input class="slider" type="range" value="10" min="0" max="50" oninput="setValue(this)">
</div>
<div>
<input class="value" type="number" value="10" min="0" max="50" oninput="setValue(this)">
<input class="slider" type="range" value="10" min="0" max="50" oninput="setValue(this)">
</div>
<div>
<input class="value" type="number" value="10" min="0" max="50" oninput="setValue(this)">
<input class="slider" type="range" value="10" min="0" max="50" oninput="setValue(this)">
</div>
<div>
<input class="value" type="number" value="10" min="0" max="50" oninput="setValue(this)">
<input class="slider" type="range" value="10" min="0" max="50" oninput="setValue(this)">
</div>
<div>
<input class="value" type="number" value="10" min="0" max="50" oninput="setValue(this)">
<input class="slider" type="range" value="10" min="0" max="50" oninput="setValue(this)">
</div>
<div>
<input class="value" type="number" value="10" min="0" max="50" oninput="setValue(this)">
<input class="slider" type="range" value="10" min="0" max="50" oninput="setValue(this)">
</div>
All I had to do was wrap it in the form tag. Like so...
<form>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
</form>
<form>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
</form>
<form>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
</form>
<form>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
</form>
<form>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
</form>
<form>
<div>
<input class="value" id="amount" type="number" value="10" min="0" max="50" oninput="rangeInput.value=amount.value">
<input class="slider" id="rangeInput" type="range" value="10" min="0" max="50" oninput="amount.value=rangeInput.value">
</div>
</form>

How to call selected radio button's input ID?

I have multiple inputs with their ID in the radio button group and range slider. I want the addition of all multiplication of checked radio buttons and range sliders. But I don't get checked radio button's input type text value. Below something I tried but it's the wrong code.
$(document).ready(function() {
$('.range').on('change', function() {
let total = 0;
let multiplyFactor = document.getElementById(`actualtime${inputIndex}`).value;
console.log(multiplyFactor);
$('.range').each(function() {
total += (parseFloat($(this).val()) * multiplyFactor);
});
$('#timetoproduce').text(total);
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="starter"><input type="radio" id="" class="radio-roi"name="plan" value="starter" checked>
<input type="text" value="2" id="actualtime1" class="hiden-actual-time" disabled></label><br>
<label for="plus"><input type="radio" id="" class="radio-roi"name="plan" value="plus" >
<input type="text" value="2.5" id="actualtime2" class="hiden-actual-time" disabled></label><br>
<label for="pro"><input type="radio" id="" class="radio-roi"name="plan" value="pro" >
<input type="text" value="3" id="actualtime3" class="hiden-actual-time" disabled></label><br>
<input type="range" class="range" id="range1" min="0" max="12" value="0" step="1"><br>
<input type="range" class="range" id="range2" min="0" max="12" value="0" step="1"><br>
<input type="range" class="range" id="range3" min="0" max="12" value="0" step="1"><br>
<span id="timetoproduce" value=""></span>
You could do with :checked and next to find the input value
$(document).ready(function() {
$('.range').on('change', function() {
let n = $(this).attr('id').match(/\d+/g)[0];
let total = 0;
let checkVal = $('.radio-roi:checked').next('input').val();
let multiplyFactor = parseFloat(checkVal);
console.log(multiplyFactor)
$('.range').each(function() {
total += (parseFloat($(this).val()) * multiplyFactor);
});
$('#timetoproduce').text(total);
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" id="" class="radio-roi" name="plan" value="starter" checked>
<input type="text" value="2" id="actualtime1" class="hiden-actual-time" disabled><br>
<input type="radio" id="" class="radio-roi" name="plan" value="plus">
<input type="text" value="2.5" id="actualtime2" class="hiden-actual-time" disabled><br>
<input type="radio" id="" class="radio-roi" name="plan" value="pro">
<input type="text" value="3" id="actualtime3" class="hiden-actual-time" disabled><br>
<input type="range" class="range" id="range1" min="0" max="12" value="0" step="1"><br>
<input type="range" class="range" id="range2" min="0" max="12" value="0" step="1"><br>
<input type="range" class="range" id="range3" min="0" max="12" value="0" step="1"><br>
<span id="timetoproduce" value=""></span>

How do I get total addition of three group?

Here I three groups with range slider and input. I want to apply two things.
Multiplication of range slider and the input.
And at the end Addition of all multiplication.
I have a different ID for all input types.
$(document).ready(function(){
var t_sum=0;
var rs=document.getElementById("range").value;
var am=document.getElementById("amount").value;
var k=0;
$('.mul').each(function(){
i++;
var newID='multiplication-'+k;
$(this).attr('id',newID);
document.getElementById("multiplication").innerHTML = rs * am;
})
document.getElementById("addition").innerHTML= multiplication+k;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="range" class="range" id="range1" min="0" max="12" value="0" step="1">
<input type="text" id="amount1" value="10" disabled ><br>
<input type="range" class="range" id="range2" min="0" max="12" value="0" step="1">
<input type="text" id="amount2" value="20" disabled ><br>
<input type="range" class="range" id="range3" min="0" max="12" value="0" step="1">
<input type="text" id="amount3" value="30" disabled ><br>
<input type="hidden" id="multiplication" class="mul">
Addition of all multiplication <input type="text" id="addition" value="" disabled >
I know the code is wrong.
You can give common class to your amt input as well then use index value of each loop to get value of amt inputs and add total to your addition input.
Demo Code :
$(document).ready(function() {
$(".range").on("change", function() {
var mult = 0;
$('.range').each(function(i) {
var selector_next = parseInt($(".amt:eq(" + i + ")").val()) //get input value
mult += parseInt($(this).val()) * selector_next //multply..
console.log($(".amt:eq(" + i + ")").val(), $(this).val())
})
$("#multiplication").val(mult)
$("#addition").val(mult)
})
$(".range:first").trigger("change")
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<input type="range" class="range" id="range1" min="0" max="12" value="0" step="1">
<!--added class-->
<input type="text" class="amt" id="amount1" value="10" disabled><br>
<input type="range" class="range" id="range2" min="0" max="12" value="0" step="1">
<input type="text" class="amt" id="amount2" value="20" disabled><br>
<input type="range" class="range" id="range3" min="0" max="12" value="0" step="1">
<input type="text" class="amt" id="amount3" value="30" disabled><br>
<input type="hidden" id="multiplication" class="mul"> Addition of all multiplication <input type="text" id="addition" value="addition" disabled>

Main range change value here child range -css javascript

I have three range first range it Main , and another it child .. when i change main range i want automatically change another range
Main:<input type="range" name="range" step="1" value="0" min="0" max="200" 0 style="width:100%;" /> <br> <BR>
Child range:<br>
<input type="range" name="range" step="1" value="0" min="0" max="200" 0/><input type="range" name="range" step="1" value="0" min="0" max="200" />
<h3>when i change Main range i want change child range with Main
</h3>
This is a basic example
window.onload = function(){
var rangeMain = document.getElementById('main'),
rangeChild1 = document.getElementById('child1'),
rangeChild2 = document.getElementById('child2');
rangeMain.onchange = function(){
rangeChild1.value = this.value;
rangeChild2.value = this.value;
}
}
Main:<input id="main" type="range" name="range" step="1" value="0" min="0" max="200" 0 style="width:100%;" /> <br> <BR>
Child range:<br>
<input id="child1" type="range" name="range" step="1" value="0" min="0" max="200" 0/>
<input id="child2" type="range" name="range" step="1" value="0" min="0" max="200" />
<h3>when i change Main range i want change child range with Main
</h3>
If you want live feedback as the range changes without waiting for mouse release, you could listen oninput
var rangeMain = document.getElementById('main'),
rangeChild1 = document.getElementById('child1'),
rangeChild2 = document.getElementById('child2');
rangeMain.onchange = function(){
rangeChild1.value = this.value;
rangeChild2.value = this.value;
}
rangeMain.oninput = function(){
rangeChild1.value = this.value;
rangeChild2.value = this.value;
}
Main:<input id="main" type="range" name="range" step="1" value="0" min="0" max="200" 0 style="width:100%;" /> <br> <BR>
Child range:<br>
<input id="child1" type="range" name="range" step="1" value="0" min="0" max="200" 0/>
<input id="child2" type="range" name="range" step="1" value="0" min="0" max="200" />
<h3>when i change Main range i want change child range with Main
</h3>

Jquery script isn't working in browser

I have tried to add a script from Stackoverflow that took ages to come by,
but it seems like the file is going against me, though it's working perfectly
fine in JSfiddle. http://jsfiddle.net/hqtsmayh/
<div data-role="page" id="page1">
<div data-role="header">
<h1>My page</h1>
</div>
<div role="main" class="ui-content">
<div id="mysliders">
<label for="slider-1">Slider:</label>
<input class="add" type="range" name="slider-1" id="slider-1" min="0" max="100" value="50" />
<label for="slider-2">Slider:</label>
<input class="add" type="range" name="slider-2" id="slider-2" min="0" max="100" value="40" />
<label for="slider-3">Slider:</label>
<input class="add" type="range" name="slider-3" id="slider-3" min="0" max="100" value="30" />
<label for="slider-4">Slider:</label>
<input class="add" type="range" name="slider-4" id="slider-4" min="0" max="100" value="65" />
<label for="slider-5">Slider:</label>
<input class="add" type="range" name="slider-5" id="slider-5" min="0" max="100" value="11" />
<label for="slider-6">Slider:</label>
<input class="add" type="range" name="slider-6" id="slider-6" min="0" max="100" value="90" />
</div>
<hr />
<p>Total: <strong id="total"></strong></p>
</div>
<div data-role="footer" data-position="fixed">
<h1>Footer</h1>
</div>
</div>
<script>
$(window).load(function(){
$(document).on("pagecreate", "#page1", function () {
$(".add").on("change", function () {
addAll();
});
addAll();
});
function addAll() {
var sum = 0
$('.add').each(function (){
sum += isNaN(this.value) || $.trim(this.value) === '' ? 0 : parseFloat(this.value);
});
$('#total').html(sum);
}
});
</script>
All I have in the header is a Jquery attachment:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
Why not just this? tested in mobile Safari
Also beware of jsFiddle's default onload
$(window).load(function() {
$(".add").on("change", function() {
addAll();
});
addAll();
});
function addAll() {
var sum = 0
$('.add').each(function() {
sum += isNaN(this.value) || $.trim(this.value) === '' ? 0 : parseFloat(this.value);
});
$('#total').html(sum);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div data-role="page" id="page1">
<div data-role="header">
<h1>My page</h1>
</div>
<div role="main" class="ui-content">
<div id="mysliders">
<label for="slider-1">Slider:</label>
<input class="add" type="range" name="slider-1" id="slider-1" min="0" max="100" value="50" />
<label for="slider-2">Slider:</label>
<input class="add" type="range" name="slider-2" id="slider-2" min="0" max="100" value="40" />
<label for="slider-3">Slider:</label>
<input class="add" type="range" name="slider-3" id="slider-3" min="0" max="100" value="30" />
<label for="slider-4">Slider:</label>
<input class="add" type="range" name="slider-4" id="slider-4" min="0" max="100" value="65" />
<label for="slider-5">Slider:</label>
<input class="add" type="range" name="slider-5" id="slider-5" min="0" max="100" value="11" />
<label for="slider-6">Slider:</label>
<input class="add" type="range" name="slider-6" id="slider-6" min="0" max="100" value="90" />
</div>
<hr />
<p>Total: <strong id="total"></strong>
</p>
</div>
<div data-role="footer" data-position="fixed">
<h1>Footer</h1>
</div>
</div>

Categories