I'm trying to do a simple calculation onblur with arrays but it's not firing. If I change it to a span or div it works fine. Why isn't it working with an input field?
I need it to be an input field because it's easier to store the values in a database.
<input type="text" class="input-small" name="partnumber[]">
<input type="text" class="input-small" name="partdescription[]" >
<input type="text" class="input-small" name="partprice[]" onblur="doCalc(); calculate(); ">
<input type="text" class="input-small" name="partquantity[]" onblur="doCalc(); calculate(); ">
<input type="text" readonly class="input-small parttotal" name="parttotal[]" >
Calculation
function doCalc() {
var total = 0;
$('tr').each(function() {
$(this).find('.parttotal').html($('input:eq(2)', this).val() * $('input:eq(3)', this).val());
});
$('.parttotal').each(function() {
total += parseInt($(this).text(),10);
});
}
Firstly, I wouldn't use inline events.. Here I've used delegated events, an advantage here if you dynamically add any more lines, it will still work..
Next make sure each line has some sort of wrapper for each line, here I've used a simple DIV. Yousr might be your TR..
The rest then becomes easy, as can be seen here, this example I've just included the price, qty & total, and done 2 lines for testing..
function calc() {
var h = $(this).closest('div');
var qty = h.find('[name="partquantity[]"]');
var price = h.find('[name="partprice[]"]');
var total = h.find('[name="parttotal[]"]');
total.val(qty.val() * price.val());
}
$('body').on('blur', '[name="partprice[]"],[name="partquantity[]"]', calc);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input type="text" class="input-small" name="partprice[]">
<input type="text" class="input-small" name="partquantity[]">
<input type="text" readonly class="input-small parttotal" name="parttotal[]" >
</div>
<div>
<input type="text" class="input-small" name="partprice[]">
<input type="text" class="input-small" name="partquantity[]">
<input type="text" readonly class="input-small parttotal" name="parttotal[]" >
</div>
you can't use .html() to set the value of a textbox.
Change this line:
$(this).find('.parttotal').html($('input:eq(2)', this).val() * $('input:eq(3)', this).val());
to
$(this).find('.parttotal').val($('input:eq(2)', this).val() * $('input:eq(3)', this).val());
Note the change ('.parttotal').html becomes ('.parttotal').val
Related
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/>
I have the following
<input type="text" class="form-control" name="total1" id="total1">
<input type="text" class="form-control" name="total1" id="total2">
I already get these two values using javascript.
but I want to display the result in a span like below or a P tag
<span id="sum">0</span>
I tried the following...but i want it to be auto...meaning once the input field if there, total should also appear
<script type="text/javascript" language="javascript" charset="utf-8">
function output(){
var value1 = document.getElementById('value1').value;
var value2 = document.getElementById('value2').value;
document.getElementById('result').innerHTML = parseInt(value1) + parseInt(value2);
}
function updateTextInput(val) {
document.getElementById('value2').value=val;
}
</script>
If you want to display the result you can simply use
Javascript : document.getElementById("sum").innerText = SumOfTwoValues
Jquery : $("#sum").text(SumOfTwoValues);
Please make sure you add required validations for the Summation value before assigning it.
Well first of you need some way to call the function output.
Now there are a few problems regarding the Ids of the elements, you have id="total1" but you are trying to call getElementById('value1').
same goes for total2 and sum.
Last I would add || 0 after your .value so incase 1 of the input's haven't been filled, then it set to 0, so we can use it as a number.
function output() {
var value1 = document.getElementById('total1').value || 0;
var value2 = document.getElementById('total2').value || 0;
document.getElementById('sum').innerHTML = parseInt(value1) + parseInt(value2);
}
<input type="text" class="form-control" oninput="output()" name="total1" id="total1">
<input type="text" class="form-control" oninput="output()" name="total1" id="total2">
<span id="sum">0</span>
With vanilla javascript
function a()
{
var a1=document.querySelectorAll('input')
let sum=0;
for(let i=0;i<a1.length;i++)
sum+=Number(a1[i].value)
document.querySelector('#e').innerHTML=sum
}
<input type="text" class="form-control" name="total1" id="total1" onchange="a()">
<input type="text" class="form-control" name="total1" id="total2" onchange="a()">
<p id="e"></p>
Calculation in one line of Javascript.
function calc() {
document.querySelector('#sum').innerHTML = [...document.querySelectorAll('input')].reduce((acc, input) => acc + Number(input.value), 0);
}
<input type="text" class="form-control" name="total1" id="total1" onchange="calc()">
<input type="text" class="form-control" name="total1" id="total2" onchange="calc()">
<p id="sum"></p>
Inputs are invisible to jQuery when they are appended.
THere are 3 inputs
<input class="bul-order-info__input bul-order-info__price" type="text" name="price" value="500" readonly>
<input class="bul-order-info__input bul-order-info__qnt" type="number" name="quantity" min="1" value="1">
<input class="bul-order-info__input bul-order-info__total" type="text" name="totalPrice" value="" readonly>
with this code
let $output = $("#output-value");
let $price = $(".bul-order-info__price");
$(document).on('change', ".bul-order-info__qnt", function () {
let value = parseFloat($(this).val());
$output.val(value * $price.val());
});
If I have these inputs in my html created manually, I can multiply the inputs value and add the result into the total price input.
But I need these inputs to appear after the click event, so I append them. After that they become invisible to jQuery, hence nothing works.
How can I make these inputs appear on the page, in the form, and then manipulate their values?
You did only one mistake while assigning the value to the input field which displays the multiplication result
let $output = $("#output-value");
let $price = $(".bul-order-info__price");
$(document).on('change', ".bul-order-info__qnt", function () {
let value = parseFloat($(this).val());
let tot=value * $price.val();
$(".bul-order-info__total").val(tot);
});
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<input class="bul-order-info__input bul-order-info__price" type="text" name="price" value="500" readonly>
<input class="bul-order-info__input bul-order-info__qnt" type="number" name="quantity" min="1" value="1">
<input class="bul-order-info__input bul-order-info__total" type="text" name="totalPrice" value="" readonly>
</body>
</html>
Jquery can't find dynamically generated elements directly.
You can access them using it's parent which is not appended dynamically.
$(document).on('change', "body .bul-order-info__qnt", function () {
let value = parseFloat($(this).val());
$output.val(value * $price.val());
});
I have 2 textboxes with a type="number".
1 textbox is my 'master' textbox, then I have another subsequent textbox that I would like that IF the 'master' textbox is filled in with a number, the subsequent textbox would get the same value.
I thought about using the data- attribute but I am not sure how to target if the 'master' textbox is filled then, then subsequently put the same value in the sub textbox(es) with the same data- attribute.
In my example below I also use spans to create plus and minus buttons that adjust the value based on the value. This is in the JS section.
My current HTML is as follow:
<div id="masterTextboxes">
<span class="minusBtn AddMinusButton">-</span>
<input type="number" value="" placeholder="0" data-attendees="Adult" />
<span class="addBtn AddMinusButton">+</span>
<span class="minusBtn AddMinusButton">-</span>
<input type="number" value="" placeholder="0" data-attendees="Child" />
<span class="addBtn AddMinusButton">+</span>
</div>
<!--Values from Master Textboxes should populate into these textboxes as well.-->
<div id="subTextboxes">
<span class="minusBtn AddMinusButton">-</span>
<input type="number" value="" placeholder="0" data-attendees="Adult" />
<span class="addBtn AddMinusButton">+</span>
<span class="minusBtn AddMinusButton">-</span>
<input type="number" value="" placeholder="0" data-attendees="Child" />
<span class="addBtn AddMinusButton">+</span>
</div>
Javascript
<script>
$(document).ready(function () {
/*Add an minus buttons for variants*/
$(".AddMinusButton").on('click touchstart', function (event) {
event.preventDefault();
//Add button active style for touch.
var $button = $(this);
var oldValue = $button.parent().find("input").val();
var newVal = oldValue;
//Hide .decButton for oldValue
if (newVal == 0 || oldValue == 0 ) {
oldValue = 0;
}
else { $button.parent().find(".minusBtn").show(); }
if ($button.text() == "+") {
newVal = parseFloat(oldValue) + 1;
// Don't allow decrementing below zero
if (oldValue >= 1) {
newVal = parseFloat(oldValue) - 1;
}
}
$button.parent().find("input.attendeeQuantityInput").val(newVal);
//Sub textboxes should take value of master textboxes. Is this correct syntax?
//This is probably wrong.
$('#subTextboxes input').data("attendee").val(newVal);
});//End button click
});
</script>
I hope this makes sense on what I am trying to get out of this.
Thanks in advance.
I would like that IF the 'master' textbox is filled in with a number,
the subsequent textbox would get the same value.
You can do it like this:
<p>
<label>Master 1: <input type="number" id="master1" placeholder="0" /></label><br>
<label>Dependant 1: <input type="number" class="dependant1" placeholder="0" /></label>
</p>
<p>
<label>Master 2: <input type="number" id="master2" placeholder="0" /></label><br>
<label>Dependant 2: <input type="number" class="dependant2" placeholder="0" /></label><br>
<label>Dependant 2: <input type="number" class="dependant2" placeholder="0" /></label>
</p>
And in the JS:
$("input[id^='master']").on("change", function(){
var no = this.id.replace("master", "");
var selector = ".dependant" + no
$(selector).val(this.value);
});
This makes use of jQuery's attribute starts with selector and will work for any number of inputs provided the class names match.
Demo
You could do this:
HTML:
<div id="masterTextboxes">
<p>Master</p>
<input type="number" value="" placeholder="0" data-attendees="Adult" />
<input type="number" value="" placeholder="0" data-attendees="Child" />
</div>
<div id="subTextboxes">
<p>Sub</p>
<input type="number" value="" placeholder="0" data-attendees="Adult" />
<input type="number" value="" placeholder="0" data-attendees="Child" />
</div>
JS:
// On change in master inputs...
$("#masterTextboxes input", this).on("change", function() {
// Store Master inputs in master variable and Sub inputs in sub variable.
var master = $("#masterTextboxes input"),
sub = $("#subTextboxes input");
// Match master and sub values by using the master array key as reference.
$(sub[$.inArray($(this)[0], master)]).val( $(this).val() );
});
The jQuery code relies on the condition that the Sub inputs follow the same order as the Master's inside each respective div.
JSFiddle:
Here's a working JSFiddle for reference.
I have dynamic form like:
<form id="formaa">
<div class="row">
<input type="text" name="item" class="item"></input>
<input type="text" name="quant" class="quant"></input>
<input type="text" name="price" class="price" onkeyup="update();"></input>
<input type="text" name="sum" id="suma" size="10" disabled="disabled"/>
</div>
<div class="row">
<input type="text" name="item" class="item"></input>
<input type="text" name="quant" class="quant"></input>
<input type="text" name="price" class="price" onkeyup="update();"></input>
<input type="text" name="sum" id="suma" size="10" disabled="disabled"/>
</div>
<!-- ... many more rows -->
<input type="text" disabled id="total" name="tot"></input>
</form>
What I'm trying to do is multiply item quantity and price and get total sum in sum field for each item seperately (not all items total sum).
What I have achiecved is this function, but it seems counting total sum of all items together not seperately and this working with first default field row, when I add new set of fields and fill them with information both, fields (and other later added) sum values become NaN..If I remove all added field sets and leave the first form fows set, number is working again.. What is the problem here?
<script type="text/javascript">
function update() {
var total = 0;
$("#formaa div.row").each(function(i,o){
total += $(o).find(".quant").val() *
$(o).find(".price").val();
if(!isNaN(total) && total.length!=0) {
sum += parseFloat(total);
}
});
$("#formaa div.row #suma").val(total);
}
</script>
function update() {
$("#formaa div.row").each(function(i,o){
var total = $(o).find(".quant").val() * $(o).find(".price").val();
if(!isNaN(total) && total.length!=0) {
sum += parseFloat(total);
}
$(o).find('[name="sum"]').val(total);
});
}
A few problems in your code :
never give the same id to more than one element. That's the reason why I defined the selector on the name
you weren't resetting the total, so it was the sum of all
I didn't fix that, but your operation before the float parsing is strange (it may depend on the content that I can't see)