Force input number decimal places natively - javascript

I'd like to force an <input type="number" step="0.01" /> to always have 2 decimals to enter accounting data.
I've managed to do that using JavaScript
document.getElementById('input').addEventListener('change', force2decimals);
function force2decimals(event) {
event.target.value = Number(Math.round(event.target.value * 100) / 100).toFixed(2);
}
<input type="number" step="0.01" id="input" value="1.00" />
Is there any way to handle this natively?
I know about the step attribute, the "duplicate answer" doesn't reply to my question.

It could be done by this:
document.getElementById('input').addEventListener('change', force2decimals);
function force2decimals(event) {
event.target.value = parseFloat(event.target.value).toFixed(2);
}
<input type="number" step="0.01" id="input" value="1.00" />
There is no way to do this "natively" in HTML5.

You can use this:
function force2decimals(event) {
var value = $(event).val();
var format_val = parseFloat(value).toFixed(2);
$(event).val(format_val);
}
<input type="number" step="0.01" id="input" onchange="force2decimals(this)" value="1.00" />
I hope this was helpful.

Related

Multiplication in jQuery dynamically

I am trying to make a multiplication function in jquery where which helps change the default value-based output.
For example - if I type the input#mainInput value then it will change all the inputs value base own his default value * input#mainInput and if the value == 'NaN' it will do dirent funcion.
Please help me how to I make this function in jQuery.
$(document).on('keyup', 'input#mainInput', function() {
thisParentQtyValueBox = $(this).val();
daughtersBoxValueAttr = $("input.input__bom").attr("inputid");
daughtersBoxValue = $("input#daughterInput_" + daughtersBoxValueAttr).val();
$("input#daughterInput_" + daughtersBoxValueAttr).val(thisParentQtyValueBox * daughtersBoxValue);
if ($("input#daughterInput_" + daughtersBoxValueAttr) == 'Nan') {
$("input#daughterInput_" + daughtersBoxValueAttr).val('3' * daughtersBoxValue)
}
});
//If
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="mainInput" type="text" placeholder="Number" />
<br><br>
<input class="input__bom" id="daughterInput_1" type="text" placeholder="value" inputid="1" value="5" /><br/>
<input class="input__bom" id="daughterInput_2" type="text" placeholder="value" inputid="2" value="10" /><br/>
<input class="input__bom" id="daughterInput_3" type="text" placeholder="value" inputid="3" value="15" /><br/>
<input class="input__bom" id="daughterInput_4" type="text" placeholder="value" inputid="4" value="20" /><br/>
<input class="input__bom" id="daughterInput_5" type="text" placeholder="value" inputid="5" value="25" /><br/>
If I understand correctly, when the input is not a number, you want to do as if the input was 3.
Some issues in your code:
$("input.input__bom").attr("inputid") is always going to evaluate to 1, as only the first matching element is used. And it is strange to use this attribute value to then retrieve that element again via its id property.
You would need a loop somewhere so to visit each of the "input__bom" elements.
== 'Nan is never going to be true. You should in fact test the main input itself to see if it represents a valid number. For that you can use isNaN.
It is a bad idea to give these elements a unique id attribute. You can use jQuery to visit them each and deal with them. There is no need for such id attribute.
Don't use the keyup event for this, as input can be given in other ways than pressing keys (e.g. dragging text with mouse, or using the context menu to paste). Use the input event instead.
There is no good reason to use event delegation here on $(document). Just bind your listener directly the main input element.
Declare your variables with var (or let, const). It is bad practice to no do that (it makes your variables global).
It seems like the 5 "bom" input elements are not really intended for input, but for output. In that case the placeholder attribute makes no sense, and they should better be marked with the readonly attribute.
$("#mainInput").on('input', function() {
var mainInput = $(this).val();
var multiplier = +mainInput; // convert to number with unary +
// default value in case input is not a valid number, or is empty
if (Number.isNaN(multiplier) || !mainInput) {
multiplier = 3;
}
$('.input__bom').each(function() {
$(this).val( multiplier * $(this).data('value') );
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="mainInput" type="text" placeholder="Number" />
<br><br>
<input class="input__bom" type="text" readonly data-value="5" value="5"><br/>
<input class="input__bom" type="text" readonly data-value="10" value="10"><br/>
<input class="input__bom" type="text" readonly data-value="15" value="15"><br/>
<input class="input__bom" type="text" readonly data-value="20" value="20"><br/>
<input class="input__bom" type="text" readonly data-value="25" value="25" /><br/>
You have to store the default value in the data attr so then it will not multiple by result value and it will multiple by your default value. for dynamic multiplication, you can use jquery each. check below code.
$(document).on('input', 'input#mainInput', function() {
thisParentQtyValueBox = parseInt( $(this).val() );
if( Number.isNaN( thisParentQtyValueBox ) ){
thisParentQtyValueBox = 3;
}
$('.input__bom').each(function(){
$(this).val( thisParentQtyValueBox * $(this).data('value') );
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="mainInput" type="text" placeholder="Number" />
<br><br>
<input class="input__bom" id="daughterInput_1" type="text" placeholder="value" inputid="1" data-value ="5" value="5" /><br/>
<input class="input__bom" id="daughterInput_2" type="text" placeholder="value" inputid="2" data-value ="10" value="10" /><br/>
<input class="input__bom" id="daughterInput_3" type="text" placeholder="value" inputid="3" data-value ="15" value="15" /><br/>
<input class="input__bom" id="daughterInput_4" type="text" placeholder="value" inputid="4" data-value ="20" value="20" /><br/>
<input class="input__bom" id="daughterInput_5" type="text" placeholder="value" inputid="5" data-value ="25" value="25" /><br/>

Iterate through N number of input boxes, updating each to their max value

Is there a way to give a bunch of inputs the same ID, and then iterate over them, when a checkbox is checked, and update their respective values to the MAX attribute? For example, with the following HTML:
CHECK ALL: <input type="checkbox" id="someIDname">
<input type="number" max="80" id="anotherIDname">
<input type="number" max="90" id="anotherIDname">
<input type="number" max="99" id="anotherIDname">
<input type="number" max="65" id="unrelated">
<input type="number" max="75" id="unrelated">
... and the JS is like this:
<script type="text/javascript">
$(document).ready(function() {
$('#someIDname').click(function(event) {
if(this.checked) {
$('#anotherIDname').each( function() {
var maxValue = $("#anotherIDname").attr("max");
document.getElementById("anotherIDname").value = maxValue;
});
}
});
});
</script>
I'd like to, when the checkbox is checked, have it fill in all of the MAX attributes from anything with the "anotherIDname" ID. (I'd then have three boxes, onewith 80, one with 90, one with 99. The other two are different IDs, so it would leave those alone.)
Total beginner with JS / jQuery here... The above script works on the 1st box, but does not update the others with the "anotherIDname" ID. (I thought maybe that ".each" would make it do them all, one at a time, but ... I guess that's not how it works. (I'm more of a PHP guy, normally, and that would be how something like this could maybe work if it was server-side.) Any thoughts appreciated.
There are few things wrong
id is always unique in the page.Same class is assigned to elements having same features
You should use $(this).val() to set the value
$(document).ready(function() {
$('#someIDname').click(function(event) {
if(this.checked) {
$('.anotherIDname').each( function() {
var maxValue = $(this).attr("max");
console.log(maxValue);
$(this).val(maxValue)
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" id="someIDname">
<input type="number" max="80" class="anotherIDname">
<input type="number" max="90" class="anotherIDname">
<input type="number" max="99" class="anotherIDname">
<input type="number" max="65" class="unrelated">
<input type="number" max="75" class="unrelated">
Added a class name and used querySelectorAll. Does this work as you want?
$(document).ready(function() {
$('#someIDname').click(function(event) {
if(this.checked) {
document.querySelectorAll('.max').forEach(a => {
a.value = a.max;
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
CHECK ALL: <input type="checkbox" id="someIDname">
<input type="number" max="80" id="anotherIDname" class="max">
<input type="number" max="90" id="anotherIDname" class="max">
<input type="number" max="99" id="anotherIDname" class="max">
<input type="number" max="65" id="unrelated" class="max">
<input type="number" max="75" id="unrelated" class="max">
The id must be unique in the page. So, you can't use same id in several places. However, you can use same class in several places.
So, you'll need to change the id to class for eg.:
<input type="number" max="80" class="maxinput" />
And to set the value from max attribute:
$('.maxinput').val(function() {
return $(this).attr('max')
});
However, I would suggest to use data-* instead of simple attribute:
<input type="number" data-max="80" class="maxinput" />
And get the data value:
$('.maxinput').val(function() {
return $(this).data('max')
});
But I am still in surprise why you aren't simply setting their values initially?
<input type="number" class="maxinput" value="80" />

Javascript to calculate input field values and show 2 decimal place accuracy

I understand this may be a repeat question but I have been searching for ages and cant figure out why this isnt working.
I have 3 input fields, Subtotal, Vat and Total: I want to be able to populate the VAT and Total inpur fields with values when there is a value inputted in Subtotal and to show 2 decimal palces after. So:
4 would be 4.00
4.5 would be 4.50
HTML code for the input field:
<input name="subtotal" id="subtotal" type="number" maxlength="20" min="0" placeholder="00.00" onchange="vatCalculation();" />
<input name="vat" id="vat" type="number" maxlength="20" min="0" placeholder="00.00" readonly="true" />
<input name="total" id="total" type="number" maxlength="20" min="0" placeholder="00.00" readonly="true" />
And the javascript code I have at the moment is:
function vatCalculation() {
var subtotal = document.getElementById('subtotal').value;
var vat = parseFloat(parseFloat(subtotal) * parseFloat(0.2)).toFixed(2);
var total = parseFloat(parseFloat(subtotal) + parseFloat(vat)).toFixed(2);
document.getElementById('vat').value = vat;
document.getElementById('total').value = total;
}
I cant see where I am going wrong. When I enter 10 in the 'subtotal'input field the 'VAT' and 'Total' fields change to 2 and 12. But I want them to show 2.00 and 12.00. Screenshot below:
SOLUTION:
When using Firefox the input field of type="number" dont seem to work with javascript calculation. Workaround is to change it to a type="text" Like J Santosh as mentioned below and it works.
Found the issue . It is with <input type='number'> you change it to <input type='text'>
Working Fiddle
Input Type Number is not accepting decimals
Reference -1
Reference-2
Is this what you want? If so, you were pretty close. You just needed to add
document.getElementById('subtotal').value = parseFloat(subtotal).toFixed(2);
to your code as well.
function vatCalculation() {
var subtotal = document.getElementById('subtotal').value;
var vat = parseFloat(parseFloat(subtotal) * parseFloat(0.2)).toFixed(2);
var total = parseFloat(parseFloat(subtotal) + parseFloat(vat)).toFixed(2);
document.getElementById('subtotal').value = parseFloat(subtotal).toFixed(2);
document.getElementById('vat').value = vat;
document.getElementById('total').value = total;
}
<input name="subtotal" id="subtotal" type="text" maxlength="20" min="0" placeholder="00.00" onchange="vatCalculation();" />
<input name="vat" id="vat" type="text" maxlength="20" min="0" placeholder="00.00" readonly="true" />
<input name="total" id="total" type="text" maxlength="20" min="0" placeholder="00.00" readonly="true" />
(2.399).toFixed(2); will give you 2.40
But if you need 2.39 try
parseInt(2.399 * 100)/100

Local Storage form in HTML5

I'm trying to store numbers into local storage for a type website with a type of shopping cart... I found examples where storing text/email works but when I try to store as numbers instead of text or change the form names it doesn't seem to work.
This is my form I made on the site to capture the data, followed by the javascript that should fill in saved data from another session, capture data, and (currently reset on submit) data.
<form id="localStorageCart" method="post" action="">
<label>Rooster:</label>
<input type="number" name="roosterQ" id="roosterQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Cow:</label>
<input type="number" name="cowQ" id="cowQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Cat:</label>
<input type="number" name="catQ" id="catQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Sheep:</label>
<input type="number" name="sheepQ" id="sheepQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Dumpster:</label>
<input type="number" name="dumpsterQ" id="dumpsterQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Dog:</label>
<input type="number" name="dogQ" id="dogQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Horse:</label>
<input type="number" name="horseQ" id="horseQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<input type="submit" class="submitOrder" value="Submit" />
</form><br>
<br>
<script type="text/javascript">
$(document).ready(function () {
function init() { /* checks for stored data and fills in... */
if (localStorage["roosterQ"]) {
$('#roosterQ').val(localStorage["roosterQ"]);
}
if (localStorage["cowQ"]) {
$('#cowQ').val(localStorage["cowQ"]);
}
if (localStorage["catQ"]) {
$('#catQ').val(localStorage["catQ"]);
}
if (localStorage["sheepQ"]) {
$('#sheepQ').val(localStorage["sheepQ"]);
}
if (localStorage["dumpsterQ"]) {
$('#dumpsterQ').val(localStorage["dumpsterQ"]);
}
if (localStorage["dogQ"]) {
$('#dogQ').val(localStorage["dogQ"]);
}
if (localStorage["horseQ"]) {
$('#horseQ').val(localStorage["horseQ"]);
}
}
init();
});
$('.stored').keyup(function () { /* keyup runs when key is pressed in a form with "stored"... Write to LS */
localStorage[$(this).attr('name')] = $(this).val();
});
$('#localStorageCart').submit(function() { /* currently resets all LS data*/
localStorage.clear();
});
</script>
localStorage can only hold strings, therefore if you want to store numbers you need to type convert
var num = 1.5, str;
// Number to string, would be done implicitly by localStorage
str = num.toString();
// String to number
num = +str; // note nothing infront of the + sign.
// OR
// num = window.parseFloat(str,10); // or parseInt if you want integers
console.log(num, str);
// 1.5 "1.5"
or change the form names it doesn't seem to work
Are you updating your init, too? To avoid having to do this in the future, it should loop over .stored rather than get each individually by id.
If you still want to do it via localstorage, you might want to check json.stringify before storing the variables
var obj = { 'a': 1, 'b': 2, 'c': 3 };
localStorage.setItem('obj', JSON.stringify(obj));
What do you intent to do anyway? are you just trying to retain the field for next use or reload of page?
if so, you might want to try this plugin, Sisyphus
http://simsalabim.github.com/sisyphus/

Simple reusable javascript averaging function for multiple forms on same page

I literally started trying to teach myself javascript less than 48 hours ago. Outside of just wanting to learn it I also have a small personal project I'm working on and using as sort of my working learn as I go example. But I've hit a problem, which I'm sure is rather basic, I'm just hampered by lack of much javascript knowledge.
Basically it is just an averaging problem.
There are going to be 4 inputs fields with the 4th being a rounded to the nearest whole number average of the first three fields.
This 4 field configuration is going to get used multiple times on the page.
I want it to work in "real time" and not with a calculate button so I'm assuming "onKeyup" is needed. (no validation of any kind is needed or submit or saving or anything)
The only code I've been able to get close is really really ugly, long, and convoluted. I can't help but think there is a very simple way to do it and just get the same function to apply to each grouping of inputs. It will look like below but probably much longer.
some text
<input id="a" type="number" /><br/>
<input id="b" type="number" /><br/>
<input id="c" type="number" /><br/>
<input id="final" value="0" disabled />
some text
<input id="a" type="number" /><br/>
<input id="b" type="number" /><br/>
<input id="c" type="number" /><br/>
<input id="final" value="0" disabled />
Thanks in advance. This is part of a larger problem but I've tried to strip it down to it's essence and seeing it work and understanding it will go a long way to helping me solve some other problems.
To start with use a different markup, there should only be a single id per page, so use classes, it make it easier to target everything too. Also if the effect is to use the last input as a display you can use readonly instead of disabled
<p>some text</p>
<div class="group">
<input class="a" type="number" /><br/>
<input class="b" type="number" /><br/>
<input class="c" type="number" /><br/>
<input class="final" value="0" readonly />
</div>
<p>some text</p>
<div class="group">
<input class="a" type="number" /><br/>
<input class="b" type="number" /><br/>
<input class="c" type="number" /><br/>
<input class="final" value="0" readonly />
</div>​
Here is an example done in jquery
$(function() {
$('.group input').on('click', function() {
var count = parseInt($(this).val()) || 0;
$(this).siblings(':not(.final)').each(function() {
if ($(this).val()) count = count + parseInt($(this).val());
});
$(this).siblings('.final').eq(0).val(count);
});
});
And the demo is here: http://jsfiddle.net/4S4Vp/1/
​
This should be understandable for your level. The second set of inputs will be named a-2 with calc(2) and so on.
<input id="a-1" type="number" onkeyup="calc(1)" value="0" /><br/>
<input id="b-1" type="number" onkeyup="calc(1)" value="0" /><br/>
<input id="c-1" type="number" onkeyup="calc(1)" value="0" /><br/>
<input id="final-1" value="0" disabled />
function calc( n ) {
var a = document.getElementById("a-" + n ).value;
var b = document.getElementById("b-" + n ).value;
var c = document.getElementById("c-" + n ).value;
document.getElementById("final-" + n ).value = Math.round((parseInt(a)+parseInt(b)+parseInt(c))/3);
}
This is really quick and dirty, but if you know how many inputs you have, this should work:
// these would instead be your textboxes
​var a = document.getElementById('a').value();
var b = document.getElementById('b').value();
var c = document.getElementById('c').value();
var avg = (a+b+b)/3;
document.getElementById('c').value() = avg;
Here is a jsfiddle so you can play with the idea and see if it works as you want it to.
Use jquery.
see the live demo on jsfiddle
some text
<div id="div1">
<input id="a" type="number" /><br/>
<input id="b" type="number" /><br/>
<input id="c" type="number" /><br/>
<input id="final" value="0" disabled />
</div>
some text
<div id="div2">
<input id="a" type="number" /><br/>
<input id="b" type="number" /><br/>
<input id="c" type="number" /><br/>
<input id="final" value="0" disabled />
</div>​
<script type="text/javascript">
$("#div1 input").bind('change keyup click',function(){
var final = 0;
$("#div1 input").not("#div1 #final").each(function(idx,el){
final += (el.value) ? parseInt(el.value) : 0;
});
$("#div1 #final").val(final/3);
});
$("#div2 input").bind('change keyup click',function(){
var final = 0;
$("#div2 input").not("#div2 #final").each(function(idx,el){
final += (el.value) ? parseInt(el.value) : 0;
});
$("#div2 #final").val(final/3);
});
​</script>
I hoped to flag this as duplicate, but because this answer does not have code, enjoy:
// find all inputs in the page and gather data trying to convert it to number
var data = [].map.call( document.querySelectorAll('input'), function (v) {
if (typeof v.value * 1 === 'NaN') {
return 'NaN';
}
return v.value * 1;
});
// not all data will be valid, so we filter it
data = data.filter( function (v) {
return !isNaN(v);
});
// and then calculate average
var avg = data.reduce( function (v, v1) {
return v + v1;
}) / data.length;

Categories