I have a dynamically created form in that a user can click "add row" and get a new element in the form.
some of the elements are quantity and price. I want to change values based on what users enter. so if he chooses qty=4 and price=10 i want amount to =40.
I dont know what to use as the selector for price or amount since input ids are dynamically generated.
var form = "<tr><td>Quantity</td>
<td><input class='qty' type='text' id='qty[]' name='qty[]'></td>";
form += "<td>Part Num</td>
<td><input type='text' id='part[]' name='part[]'></td>";
form += "<td>Description</td>
<td><input class='desc' type='text' id='desc[]' name='desc[]'></td>";
form += "<td>Unit Price</td>
<td><input type='text' id='price[]' name='price[]'></td>";
form += "<td>Amount</td>
<td><input type='text' id='amount[]' name='amount'></td></tr>";
$('#addItem').click(function(){
$('#itemsTable').append(form);
});
$(document).on('change','.qty',function(){
//What can i use as a selector for value_of_qty and value_of_price here???
//var total = $(value_of_qty) * $(value_of_price);
//$(id_of_amount).val(total);
});
on form submissions i see the following:
[qty] => Array
(
[0] => asdfdasf
[1] => asdfdasf
)
and so on....
You have (roughly) this structure:
<tr>
<td><input class="qty"></td>
<td><input name="price[]"></td>
</tr>
So, given that you have the .qty input, all you need to do is rise to the tr and get its input[name='price[]']. In code:
$(document).on('change','.qty',function(){
var $qty = $(this);
var $price = $qty.closest("tr").find("input[name='price[]']");
});
As I described in my comment, your HTML is invalid because you have duplicate ids. You should dynamically generate the HTML you append to the parent element, and assign a unique id value with each appendage. Here's what I would do:
var g_ROWNUM = 1;
$('#addItem').click(function() {
var form = '\
<tr>\
<td>Quantity</td><td><input class="qty" type="text" id="qty_${num}" name="qty[]"></td>\
<td>Part Num</td><td><input type="text" id="part_${num}" name="part[]"></td>\
<td>Description</td><td><input class="desc" type="text" id="desc_${num}" name="desc[]"></td>\
<td>Unit Price</td><td><input type="text" id="price_${num}" name="price[]"></td>\
<td>Amount</td><td><input type="text" id="amount_${num}" name="amount[]"></td>\
</tr>\
'.replace(/\$\{num\}/g,g_ROWNUM++);
$('#itemsTable').append(form);
});
$(document).on('change', '.qty', function() {
var qtyInput = $(this);
var num = qtyInput.attr('id').replace(/^qty_/,'');
var priceInput = $('#price_'+num);
var amountInput = $('#amount_'+num);
var total = qtyInput.val()*priceInput.val();
amountInput.val(total);
});
As you can see, this allows you to extract the generated number and use it to retrieve the price and amount elements in the same row as the changed quantity element, and then apply any dynamic changes you want to the elements in that row.
http://jsfiddle.net/p6wrkne4/1/
you should restructure your html by adding classes like this:
<tr class="tableRow">
<td>Quantity</td>
<td><input class='qty' type='text' id='qty[]' name='qty[]'/></td><td>Part Num</td>
<td><input type='text' id='part[]' name='part[]'/></td>
<td>Description</td>
<td><input class='desc' type='text' id='desc[]' name='desc[]'/></td>
<td>Unit Price</td>
<td><input type='text' class="price" id='price[]' name='price[]'/></td>
<td>Amount</td>
<td><input type='text' class="amount" id='amount[]' name='amount'/></td>
</tr>
$(document).on('change', '.qty', function() {
var qty = $(this).val();
var price = $(this).closest('.tableRow').find('.price').val();
var total = qty * price;
$(this).closest('.tableRow').find('.amount').val(total);
});
Try this code:
$(document).on('change','.qty',function(){
var qtyInput = $(this);
var price = qtyInput.closest("tr").find("input[name='price[]']").val();
var amount = qtyInput.val() * price;
qtyInput.closest("tr").find("input[name=amount]").val(amount);
});
Related
Could someone please tell me how I can use the index in this situation?
I have a text field, which is my multiplication factor
<input type="text" id="value">
And I have a table that has 2 fields arranged in the same tr
One with a fixed value
And one that must be the result of multiplying these two values.
Example:
In input I set value = 2
Field Value2 = Value 1 * 2
Value 1
Value 2
3
6
4
8
My jQuery function looks like this:
$( "#btn" ).on( "click", function()
{
let vlUS = $('#value').val()
$("table > tbody > tr > td > input")
.each(function (index) {
let vl1 = $('.val1').val()
let vl2 = vl1 * vlUS
$('.val2').val(vl2)
});
});
Using this way, assigns the same value to all "value2" fields
How can I use index to tune the process?
Loop over the rows and use each row instance to find() the specific inputs within that row
$("#btn").on("click", function() {
let vlUS = $('#value').val();
$("table > tbody > tr").each(function(index) {
const $row = $(this);
let vl1 = $row.find('.val1').val()
let vl2 = vl1 * vlUS
$row.find('.val2').val(vl2);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn">
Calculate
</button> US: <input id="value" value="5" />
<table>
<tr>
<td><input type="text" class="val1" value="3"></td>
<td><input type="text" class="val2"></td>
</tr>
<tr>
<td><input type="text" class="val1" value="6"></td>
<td><input type="text" class="val2"></td>
</tr>
</table>
Consider the following code.
$("#btn").on("click", function() {
$("table tbody tr").each(function(index, elem) {
$(".val2", elem).val(parseInt($(".val1", elem).val()) * parseInt($("#value").val()));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn">Calculate</button> US: <input id="value" value="5" />
<table>
<tr>
<td><input type="text" class="val1" value="3"></td>
<td><input type="text" class="val2"></td>
</tr>
<tr>
<td><input type="text" class="val1" value="6"></td>
<td><input type="text" class="val2"></td>
</tr>
</table>
Simply reduces the operation to one line. Also ensures that if the User enters a Letter; it won't fail.
I'm trying to apply a function to input field with ids that contain consequent numbers (ie. price1, price2, price3), etc.
There's no problem with the first row of field that are defined for a start. But further input fields are dynamically added by a jQuery function and their number is not known in advance.
I hoped it would be an easy loop to apply:
var i=1;
$("#quantity"+i).keyup(function() {
var price= $("#price"+i).val();
var quantity= $(this).val();
var value= price*quantity;
var value=value.toFixed(2); /* rounding the value to two digits after period */
value=value.toString().replace(/\./g, ',') /* converting periods to commas */
$("#value"+i).val(value);
});
So far so good - the outcome of the multiplication properly displays in the id="value1" field after the "quantity" field is filled up.
Now further fields should follow the pattern and calculate the value when the quantity is entered - like this:
[price2] * [quantity2] = [value2]
[price3] * [quantity3] = [value3]
etc.
So the code follows:
$('#add_field').click(function(){ /* do the math after another row of fields is added */
var allfields=$('[id^="quantity"]');
var limit=(allfields.length); /* count all fields where id starts with "quantity" - for the loop */
for (var count = 2; count < limit; count++) { /* starting value is now 2 */
$("#quantity"+count).keyup(function() {
var cena = $("#price"+count).val();
var quantity= $("#quantity"+count).val();
var value= price*quantity;
var value=value.toFixed(2);
value=value.toString().replace(/\./g, ',')
$("#value"+count).val(value);
});
}
});
The problem is that all further "value" fields are only calculated when "quantity2" is (re)entered and the "value2" is not calculated at all.
I guess there's a mistake while addressing fields and/or triggering the calculation.
How should I correct the code?
Just in case the "add_field" function is needed to solve the problem:
$(document).ready(function(){
var i=1;
$('#add_field').click(function(){
i++;
$('#offer').append('<tr id="row'+i+'">
<td><input type="text" name="prod_num[]" id="prod_num'+i+'" placeholder="Product number (6 digits)"></td><td><input type="text" name="prod_name[]" disabled></td>
<td><input type="text" name="cena[]" id="price'+i+'" placeholder="Enter your price"></td>
<td><input type="text" name="quantity[]" id="quantity'+i+'" placeholder="Enter quantity"></td>
<td><input type="text" name="value[]" id="value'+i+'" disabled></td>
<td><button type="button" name="remove_field" id="'+i+'" class="button_remove">X</button></td></tr>');
});
Incrementing IDs is a lot more trouble than it is worth, especially when you start removing rows as well as adding them.
This can all be done using common classes and traversing within the specific row instance.
To account for future rows use event delegation.
Simplified example:
// store a row copy on page load
const $storedRow = $('#myTable tr').first().clone()
// delegate event listener to permanent ancestor
$('#myTable').on('input', '.qty, .price', function(){
const $row = $(this).closest('tr'),
price = $row.find('.price').val(),
qty = $row.find('.qty').val();
$row.find('.total').val(price*qty)
});
$('button').click(function(){
// insert a copy of the stored row
// delegated events will work seamlessly on new rows also
const $newRow = $storedRow.clone();
const prodName = 'Product XYZ';// get real value from user input
$newRow.find('.prod-name').text(prodName)//
$('#myTable').append($newRow)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Add row</button>
<table id="myTable">
<tr>
<td class="prod-name">Product 1</td>
<td>Qty:<input type="number" class="qty" value="0"></td>
<td>Price:<input type="number" class="price" value="0"></td>
<td>Total:<input type="text" class="total" value="0" readonly></td>
</tr>
<tr>
<td class="prod-name">Product 2</td>
<td>Qty:<input type="number" class="qty" value="0"></td>
<td>Price:<input type="number" class="price" value="0"></td>
<td>Total:<input type="text" class="total" value="0" readonly></td>
</tr>
</table>
Understanding Event Delegation
The first thing to consider is that you can get the length of a selector. So for example:
var count = $("input").length;
If there is one, value here would be 1. if there are four, the value would be 4.
You can also use .each() option to itereate each of the items in the selector.
$('#add_field').click(function(){
var allFields = $('[id^="quantity"]');
allFields.each(function(i, el){
var c = i + 1;
$(el).keyup(function() {
var price = parseFloat($("#price" + c).val());
var quantity = parseInt($(el).val());
var value = price * quantity;
value = value.toFixed(2);
value = value.toString().replace(/\./g, ',');
$("#value" + c).val(value);
});
});
});
You could also create relationship based on the ID itself.
$(function() {
function calcTotal(price, qnty) {
return (parseFloat(price) * parseInt(qnty)).toFixed(2);
}
$('#add_field').click(function() {
var rowClone = $("#row-1").clone(true);
var c = $("tbody tr[id^='row']").length + 1;
rowClone.attr("id", "row-" + c);
$("input:eq(0)", rowClone).val("").attr("id", "prod_num-" + c);
$("input:eq(1)", rowClone).val("").attr("id", "price-" + c);
$("input:eq(2)", rowClone).val("").attr("id", "quantity-" + c);
$("input:eq(3)", rowClone).val("").attr("id", "value-" + c);
$("button", rowClone).attr("id", "remove-" + c);
rowClone.appendTo("table tbody");
});
$("table tbody").on("keyup", "[id^='quantity']", function(e) {
var $self = $(this);
var id = $self.attr("id").substr(-1);
if ($("#price-" + id).val() != "" && $self.val() != "") {
$("#value-" + id).val(calcTotal($("#price-" + id).val(), $self.val()));
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="add_field">Add Field</button>
<br />
<h2>Product</h2>
<table>
<thead>
<tr>
<td>Number</td>
<td>Name</td>
<td>Price</td>
<td>Quantity</td>
<td>Total</td>
<td></td>
</thead>
<tbody>
<tr id="row-1">
<td><input type="text" name="prod_num[]" id="prod_num-1" placeholder="Product number (6 digits)"></td>
<td><input type="text" name="prod_name[]" disabled></td>
<td><input type="text" name="cena[]" id="price-1" placeholder="Enter your price"></td>
<td><input type="text" name="quantity[]" id="quantity-1" placeholder="Enter quantity"></td>
<td><input type="text" name="value[]" id="value-1" disabled></td>
<td><button type="button" name="remove_field" id="remove-1" class="button_remove">X</button></td>
</tr>
</tbody>
</table>
I have a table which is created by a forEach loop (loop through a database). what I'm trying to do is to calculate the price by multiplying qty x rate in each row.
I have a JavaScript function(boqMath) to do this, but it only works for the first row(first loop). How can I change it to do this math for every rows(all loops)?
table:
<% user.myrates.forEach(function(myrates){ %>
<tr>
<td><input type='text' class='form-control' value = "<%= myrates.boqUnit %>"></td>
<td><input type='text' class='form-control qty' oninput = "boqMath()"></td>
<td><div class="input-icon"><i>$</i><input type='text' class='form-control rate' oninput="boqMath()" value="<%= myrates.boqRate %>"></div></td>
<td><div class="input-icon"><i>$</i><input type='text' class='form-control price' oninput="boqMath()"></div></td>
<td><button type="submit" name="submit" class="btn btn-primary">Add</button></td>
</tr>
<% }); %>
and this the function:
function boqMath(){
var a = document.querySelector('.qty').value;
var b = document.querySelector('.rate').value;
var price = document.querySelector('.price');
price.value = (Number(a) * Number(b)).toLocaleString();
}
Pass the current element to boqMath(). From this you can find the closest tr, and get the inputs in that row.
function boqMath(element) {
row = element.closest("tr");
var qty = row.querySelector(".qty").value;
var rate = row.querySelector(".rate").value;
var price = row.querySelector(".price");
price.value = (qty * rate).toLocaleString();
}
Change oninput = "boqMath()"> to oninput="boqMath(this)"
My Java Script Code
<script>
$(function(){
$('#addRow').click(function(){
var html = $('#row_template').html();
$('#dataTable').append(html);
$(".tablerow").each(function(index) {
$(this).html(index + 1);
});
});
$('#deleteRow').click(function(){
$('#dataTable .mychkbox:checked').parents('tr').remove();
});
$('#dataTable').on('change','.select-desc',function(){
var cur_val = $(this).val();
$(this).parents('tr').find('input[name="rate[]"]').val(cur_val);
});
$('#dataTable').on('keyup','input[name="qty[]"]', function(){
var qty = +$(this).val();
var unit = +$(this).parents('tr').find('input[name="rate[]"]').val();
$(this).parents('tr').find('input[name="amt[]"]').val(qty*unit);
var totamt = 0 ;
var theTbl = document.getElementById('dataTable');
for(var i=0;i<theTbl.length;i++)
{
for(var j=0;j<theTbl.rows[i].cells.length;j++)
{
totamt = totamt + theTbl.rows[i].cells[4].InnerHTML;
}
}
});
});
</script>
My HTML Code is
<!DOCTYPE html>
<html>
<div class="left">
<h2><span class="orange">Work Order Items</span></h2>
<table>
<tr>
<td><input type="button" value="Add Row" id="addRow" /></td>
<td><input type="button" value="Remove Row" id="deleteRow" /></td>
</tr>
</table>
</div>
<table id="dataTable" class="form" border="0" width='100%'>
<tr>
<td></td>
<td>No</td>
<td>Item Description</label></td>
<td>Qty</td>
<td>Rate</td>
<td>Amount</td>
<td>Cert No</td>
<td>C Date</td>
</tr>
</table>
<table id="row_template" style="display:none">
<tr>
<td><input type="checkbox" name="chk[]" class="mychkbox" /></td>
<td class="tablerow"></td>
<td>
<?php
$sql = "SELECT itrate,CONCAT(itname,'|',itcode) as mname FROM ITMAST ";
$result = mysql_query($sql) or die(mysql_error());
echo "<select name='itname[]' id='itname' class='select-desc' >";
echo "<option value=''>-- Select Item --</option>";
while ($row = mysql_fetch_array($result))
{
echo "<option value = '{$row['itrate']}'";
if ($pitcode == $row['itrate'])
echo "selected = 'selected'";
echo ">{$row['mname']}</option>";
}
echo "</select>";
?>
</td>
<td><input type="text" name="qty[]" id="qty" size="6" class='rightJustified'></td>
<td><input type="text" name="rate[]" id="rate" size="8" class='rightJustified' readonly></td>
<td><input type="text" name="amt[]" id="amt" size="9" class='rightJustified' readonly></td>
<td><input type="text" maxlength="10" size="8" name="txtcertno[]"></td>
<td><input type="date" maxlength="10" size="10" name="txtcdate[]"></td>
</tr>
</table>
</html>
I am trying to take total of amount column i.e. amt[] after each entry of a row, but I am not getting it properly, I have written Javascript function for the same but some thing may be wrong in it
I did not correct all of your mistakes,
You should check #Samurai answer for more details (such as use of the 'id' and other things)
Main problem was, as I said in comment, use of innerHTML which returned "
another thing, your theTbl var was not good, you could never call .length on it. To solve that, you had to handle it this way :
var totamt = 0 ;
var theTbl = $('#dataTable');
//You are using jquery, so use jquery selectors...
var trs = theTbl.find("input[name='amt[]']");
//find there the AMT[] INPUTS, not the rows...
console.log("how many amt inputs? : "+trs.length);
for(var i=0;i<trs.length;i++)
{
//fetch the inputs, and make your calculations here
console.log("amount from row "+i+" = "+trs[i].value);
//do not forget, as Samurai said, to convert html to numeric...
$("#total").html(totamt+=parseFloat(trs[i].value));
}
Here is a working solution :
http://jsfiddle.net/nxm0ye54/20/
First to point out a few mistakes:
$('#row_template').html(): browsers automatically add tbody to the table, so you end up having multiple tbody in your main table which of course won't cause any problem on its own, if that's the desired output.
You're misusing ID. Each tr has multiple td with inputs that share the same ID. Instead you should use class.
To calculate the total amount you're getting the innerHTML of the cells which don't hold a number, but an input element. Instead you want the value these input elements are holding.
You need to convert the values to numbers before doing math on them, otherwise it will assume they're string and just put them beside each other. (e.g. 0+1+2 = 012 and not 3). You should use parseInt or parseFlout which the latter suits this case better.
A few modifications to your code:
$('#addRow').click(function () {
var html = $('#row_template tbody').html();
$('#dataTable tbody').append(html);
And - since you're using jQuery - I completely changed the calculation to a jQuery version:
//gt(0) cause the first row contains headers
//eq(5) cause we want the 6th cell (Amount)
var totamt = 0;
$('#dataTable tr:gt(0)').each(function() {
var newAmt = $(this).find('td:eq(5) input[type=text]').val();
totamt += parseFloat(newAmt);
});
input fields are created via jquery depend on user input
If user type Quantity : 5 then i m created 5 input fields
for example if user give Quantity = 3 then this is how the html created dynamically using Jquery
<tr id = "tr_1">
<td><input type="text" name="cont_no1" id="cont_no1" /><td>
<td><input type="text" name="cont_size1" id="cont_size1" /><td>
<td><input type="text" name="cont_type1" id="cont_type1" /><td>
</tr>
<tr id = "tr_2">
<td><input type="text" name="cont_no2" id="cont_no1" /><td>
<td><input type="text" name="cont_size2" id="cont_size2" /><td>
<td><input type="text" name="cont_type2" id="cont_type2" /><td>
</tr>
<tr id = "tr_3">
<td><input type="text" name="cont_no3" id="cont_no3" /><td>
<td><input type="text" name="cont_size3" id="cont_size3" /><td>
<td><input type="text" name="cont_type3" id="cont_type3" /><td>
</tr>
now i need to store all this input fields values in json.
var jsonObj= jsonObj || [];
for(var i=1; i<cont_qty; i++)
{
item = {};
item ["cont_no"] = $('#cont_no'+i).val();
item ["cont_size"] = $('#cont_size'+i).val();
item ["cont_type"] = $('#cont_type'+i).val();
jsonObj.push(item);
}
i tried like this but its not working the please someone help me. ThankYou
for your refrence here is full code, var auto_tr value is aligned here(with enter) for your purpose .
$(document).ready(function(){
$( "#cont_qty" ).change(function()
{
var itemCount = 0;
$("#munna").empty();
var cont_qty = this.value;
for(var i=0 ; cont_qty>i; i++)
{
itemCount++;
// dynamically create rows in the table
var auto_tr = '<tr id="tr'+itemCount+'">
<td>
<input class="input-medium" type="text" id="cont_no'+itemCount+'" name="cont_no'+itemCount+'" value="">
</td>
<td>
<select class="input-mini" name="cont_size'+itemCount+'" id="cont_size'+itemCount+'">
<option>20</option>
<option>40</option>
<option>45</option>
</select>
</td>
<td>
<select class="input-mini" name="cont_type'+itemCount+'" id="cont_type'+itemCount+'">
<option>DV</option>
<option>HD</option>
<option>HC</option>
<option>OT</option>
<option>FR</option>
<option>HT</option>
<option>RF</option>
</select>
</td>
<td>
<select class="input-medium" name="cont_tonnage'+itemCount+'" id="cont_tonnage'+itemCount+'">
<option>24000 Kgs</option>
<option>27000 Kgs</option>
<option>30480 Kgs</option>
<option>Super Heavy Duty</option>
</select>
</td>
<td>
<input class="input-medium" type="text" id="cont_tare'+itemCount+'" name="cont_tare'+itemCount+'" value="">
</td>
<td>
<input class="input-medium" name="cont_netweight'+itemCount+'" id="cont_netweight'+itemCount+'" type="text" value="">
</td>
<td>
<input class="input-mini" name="yom'+itemCount+'" id="yom'+itemCount+'" type="text" value=""></td>
<td>
<select class="input-medium" name="cont_condition'+itemCount+'" id="cont_condition'+itemCount+'">
<option>IICL</option>
<option>ASIS</option>
<option>CARGO WORTHY</option>
</select>
</td>
</tr>';
$("#munna").append(auto_tr);
}
});
$("#getButtonValue").click(function ()
{
var jsonObj= jsonObj || [];
for(var i=1; i<cont_qty.value; i++)
{
item = {};
item ["cont_no"] = $('#cont_no'+i).val();
item ["cont_size"] = $('#cont_size'+i).val();
item ["cont_type"] = $('#cont_type'+i).val();
jsonObj.push(item);
}
alert(jsonObj[0].cont_no[1]);
});
});
did small loop mistake :)
for(var i=1; i<=cont_qty.value; i++)
{
alert(cont_qty.value);
item = {};
item ["cont_no"] = $('#cont_no'+i).val();
item ["cont_size"] = $('#cont_size'+i).val();
item ["cont_type"] = $('#cont_type'+i).val();
jsonObj.push(item);
}
in previous one i<cont_qty.value this one used now just changed as i<=cont_qty.value
so the loop ran 3 times when qty is 4. now just added <=
ThankYou for your answers friends
Make sure you call your function after you created the html via jquery.
createHtml(); // function to create the html
storeValuesToArray(); // Your function to store data to array
Also make sure you properly close your tags <tr></tr>. And put <tr> inside a <table> tag.
And make sure your cont_qty is set to a value
After you created the html and added all the fields necessary, you can catch all elements by using a selector like:
var jsonObj= jsonObj || [];
$('[name^="cont_no"]').each(function(){
var i = this.name.split('cont_no')[1];
var item = {};
item['cont_no'] = $(this).val();
item['cont_size'] = $('[name="cont_size'+i+'"]').val();
item['cont_type'] = $('[name="cont_type'+i+'"]').val();
jsonObj.push(item);
});