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>
Related
So I was tasked with creating a menu in which the user will choose between four noodles, four main dishes, and three sides. The sides will multiply the price of the main dish. The catch is that for every noodle the user checked, it will be incremented to the total price by 50%. So, if the user pays $120 and chooses two noodles, it will be $180.
I know that the checkbox will call for two functions, but I have no clue as to how it would work only if there are two or more checked checkboxes. Can someone help or guide me into how to actually perform this?
Fiddle
function pmodel() {
Model();
finalCost();
}
function Model() {
if (document.querySelector('input[name="NDLS"]:checked')) {
document.getElementById("MMD").disabled = false;
document.getElementById("ADDONS").disabled = false;
} else {
document.getElementById("MMD").disabled = true;
document.getElementById("ADDONS").disabled = true;
}
}
function total() {
var selected1 = document.querySelector('input[name="MD"]:checked').value;
var selected2 = document.querySelector('input[name="ADDONS"]:checked').value;
//var totals = 0;
totals = (selected1 * selected2);
finalCost(totals);
}
function finalCost(totals) {
//totals += (totals * document.querySelector('input[id="PMODEL"]').value);
document.getElementById("amount").value = totals;
}
<fieldset id="MNDLS">
<legend>Noodles</legend>
<input type="checkbox" name="NDLS" id="PNDLS" value="0.5" onclick="pmodel()">
<label for="Model">Spaghetti</label><br>
<input type="checkbox" name="NDLS" id="PNDLS" value="0.5" onclick="pmodel()">
<label for="Model">Carbonara</label><br>
<input type="checkbox" name="NDLS" id="PNDLS" value="0.5" onclick="pmodel()">
<label for="Model">Lasagna</label><br>
<input type="checkbox" name="NDLS" id="PNDLS" value="0.5" onclick="pmodel()">
<label for="Model">Plain</label>
</fieldset>
<fieldset id="MMD" disabled>
<legend>Main Dish</legend>
<input type="radio" name="MD" value="50" onclick="total()">
<label>Chicken Wings ($50)</label><br>
<input type="radio" name="MD" value="55" onclick="total()">
<label>Chicken Breast ($55)</label><br>
<input type="radio" name="MD" value="60" onclick="total()">
<label>Pork Cutlets ($60)</label><br>
<input type="radio" name="MD" value="65" onclick="total()">
<label>Steak($65)</label>
</fieldset>
<fieldset id="ADDONS" disabled>
<legend>Sides</legend>
<input type="radio" name="ADDONS" value="1" onclick="total()">
<label>Nothing (100%)</label><br>
<input type="radio" name="ADDONS" value="1.5" onclick="total()">
<label>Softdrinks (150%)</label><br>
<input type="radio" name="ADDONS" value="2" onclick="total()">
<label>Softdrinks and Fries (200%)</label>
</fieldset>
<br>
<p><strong>Amount (US$)</strong>: <input type="text" name="amount" id="amount" value="" /></p>
First of all don't use same ID more than once, they should be unique.
Instead of that you can set your checkboxes with same class (just for ease selecting) and then count how many of them are checked:
function pmodel() {
var count = 0;
var list=document.getElementsByClassName("PNDLS");
for (var i = 0; i < list.length; ++i) { if(list[i].checked) { count++; } }
console.log(count);
}
<fieldset id="MNDLS">
<legend>Noodles</legend>
<input type="checkbox" name="NDLS" class="PNDLS" value="0.5" onclick="pmodel()">
<label for="Model">Spaghetti</label><br>
<input type="checkbox" name="NDLS" class="PNDLS" value="0.5" onclick="pmodel()">
<label for="Model">Carbonara</label><br>
<input type="checkbox" name="NDLS" class="PNDLS" value="0.5" onclick="pmodel()">
<label for="Model">Lasagna</label><br>
<input type="checkbox" name="NDLS" class="PNDLS" value="0.5" onclick="pmodel()">
<label for="Model">Plain</label>
</fieldset>
<fieldset id="MMD" disabled>
<legend>Main Dish</legend>
<input type="radio" name="MD" value="50" onclick="total()">
<label>Chicken Wings ($50)</label><br>
<input type="radio" name="MD" value="55" onclick="total()">
<label>Chicken Breast ($55)</label><br>
<input type="radio" name="MD" value="60" onclick="total()">
<label>Pork Cutlets ($60)</label><br>
<input type="radio" name="MD" value="65" onclick="total()">
<label>Steak($65)</label>
</fieldset>
<fieldset id="ADDONS" disabled>
<legend>Sides</legend>
<input type="radio" name="ADDONS" value="1" onclick="total()">
<label>Nothing (100%)</label><br>
<input type="radio" name="ADDONS" value="1.5" onclick="total()">
<label>Softdrinks (150%)</label><br>
<input type="radio" name="ADDONS" value="2" onclick="total()">
<label>Softdrinks and Fries (200%)</label>
</fieldset>
<br>
<p><strong>Amount (US$)</strong>: <input type="text" name="amount" id="amount" value="" /></p>
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>
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>
How do I get querySelectorAll to return all sliders with name="type" and also value="0"
My current code looks like this:
function getSlider0Values(name) {
const sliders = document.querySelectorAll(`input[name = "${name}"][value='0'] `);
let type_0preference_list = [];
sliders.forEach((range) => {
type_0preference_list.push(range.id);
});
return type_0preference_list;
}
<div class="type_sliders">
<label for="Apples">Apples</label>
<input type="range" name="type" min="0" max="5" value="0" id="Apples" class="type_slider">
<label for="Peaches">Peaches</label>
<input type="range" name="type" min="0" max="5" value="0" id="Peaches" class="type_slider">
<label for="Pears">Pears</label>
<input type="range" name="type" min="0" max="5" value="0" id="Pears" class="type_slider">
</div>
It's currently selecting all sliders, not just the ones with the value 0.
This can be a bit confusing, because while range.value will give you the current value of the slider the test for value='0' in CSS does not get updated on input changing.
You can update the attribute on a change and then your selecting will work. See this answer for a bit more explanation.
One thing you can do is listen for the change event on each input and update the actual attribute accordingly. Alternatively you could just do that in your function and not bother with additional event listeners. It depends on your actual use case.
This snippet does an update on a change by setting an event listener on each input so the value attribute is always uptodate.
//set an event listener on each input so value attribute can be updated
const allSliders = document.querySelectorAll('input.type_slider');
allSliders.forEach((slider) => {
slider.addEventListener('change', function() {
slider.setAttribute('value', slider.value);
});
});
function getSlider0Values(name) {
const sliders = document.querySelectorAll(`input[name = "${name}"][value='0'] `);
let type_0preference_list = [];
sliders.forEach((range) => {
type_0preference_list.push(range.id);
});
return type_0preference_list;
}
<div class="type_sliders">
<label for="Apples">Apples</label>
<input type="range" name="type" min="0" max="5" value="0" id="Apples" class="type_slider">
<label for="Peaches">Peaches</label>
<input type="range" name="type" min="0" max="5" value="0" id="Peaches" class="type_slider">
<label for="Pears">Pears</label>
<input type="range" name="type" min="0" max="5" value="0" id="Pears" class="type_slider">
</div>
<button onclick="console.log(getSlider0Values('type'))">Alter some slider(s) and then click me</button>
Your code is working. You are getting all the sliders because all of theme have name="type" and value="0".
const inputs = Array.from(document.getElementsByTagName('INPUT'));
const handler = (e) => {
const result = inputs.filter((input) => {
return (input.value === '0' && input.name === 'type');
});
console.log(result);
};
document.getElementById('Container').addEventListener('change', handler)
<div id="Container" class="type_sliders">
<label for="Apples">Apples</label>
<input type="range" name="type" min="0" max="5" value="0" id="Apples" class="type_slider">
<label for="Peaches">Peaches</label>
<input type="range" name="type" min="0" max="5" value="0" id="Peaches" class="type_slider">
<label for="Pears">Pears</label>
<input type="range" name="type" min="0" max="5" value="0" id="Pears" class="type_slider">
</div>
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>