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

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"/>

Related

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

Calculate the values of input where each input has different prices. Any shorter code for this?(javascript only)

The code below is working fine but what if there are 100 inputs? any shorter way to do this?
function checkTotal() {
var a = document.getElementById("sandwich").value;
var b = document.getElementById("burger").value;
var c = document.getElementById("cake").value;
var d = document.getElementById("coffee").value;
document.getElementById("total").value = parseInt(a) * 10 + parseInt(b) * 5 + parseInt(c) * 15 + parseInt(d) * 20;
}
<form role="form" name="listForm">
<label>Sandwich</label>
<input type="number" id="sandwich" value="0" onkeyup="checkTotal()"><br>
<label>Burger</label>
<input type="number" id="burger" value="0" onkeyup="checkTotal()"><br>
<label>Cake</label>
<input type="number" id="cake" value="0" onkeyup="checkTotal()"><br>
<label>Coffee</label>
<input type="number" id="coffee" value="0" onkeyup="checkTotal()"><br> Total: <input type="text" size="2" name="total" id="total" value="0" />
</form>
1) Here each input article has a different price.
2) The value of the input should be mutiply with its price given(Eg. if the sandwich has a price:30, and user inputs value 2 it should calculte the total=price*input value.)
3) i have my code which is working fine but is the above code is the right way to do?
4) what if there are 100 of article inputs. is there shorter code or should i create variable for each one?
what if there are 100 of article inputs. is there shorter code or
should i create variable for each one?
You can maintain a map
var idPriceMap = {
"sandwich" : 20,
"burger" : 10,
"cake" : 5,
"coffee" : 10
};
You can iterate this and produce your value using reduce
var output = Object.keys( idPriceMap ).reduce( function(a,b){
var value = +document.getElementById( b ).value;
a += value * idPriceMap[ b ];
return a;
}, 0);
document.getElementById( "total" ).value = output;
Another way to try is to give your elements a class and some data attributes that can be retrieved by JavaScript using dataset. You can then use them to make your calculations. That way you get rid of ids and you just have to change the HTML code to add a new element.
function checkTotal() {
var total = 0,
foods = document.querySelectorAll('.food');
for (var i = 0; i < foods.length; i++) {
var food = foods[i],
name = food.dataset.item,
price = parseInt(food.dataset.price),
howMany = parseInt(food.value);
console.log(howMany, name, 'costs', (howMany * price));
total += howMany * price;
}
document.getElementById('total').value = total;
}
<form role="form" name="listForm">
<label>Sandwich</label>
<input class="food" data-item="sandwich" data-price="30" type="number" value="0" onBlur="checkTotal()"><br>
<label>Burger</label>
<input class="food" data-item="burger" data-price="10" type="number" value="0" onBlur="checkTotal()"><br>
<label>Cake</label>
<input class="food" data-item="cake" data-price="5" type="number" value="0" onBlur="checkTotal()"><br>
<label>Coffee</label>
<input class="food" data-item="coffee" data-price="15" type="number" value="0" onBlur="checkTotal()"><br>
Total: <input type="text" size="2" name="total" id="total" value="0" />
</form>
As a side note, you should give a try on Angular or Knockout which can help you to achieve those operations.

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>

Display Leading Zeros On Input Number Fields

I have two input fields representing hours and minutes.
<input type="number" min="0" max="24" step="1" value="00" class="hours">
<input type="number" min="0" max="0.60" step="0.01" value="00" class="minutes">
Which display as:
0:0
Or:
5:3
Is there a way to display it as:
00:00
Or:
05:03
i.e in 24-hour data format (before people suggest it, I can't use type="time").
You can add an onchange attribute to your input tag, which calls a javascript function.
<script>
function myFunction() {
var minuteValue = document.getElementById("minutes").value;
if (minuteValue.length < 2) {
minuteValue = "0" + minuteValue;
}
alert(minuteValue);
}
</script>
<input id="minutes" onchange="myFunction()"/>
function formatNums(num){
if (nums < 10){
return "0" + num;
}
}
var formattedHours = formatNums(hours);
var formattedMinutes = formatNums(minutes);
NOTE: This method uses type="text" so be sure to convert back to a number if needed. Number(formattedHours);
Add a leading zero with a JavaScript function.
const hours = document.getElementById("hours");
const minutes = document.getElementById("minutes");
function addLeadingZero(value) {
return value.length < 2 ? "0" + value : value;
}
hours.addEventListener("input", function() {
hours.value = addLeadingZero(hours.value);
});
minutes.addEventListener("input", function() {
minutes.value = addLeadingZero(minutes.value);
});
<input type="number" min="0" max="24" value="00" id="hours" class="hours">
<input type="number" min="0" max="59" value="00" id="minutes" class="minutes">
simple is the best
`${number}`.padStart(2, '0')

Categories