form, which is fetching service name in <td>Name</td> and jQuery below is appending sub total as quantity increases with respect to price.
$(document).on('change', '.qty', function() {
var quantity = $(this).val();
var sub = $(this).parent().next().children();
var price = $(this).parent().prev().children().val();
var subTotal = parseInt(quantity) * parseInt(price);
sub.val(subTotal);
});
var i = 1;
$(function() {
$("#btnAdd").bind("click", function() {
var div = $("<tr />");
div.html(GetDynamicTextBox(""));
$("#TextBoxContainer").append(div);
});
$("body").on("click", ".remove", function() {
$(this).closest("tr").remove();
// GrandTotal();
});
});
function GetDynamicTextBox(value) {
i++;
return '<td><select class="form-control select2 select-service" style="width: 100%;" id="service-select' + i + '" required name="product[]"><option value="">--Select Product--</option> <?php foreach($dbf->fetchOrder("service") as $services){?><option value="<?= $services['
id '];?>"><?= $services['
service '];?></option><?php }?></select></td>' +
'<td><input class="form-control rate" name = "rate[]" type="text" placeholder="Rate" id="rate1' + i + '" required readonly/></td>' +
'<td><input class="form-control qty" placeholder="Quantity" name = "qty[]" type="number" id="qty1' + i + '" /></td>' +
'<td><input class="form-control sub-total" placeholder="Sub Total" name = "sub_total[]" type="text" id="sub_total1' + i + '" readonly required/></td>' +
'<td><button type="button" class="btn btn-danger remove"><i class="glyphicon glyphicon-remove-sign"></i></button></td>'
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-responsive table-striped table-bordered">
<thead>
<tr>
<td>Name</td>
<td>Price</td>
<td>Quantity</td>
<td>Sub Total</td>
<td><button id="btnAdd" type="button" class="btn btn-primary" data-toggle="tooltip" data-original-title="Add more controls"><i class="glyphicon glyphicon-plus-sign"></i> Add </button></td>
</tr>
</thead>
<tbody id="TextBoxContainer">
<tr>
<td>
<select class="form-control select-service" style="width: 100%;" id="service-select" required name="service[]">
<option value="">--Select Services--</option>
<?php foreach($dbf->fetchOrder("service") as $services){?>
<option value="<?= $services['id'];?>">
<?= $services['service'];?>
</option>
<?php }?>
</select>
</td>
<td><input type="text" class="form-control rate" placeholder="Rate" readonly name="rate[]" id="rate1" required></td>
<td><input type="number" min="1" class="form-control qty" placeholder="Quantity" name="qty[]" id="qty1"></td>
<td><input type="text" min="1" class="form-control sub_total" placeholder="Sub Total" name="sub_total[]" readonly id="sub_total1"></td>
<td><button type="button" class="btn btn-danger remove"><i class="glyphicon glyphicon-remove-sign"></i></button></td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
this is the multiple dynamic input field of the same form above, which is adding Name,Price,Quantity,Sub Total dynamic field as add button is clicked.
My goal is to add all the sub-total from the multiple dynamic field and display it inside a different field.
You can use each loop to iterate through all inputs i.e : sub_total then get value of input and add it to some variable on each iteration and finally append it to some element.
Demo Code :
$(document).on('change', '.qty', function() {
var quantity = $(this).val();
var sub = $(this).parent().next().children();
var price = $(this).parent().prev().children().val()
var subTotal = parseInt(quantity) * parseInt(price);
sub.val(subTotal);
calculate_total(); //call to calculate
});
var i = 1;
$(function() {
$("#btnAdd").bind("click", function() {
var div = $("<tr />");
div.html(GetDynamicTextBox(""));
$("#TextBoxContainer").append(div);
});
$("body").on("click", ".remove", function() {
$(this).closest("tr").remove();
calculate_total(); //call to calculate
});
});
function GetDynamicTextBox(value) {
i++;
return '<td><select class="form-control select2 select-service" style="width: 100%;" id="service-select' + i + '" required name="product[]"><option value="">--Select Product--</option></select></td>' + '<td><input class="form-control rate" value="10" name = "rate[]" type="text" placeholder="Rate" id="rate1' + i + '" required readonly/></td>' + '<td><input class="form-control qty" placeholder="Quantity" name = "qty[]" type="number" id="qty1' + i + '" /></td>' + '<td><input class="form-control sub_total" placeholder="Sub Total" name = "sub_total[]" type="text" id="sub_total1' + i + '" readonly required/></td>' + '<td><button type="button" class="btn btn-danger remove"><i class="glyphicon glyphicon-remove-sign">x</i></button></td>'
}
function calculate_total() {
var total = 0;
//loop through all inputs(sub-total)
$("input.sub_total").each(function() {
//check if value is not null
total += ($(this).val() != "") ? parseInt($(this).val()) : 0;
})
//add total
$("#total").text(total)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-responsive table-striped table-bordered">
<thead>
<tr>
<td>Name</td>
<td>Price</td>
<td>Quantity</td>
<td>Sub Total</td>
<td><button id="btnAdd" type="button" class="btn btn-primary" data-toggle="tooltip" data-original-title="Add more controls"><i class="glyphicon glyphicon-plus-sign"></i> Add </button></td>
</tr>
</thead>
<tbody id="TextBoxContainer">
<tr>
<td>
<select class="form-control select-service" style="width: 100%;" id="service-select" required name="service[]">
<option value="">--Select Services--</option>
<option value="1">1 </option>
<option value="2">2 </option>
<option value="3">3 </option>
</select>
</td>
<td><input type="text" class="form-control rate" placeholder="Rate" readonly name="rate[]" value="10" id="rate1" required></td>
<td><input type="number" min="1" class="form-control qty" placeholder="Quantity" name="qty[]" id="qty1"></td>
<td><input type="text" min="1" class="form-control sub_total" placeholder="Sub Total" name="sub_total[]" readonly id="sub_total1"></td>
<td><button type="button" class="btn btn-danger remove"><i class="glyphicon glyphicon-remove-sign">x</i></button></td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="3">Total : </th>
<th id="total">0</th>
</tr>
</tfoot>
</table>
Related
I have multiple buttons that need to be activated at the same time. When each button is click from the input it returns what is type. The problem is I need all the buttons to be fire off at the same time. When I have a separate button fire off theses buttons though I get undefined and not the input.
$(document).on("click", "#devSaveBtn", function () {
if (
$("#primaryBtn").trigger("click") &&
$("#secondaryBtn").trigger("click") &&
$("#thirdBtn").trigger("click")
) {
var getInput = $(this)
.closest("td")
.find("input[name='Object Name']")
.val();
console.log("Input = " + getInput);
var getInput2 = $(this)
.closest("td")
.find("input[name='Project Name']")
.val();
console.log("Input2 = " + getInput2);
var getInput3 = $(this)
.closest("td")
.find("input[name='Description']")
.val();
console.log("Input3 = " + getInput3);
} else {
console.log("This is not working");
}
});
<button type="button" input type="submit" id="devSaveBtn" class="devbutton devinithidden readonlyhidden" title="Reset Changes" style="visibility: visible; background-color: #f4d8b4;"><i class="fa fa-save"></i>
Save</button>
<td class="noncomponentswidth" id="recordObjName">
<p>
<input type="text" id="OBJ_NAME" name="Object Name" placeholder="" required minlength="8">
<button id="primaryBtn">Primary</button>
</p>
<button style="display: none;">Submit</button>
</td>
<td class="noncomponentswidth" id="recordProjectName">
<input type="text" id="DEPLOYER_PROJECT" name="Project Name" placeholder="">
<button id="secondaryBtn">Secondary</button>
</td>
<td class="noncomponentswidth" id="recordDeployerCandidate" placeholder="">
<input type="text" id="DESCRIPTION" name="Description" placeholder="" style="resize: vertical; width: 40em; height: 85px;">
<button id="thirdBtn">Third</button>
</td>
$(document).on("click", "#devSaveBtn", function () {
var getInput = $("input");
for (var i = 0; i < getInput.length; i++)
console.log(getInput[i].id, " => Input", i, " = ", getInput[i].value);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.js" integrity="sha512-CX7sDOp7UTAq+i1FYIlf9Uo27x4os+kGeoT7rgwvY+4dmjqV0IuE/Bl5hVsjnQPQiTOhAX1O2r2j5bjsFBvv/A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<button type="button" input type="submit" id="devSaveBtn" class="devbutton devinithidden readonlyhidden" title="Reset Changes" style="visibility: visible; background-color: #f4d8b4;"><i class="fa fa-save"></i>
Save</button>
<td class="noncomponentswidth" id="recordObjName">
<p>
<input type="text" id="OBJ_NAME" name="Object Name" placeholder="" required minlength="8">
</p>
</td>
<td class="noncomponentswidth" id="recordProjectName">
<input type="text" id="DEPLOYER_PROJECT" name="Project Name" placeholder="">
</td>
<td class="noncomponentswidth" id="recordDeployerCandidate" placeholder="">
<input type="text" id="DESCRIPTION" name="Description" placeholder="" style="resize: vertical; width: 40em; height: 85px;">
</td>
I use jQuery to create a table with CRUD operations. I give the table the ability to sort and filter data. The sort and filter functions work perfectly as well as all CRUD actions.
I have to store the table's data in local storage. Because of this, I add some codes. It functions and stores the data locally not properly. I need to store properly in array format. I need your assistance to address this issue.
<!DOCTYPE html>
<html lang="en">
<head>
<title>CRUD Table jQuery</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-4 col-xs-offset-8">
<input id="searchfield" type="search" class="form-control" placeholder="Search...">
</div>
<div class="col-md-12 text-right">
<input type="button" id="btnAdd" class="btn btn-primary para" value="Add New" />
</div>
</div>
<div class="row pt-3">
<div class="col-md-12 col-sm-12 col-12 p-2 ">
<table id="tblData" class="table table-bordered table-hover table-striped">
<thead>
<tr id="headings">
<th class="num">ID</th>
<th class="text">Name</th>
<th class="text">Address</th>
<th class="num">Age</th>
<th class="tdaction">Action</th>
</tr>
</thead>
<tbody id="searchable">
</tbody>
</table>
</div>
</div>
</div>
<script>
var emptyNewRow = "<tr class='trNewRow'>";
emptyNewRow = emptyNewRow + "<td class='tdID'><input type='text' class='form-control txtID' /></td>";
emptyNewRow = emptyNewRow + "<td class='tdName'><input type='text' class='form-control txtName' /></td>";
emptyNewRow = emptyNewRow + "<td class='tdAddress'><input type='text' class='form-control txtAddress' /></td>";
emptyNewRow = emptyNewRow + "<td class='tdAge'><input type='text' class='form-control txtAge' /></td>";
emptyNewRow = emptyNewRow + "<td class='tdAction'><button class='btn btn-sm btn-success btn-save'> Save</button><button class='btn btn-sm btn-success btn-cancel'> Cancel</button></td>";
emptyNewRow = emptyNewRow + "</tr>";
var rowButtons ="<button class='btn btn-success btn-sm btn-edit' > Edit </button> <button class='btn btn-danger btn-sm' > Delete </button>";
var rowUpdateButtons ="<button class='btn btn-success btn-sm btn-save' > Update </button> <button class='btn btn-danger btn-sm btn-save' > Delete </button> ";
$(document).ready(function () {
$("#btnAdd").click(function () {
$("#tblData tbody").append(emptyNewRow);
});
$('#tblData').on('click', '.btn-save', function () {
const id = $(this).parent().parent().find(".txtID").val();
$(this).parent().parent().find(".tdID").html(""+id+"");
const name = $(this).parent().parent().find(".txtName").val();
$(this).parent().parent().find(".tdName").html(""+name+"");
const address = $(this).parent().parent().find(".txtAddress").val();
$(this).parent().parent().find(".tdAddress").html(""+address+"");
const age = $(this).parent().parent().find(".txtAge").val();
$(this).parent().parent().find(".tdAge").html(""+age+"");
$(this).parent().parent().find(".tdAction").html(rowButtons);
//local storage
let arr = JSON.parse(localStorage.getItem('Data'));
if(arr==null){
let data = ["ID " + id,"NAME "+name,"ADDRESS "+address,"AGE "+ age];
localStorage.setItem('Data', JSON.stringify(data));
}else{
arr.push(id,name,address,age);
localStorage.setItem('Data', JSON.stringify(arr));
}
});
$('#tblData').on('click', '.btn-danger', function () {
$(this).parent().parent().remove();
});
$('#tblData').on('click', '.btn-cancel', function () {
$(this).parent().parent().remove();
});
$('#tblData').on('click', '.btn-edit', function () {
const id =$(this).parent().parent().find(".tdID").html();
$(this).parent().parent().find(".tdID").html("<input type='text' value='"+id+"' class='form-control txtID' />");
const name =$(this).parent().parent().find(".tdName").html();
$(this).parent().parent().find(".tdName").html("<input type='text' value='"+name+"' class='form-control txtName' />");
const address =$(this).parent().parent().find(".tdAddress").html();
$(this).parent().parent().find(".tdAddress").html("<input type='text' value='"+address+"' class='form-control txtAddress' />");
const age =$(this).parent().parent().find(".tdAge").html();
$(this).parent().parent().find(".tdAge").html("<input type='text' value='"+age+"' class='form-control txtAge' />");
$(this).parent().parent().find(".tdAction").html(rowUpdateButtons);
});
//filtering
$("#searchfield").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#searchable tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
//sorting
$('th').each(function (col) {
$(this).data("type", $(this).attr("class"));
$(this).click(function () {
var type = $(this).data("type");
var records = $("table").find("tbody > tr");
records.sort(function(x,y){
var val1 = $(x).children("td").eq(col).text();
var val2 = $(y).children("td").eq(col).text();
if (type == "num")
{
val1 *= 1;
val2 *= 1;
}
return (val1 < val2) ? -1 : (val1 > val2 ? 1 :0)
});
$.each(records, function(index, row){
$("tbody").append(row);
});
});
});
});
</script>
</body>
</html>
If you need to serialize the whole table content updating the value you have previously saved, you had the option to keep track of changed rows and update only that part of the state. But it would require lots of efforts compared to saving the whole table from scratch and replacing its previously serialized state with the new one.
I focused here on that task only: how to serialize your table in a structured manner, dumping each row as an object having key-values pair as tdClassName-inputValue.
I extrapolated the table you have in your snippet and populated it with some sample data. Then I added a new button that triggers the logic to dump its content inside a variable that will be returned by the dumpTable() function.
When you click the button, it will print on console the object containing the table saved state. You can copy that logic in your code so that you'll call that function one moment before replacing the json data in the storage.
function dumpClickHandler() {
const dataTable = dumpTable();
console.log(dataTable);
}
function dumpTable() {
const dataTable = [];
//fetch table rows and iterate through all of them
const rows = document.querySelectorAll('#tblData tbody tr');
for (const row of rows) {
const dataRow = {};
//fetch row fields
const fields = row.querySelectorAll('td');
//for each field in row
for (const field of fields) {
//skip the action field containing buttons
if (field.classList.contains('tdAction'))
continue;
//fetch field name using the class assigned to the table cell
const fieldName =
Object.values(field.classList).filter(className => className.startsWith("td"))?.[0];
//fetch field value
dataRow[fieldName] = field.querySelector('input')?.value;
}
//push the fetched row in the array
dataTable.push(dataRow);
}
return dataTable;
}
h1{
margin: 2rem 0 2rem 0 !important;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<div class="container col-10">
<h1>Table filled with sample data:</h1>
<table id="tblData" class="table table-bordered table-hover table-striped">
<thead>
<tr id="headings">
<th class="num">ID</th>
<th class="text">Name</th>
<th class="text">Address</th>
<th class="num">Age</th>
<th class="tdaction">Action</th>
</tr>
</thead>
<tbody id="searchable">
<tr class="trNewRow">
<td class="tdID">
<input type="text" class="form-control txtID" value="1">
</td>
<td class="tdName">
<input type="text" class="form-control txtName" value="Name1">
</td>
<td class="tdAddress">
<input type="text" class="form-control txtAddress" value="Address1">
</td>
<td class="tdAge">
<input type="text" class="form-control txtAge" value="10">
</td>
<td class="tdAction">
<button class="btn btn-sm btn-success btn-save">Save</button>
<button class="btn btn-sm btn-success btn-cancel">Cancel</button>
</td>
</tr>
<tr class="trNewRow">
<td class="tdID">
<input type="text" class="form-control txtID" value="2">
</td>
<td class="tdName">
<input type="text" class="form-control txtName" value="Name2">
</td>
<td class="tdAddress">
<input type="text" class="form-control txtAddress" value="Address2">
</td>
<td class="tdAge">
<input type="text" class="form-control txtAge" value="20">
</td>
<td class="tdAction">
<button class="btn btn-sm btn-success btn-save"> Save</button>
<button class="btn btn-sm btn-success btn-cancel"> Cancel</button>
</td>
</tr>
</tbody>
</table>
<button type="button" class="btn btn-primary" onclick="dumpClickHandler();">DUMP TABLE CONTENT</button>
</div>
I'm working on dynamic 3 column table that has 3 input text type : Product, quantity and date
This works good but i want to change type format:
Product column => Dropdown type
Quantity column => number type
Date column => Date type (dd-mm-yyyy)
How i do change it?
Thank you
Original source: link
Code online: https://jsfiddle.net/bvotcode/r61ptxe9/7/
HTML
<body>
<div id="wrapper">
<table align='center' cellspacing=2 cellpadding=5 id="data_table" border=1>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Date</th>
</tr>
<tr id="row1">
<td id="product_row1">Car</td>
<td id="quantity_row1">10</td>
<td id="date_row1">20/12/2021</td>
<td>
<input type="button" id="edit_button1" value="Edit" class="edit" onclick="edit_row('1')">
<input type="button" id="save_button1" value="Save" class="save" onclick="save_row('1')">
<input type="button" value="Delete" class="delete" onclick="delete_row('1')">
</td>
</tr>
<tr id="row2">
<td id="product_row2">Book</td>
<td id="quantity_row2">22</td>
<td id="date_row2">26</td>
<td>
<input type="button" id="edit_button2" value="Edit" class="edit" onclick="edit_row('2')">
<input type="button" id="save_button2" value="Save" class="save" onclick="save_row('2')">
<input type="button" value="Delete" class="delete" onclick="delete_row('2')">
</td>
</tr>
<tr id="row3">
<td id="product_row3">Laptop</td>
<td id="quantity_row3">44</td>
<td id="date_row3">19/01/2022</td>
<td>
<input type="button" id="edit_button3" value="Edit" class="edit" onclick="edit_row('3')">
<input type="button" id="save_button3" value="Save" class="save" onclick="save_row('3')">
<input type="button" value="Delete" class="delete" onclick="delete_row('3')">
</td>
</tr>
<tr>
<td><input type="text" id="new_product"></td>
<td><input type="text" id="new_quantity"></td>
<td><input type="text" id="new_date"></td>
<td><input type="button" class="add" onclick="add_row();" value="Add Row"></td>
</tr>
</table>
</div>
</body>
</html>
</body>
CSS
.pt-3-half { padding-top: 1.4rem; }
Javascript
function edit_row(no)
{
document.getElementById("edit_button"+no).style.display="none";
document.getElementById("save_button"+no).style.display="block";
var product=document.getElementById("product_row"+no);
var quantity=document.getElementById("quantity_row"+no);
var date=document.getElementById("date_row"+no);
var product_data=product.innerHTML;
var quantity_data=quantity.innerHTML;
var date_data=date.innerHTML;
product.innerHTML="<input type='text' id='product_text"+no+"' value='"+product_data+"'>";
quantity.innerHTML="<input type='text' id='quantity_text"+no+"' value='"+quantity_data+"'>";
date.innerHTML="<input type='text' id='date_text"+no+"' value='"+date_data+"'>";
}
function save_row(no)
{
var product_val=document.getElementById("product_text"+no).value;
var quantity_val=document.getElementById("quantity_text"+no).value;
var date_val=document.getElementById("date_text"+no).value;
document.getElementById("product_row"+no).innerHTML=product_val;
document.getElementById("quantity_row"+no).innerHTML=quantity_val;
document.getElementById("date_row"+no).innerHTML=date_val;
document.getElementById("edit_button"+no).style.display="block";
document.getElementById("save_button"+no).style.display="none";
}
function delete_row(no)
{
document.getElementById("row"+no+"").outerHTML="";
}
function add_row()
{
var new_product=document.getElementById("new_product").value;
var new_quantity=document.getElementById("new_quantity").value;
var new_date=document.getElementById("new_date").value;
var table=document.getElementById("data_table");
var table_len=(table.rows.length)-1;
var row = table.insertRow(table_len).outerHTML="<tr id='row"+table_len+"'><td id='product_row"+table_len+"'>"+new_product+"</td><td id='quantity_row"+table_len+"'>"+new_quantity+"</td><td id='date_row"+table_len+"'>"+new_date+"</td><td><input type='button' id='edit_button"+table_len+"' value='Edit' class='edit' onclick='edit_row("+table_len+")'> <input type='button' id='save_button"+table_len+"' value='Save' class='save' onclick='save_row("+table_len+")'> <input type='button' value='Delete' class='delete' onclick='delete_row("+table_len+")'></td></tr>";
document.getElementById("new_product").value="";
document.getElementById("new_quantity").value="";
document.getElementById("new_date").value="";
}
You're using the type="text" for all of the <input> tags. You should consider changing the type of the inputs in your edit_row function.
For numbers, the type of input should be number;
For dates, date;
And finally, to render a dropdown box, the best solution is to use a <select> tag instead of an <input>. Don't forget to write all the options of your dropdown inside of <option> tags (which should be all inside of one <select> tag); Here you can find a simple explanation on how to use the <select> tag.
I want my added dynamic row have the same function with my first row which can remove the comma. My first row works pretty well. The problems is the .replace(/,/g, '') in added row.
When I add .replace(/,/g, '') into my add row function, it shows me Uncaught SyntaxError: Unexpected string.
html += '<td><input class="qty" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, '')));" onkeyup="onlyDecimal(this)"></td>';
html += '<td><input class="price" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, '')));" onkeyup="onlyDecimal(this)"></td>';
If I change .replace(/,/g, '') to .replace(/,/g, ""), it shows me Uncaught SyntaxError: Unexpected end of input.
html += '<td><input class="qty" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, "")));" onkeyup="onlyDecimal(this)"></td>';
html += '<td><input class="price" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, "")));" onkeyup="onlyDecimal(this)"></td>';
I insert the same amount for row 1 and row 2 but my result for row 2 should same as row 1.
My current result:
Qty | Price
6,000.00 | 1,234,567.00
6.00 | 1.00
My expected result:
Qty | Price
6,000.00 | 1,234,567.00
6,000.00 | 1,234,567.00
function currencyFormat(num) {
if (isNaN(num)) {
return "";
}
return num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
}
function onlyDecimal(ControlId) {
$(ControlId).on('keyup', function(key) {
if (this.value != this.value.replace(/[^0-9\.,]/g, '')) {
this.value = this.value.replace(/[^0-9\.,]/g, '');
}
})
};
$(document).on('click', '#addRow', function(e) {
var html = '';
html += '<tr>'
html += '<td><input class="qty" type="text" onblur="this.value=currencyFormat(parseFloat(this.value));" onkeyup="onlyDecimal(this)"></td>';
html += '<td><input class="price" type="text" onblur="this.value=currencyFormat(parseFloat(this.value));" onkeyup="onlyDecimal(this)"></td>';
html += '</tr>'
$('.table').append(html);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>Qty</td>
<td>Price</td>
</tr>
</thead>
<tbody class="table">
<tr>
<td><input class="qty" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, '')));" onkeyup="onlyDecimal(this)"></td>
<td><input class="price" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, '')));" onkeyup="onlyDecimal(this)"></td>
</tr>
</tbody>
</table>
<a id="addRow" href="javascript:; "><i class="fe fe-plus-circle mr-1"></i>Add</a>
You have to use `` character for your HTML like this:
html += `<td><input class="qty" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, '')));" onkeyup="onlyDecimal(this)"></td>`;
Here is working sample
function currencyFormat(num) {
if (isNaN(num)) {
return "";
}
return num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
}
function onlyDecimal(ControlId) {
$(ControlId).on('keyup', function(key) {
if (this.value != this.value.replace(/[^0-9\.,]/g, '')) {
this.value = this.value.replace(/[^0-9\.,]/g, '');
}
})
};
$(document).on('click', '#addRow', function(e) {
var html = '';
html += '<tr>'
html += `<td><input class="qty" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, '')));" onkeyup="onlyDecimal(this)"></td>`;
html += `<td><input class="price" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, '')));" onkeyup="onlyDecimal(this)"></td>`;
html += '</tr>'
$('.table').append(html);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>Qty</td>
<td>Price</td>
</tr>
</thead>
<tbody class="table">
<tr>
<td><input class="qty" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, '')));" onkeyup="onlyDecimal(this)"></td>
<td><input class="price" type="text" onblur="this.value=currencyFormat(parseFloat(this.value.replace(/,/g, '')));" onkeyup="onlyDecimal(this)"></td>
</tr>
</tbody>
</table>
<a id="addRow" href="javascript:; "><i class="fe fe-plus-circle mr-1"></i>Add</a>
my jquery code doesn't work on dynamically appended elements. It is working fine for the elements that already present there but When I embed a new row using the jQuery append function, then the jquery code no longer works.
Here is the jquery code that embeds a new row
<script>
$(document).ready(function() {
$('#add_row').click(function(){
$('#sale_table').append('<tr><td><select class="form-control" name="item_name[]"><option>Select an Item</option><?php while($item_result = mysqli_fetch_assoc($select_item_query)) { ?><option><?php echo $item_result['item_name']; ?></option><?php } ?></select></td><td><input type="text" class="form-control" name="item_quantity[]" id="sale_item_quantity" placeholder="0.00"></td><td><input type="text" class="form-control" name="item_price[]" id="sale_item_price" placeholder="0.00"></td><td><input type="text" class="form-control" name="item_discount[]" id="sale_item_discount" placeholder="%"></td><td><input type="text" class="form-control" name="item_total_amount[]" id="sale_item_total_amount" placeholder="0.00"></td></tr>');
});
});
</script>
and this is the jquery code that I'm trying to run on appended row. This code doesn't work on appended rows
<script>
$(document).ready(function() {
$('#sale_item_price, #sale_item_quantity').on('keyup', function(){
var sum = 0;
$('.sale-entry > tbody > tr').each(function() {
var qty = $(this).find('#sale_item_quantity').val();
var price = $(this).find('#sale_item_price').val();
var discount = $(this).find('#sale_item_discount').val();
var amount = (qty * price);
if(discount){
amount = amount - discount;
}
$(this).find('#sale_item_total_amount').val(amount);
sum += amount;
});
$('#sale_subtotal_amount').text(sum);
$('#sale_total_amount').text(sum);
$("#sale_item_discount").on('keyup', function() {
var discount = $("#sale_item_discount").val();
$("#sale_item_total_amount").val(sum - discount);
$("#sale_subtotal_amount").text(sum - discount);
$("#sale_total_amount").text(sum - discount);
});
});
});
</script>
and here is the HTML code
<table class="table sale-entry" id="sale_table">
<thead class="thead-light">
<tr>
<th scope="col">Item Name</th>
<th scope="col">Quantity</th>
<th scope="col">Rate</th>
<th scope="col">Discount</th>
<th scope="col">Total Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td><select class="form-control" name="item_name[]">
<option>Select an Item</option>
<?php while($item_result = mysqli_fetch_assoc($select_item_query)) { ?>
<option><?php echo $item_result['item_name']; ?></option>
<?php } ?>
</select>
</td>
<td><input type="text" class="form-control" name="item_quantity[]" id="sale_item_quantity" placeholder="0.00"></td>
<td><input type="text" class="form-control" name="item_price[]" id="sale_item_price" placeholder="0.00"></td>
<td><input type="text" class="form-control" name="item_discount[]" id="sale_item_discount" placeholder="%"></td>
<td><input type="text" class="form-control" name="item_total_amount[]" id="sale_item_total_amount" placeholder="0.00"></td>
</tr>
</tbody>
</table>
What could be the issue?
if $('#sale_item_price, #sale_item_quantity').on('keyup'... not working then $(document).on('keyup', '#sale_item_price, #sale_item_quantity',... works.
Here, $('#sale_item_price, #sale_item_quantity') is unaware of DOM changed.
Have a look in example:-
$(document).ready(function() {
$(document).on('keyup', '#sale_item_price, #sale_item_quantity, #sale_item_discount', function() {
var sum = 0;
$('.sale-entry > tbody > tr').each(function() {
var qty = $(this).find('#sale_item_quantity').val();
var price = $(this).find('#sale_item_price').val();
var discount = $(this).find('#sale_item_discount').val();
var amount = (qty * price);
if (discount) {
amount = amount - discount;
}
$(this).find('#sale_item_total_amount').val(amount);
sum += amount;
});
$('#sale_subtotal_amount').text(sum);
$('#sale_total_amount').text(sum);
});
});
$(document).ready(function() {
$('#add_row').click(function() {
$('#sale_table').append('<tr><td><select class="form-control" name="item_name[]"><option>Select an Item</option></select></td><td><input type="text" class="form-control" name="item_quantity[]" id="sale_item_quantity" placeholder="0.00"></td><td><input type="text" class="form-control" name="item_price[]" id="sale_item_price" placeholder="0.00"></td><td><input type="text" class="form-control" name="item_discount[]" id="sale_item_discount" placeholder="%"></td><td><input type="text" class="form-control" name="item_total_amount[]" id="sale_item_total_amount" placeholder="0.00"></td></tr>');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table sale-entry" id="sale_table">
<thead class="thead-light">
<tr>
<th scope="col">Item Name</th>
<th scope="col">Quantity</th>
<th scope="col">Rate</th>
<th scope="col">Discount</th>
<th scope="col">Total Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<select class="form-control" name="item_name[]">
<option>Select an Item</option>
</select>
</td>
<td><input type="text" class="form-control" name="item_quantity[]" id="sale_item_quantity" placeholder="0.00"></td>
<td><input type="text" class="form-control" name="item_price[]" id="sale_item_price" placeholder="0.00"></td>
<td><input type="text" class="form-control" name="item_discount[]" id="sale_item_discount" placeholder="%"></td>
<td><input type="text" class="form-control" name="item_total_amount[]" id="sale_item_total_amount" placeholder="0.00"></td>
</tr>
</tbody>
</table>
<button id="add_row" type="button">Add row</button>
<div>sale_subtotal_amount: <span id="sale_subtotal_amount"></span></div>
<div>sale_total_amount: <span id="sale_total_amount"></span></div>