JS - combine values from two functions - javascript

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>

Related

Insert Input Value into Label Text 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>

Why does my program only output a correct number when one input is filled out, but output incorrect results if anymore inputs are filled out?

My program calculates a student's GPA, but it only accurately outputs a GPA if one input is filled out. Once any other inputs are filled out, the program outputs wildly inaccurate numbers. How can I fix this?
The JavaScript:
function computeGPA() {
var aPlus = document.getElementById("aPlus").value;
var a = document.getElementById("a").value;
var aMinus = document.getElementById("aMinus").value;
var bPlus = document.getElementById("bPlus").value;
var b = document.getElementById("b").value;
var bMinus = document.getElementById("bMinus").value;
var cPlus = document.getElementById("cPlus").value;
var c = document.getElementById("c").value;
var cMinus = document.getElementById("cMinus").value;
var dPlus = document.getElementById("dPlus").value;
var d = document.getElementById("d").value;
var dMinus = document.getElementById("dMinus").value;
var f = document.getElementById("f").value;
var og = ((aPlus*4)+(a*4)+(aMinus*3.7)+(bPlus*3.3)+(b*3)+(bMinus*2.7)+(cPlus*2.3)+(c*2)+(cMinus*1.7)+(dPlus*1.3)+(d*1)+(dMinus*.7))/((aPlus)+(a)+(aMinus)+(bPlus)+(b)+(bMinus)+(cPlus)+(c)+(cMinus)+(dPlus)+(d)+(dMinus))
var prettyOg = og.toFixed(2);
document.getElementById("og").innerHTML = "GPA: " + prettyOg;
}
The HTML body:
<h1> Overall Grade Calculator</h1>
<p>Number of A+: <input id="aPlus" min="0" max="120"></input></p>
<p>Number of A: <input id="a" min="0" max="120"></input></p>
<p>Number of A-: <input id="aMinus" min="0" max="120"></input></p>
<p>Number of B+: <input id="bPlus" min="0" max="120"></input></p>
<p>Number of B: <input id="b" min="0" max="120"></input></p>
<p>Number of B-: <input id="bMinus" min="0" max="120"></input></p>
<p>Number of C+: <input id="cPlus" min="0" max="120"></input></p>
<p>Number of C: <input id="c" min="0" max="120"></input></p>
<p>Number of C-: <input id="cMinus" min="0" max="120"></input></p>
<p>Number of D+: <input id="dPlus" min="0" max="100"></input></p>
<p>Number of D: <input id="d" min="0" max="120"></input></p>
<p>Number of D-: <input id="dMinus" min="0" max="120"></input></p>
<p>Number of F: <input id="f" min="0" max="120"
<br>
<br>
<button onclick="computeGPA()">Submit</button>
<h2 id="og"></h2>
Since + operator used for concatenation as well as addition. Input box will provide string values so it's an ambiguous operation. To avoid this use parseInt() for addition operation.
Have a look at following example
let a = '3';
let b = '5';
const result = a + b;
console.log('Result without parsing', result);
const resultWithParse = parseInt(a, 10) + parseInt(b, 10);
console.log('Result after parsing', resultWithParse);

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

Get average value from multiple input fields(range)

I have been searching for a solution for days, i am an beginner in javascript.
This is the form i use to input value via sliders.
<div class="formSliderField" style="display:block">
<div class="formIcons" id="formSliderImage1"></div>
<div class="formSlider" id="formSlider1">
<input class="slider" name="cat_pk" type="range" min="0" max="10" step="0.5" width="290px" value="0" onchange="field1(this.value)"/>
</div>
<div class="formMark"><p id="formMark1" class="mark">1</p></div>
</div>
<div class="formSliderField" style="display:block">
<div class="formIcons" id="formSliderImage2"></div>
<div class="formSlider" id="formSlider2">
<input class="slider" name="cat_service" type="range" min="0" max="10" step="0.5" width="290px" value="0" onchange="field2(this.value)"/>
</div>
<div class="formMark"><p id="formMark2" class="mark">1</p></div>
</div>
<div class="formSliderField" style="display:block">
<div class="formIcons" id="formSliderImage3"></div>
<div class="formSlider" id="formSlider3">
<input class="slider" name="cat_prijs" type="range" min="0" max="10" step="0.5" width="290px" value="0" onchange="field3(this.value)"/>
</div>
<div class="formMark"><p id="formMark3" class="mark">1</p></div>
</div>
<div class="formSubmitWrapper">
<div id="formSubmitButton">
<input id="formRecensieSubmit" type="submit" value="Bevestigen"/>
</div>
</div>
I need the input value from these sliders to get an average for further use. This needs to be as dynamic as possible, not after i submit this form.
You can see i use onchange, this is already used in a function to display the input values per slider.
Hope someone can help me with this.
JavaScript :
window.onload = function(){
var elements=document.querySelectorAll('input[type=range]')
for(var i = 0; i < elements.length; i++){
elements[i].addEventListener('change',calcul , false);
}
}
function calcul(){
var elements = document.querySelectorAll('input[type="range"]')
var len = 0
var buf = 0
for(var i=0;i<elements.length;i++) {
if(elements[i].parentNode.parentNode.style.display != 'none'){
buf += parseInt(elements[i].value)
len++
}
}
buf = len === 0 ? 0 : buf/len
console.log(buf)
}
CodeOpen
Maybe you're trying to achieve something like this?
(function (win, doc, undefined) {
"use strict";
var myForm = doc.getElementById("myForm"),
sliders = myForm.getElementsByClassName("slider"),
marks = myForm.getElementsByClassName("mark");
myForm.addEventListener("change", changeHandler);
function changeHandler(e) {
var t = e.target,
i = -1,
sum = 0,
avg = 0;
if (t.nodeName.toLowerCase() === "input" && t.type.toLowerCase() === "range") {
i = [].indexOf.call(sliders, t);
marks[i].innerHTML = t.value;
[].forEach.call(sliders, function (val) {
sum += parseFloat(val.value);
});
avg = parseFloat((sum / sliders.length).toFixed(1));
}
console.log(avg);
}
}(window, window.document));
Look at Demonstration

Categories