I have a formfield with a static row for an invoice position. With + and - buttons I can add or remove additional rows for invoice positions dynamically. This works fine, but within each row I have a have a selectbox that switches the calculation method for the row (from km- to hour- or misc-based). This last feature only works for the first static row, not for the added rows?
HTML
<form action="" method="post">
<div class="mb-3">
<div id="position_0" class="row align-items-start">
<div class="col-4">
<label for="description" class="form-label">Beschreibung</label>
<textarea class="form-control" id="description_0" name="description_0" rows="1"></textarea>
</div>
<div class="col-2">
<label for="date" class="form-label">Tag der Leistung</label>
<input type="text" class="form-control" id="date_0" name="date_0">
</div>
<div class="col-1">
<label for="amount" class="form-label">Menge</label>
<input type="text" class="form-control" id="amount_0" name="amount_0">
</div>
<div class="col-2">
<label for="type" class="form-label">Abrechnungsform</label>
<select class="form-select" id="type_0" name="type_0">
<option value="km" selected>Kilometer</option>
<option value="hours">Stunden</option>
<option value="misc">Sonstiges</option>
</select>
</div>
<div class="col-1">
<label for="price" class="form-label">Einzelpreis</label>
<input type="text" class="form-control" id="price_0" name="price_0" value="{{price_km}}">
</div>
<div class="col-2">
<label for="sum" class="form-label">Summe</label>
<input type="text" class="form-control" id="sum_0" name="sum_0">
</div>
</div>
</div>
<div id="multiple"></div>
<button type="submit" class="btn btn-primary float-start">Speichern</button>
</form>
<button class="btn btn-primary float-end" onclick="addItems()"><i class="bi bi-plus"></i></button>
<button class="btn btn-primary float-end" onclick="removeItems()"><i class="bi bi-dash"></i></button>
Javascript/JQuery
<script>
var formatter = new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR',
});
var km = 0.97;
var hours = 12;
var misc = 0;
// THIS DOES NOT WORK START
$("#multiple").each(function () {
var n = $(this).find("div.mb-3").length;
$('#type_' + n).on('change', function () {
if (this.value === 'km') {
$('#price_' + n).val(formatter.format(km));
} else if (this.value === 'hours') {
$('#price_' + n).val(formatter.format(hours));
} else if (this.value === 'misc') {
$('#price_' + n).val(formatter.format(misc));
}
});
});
// THIS DOES NOT WORK END
function addItems() {
$("#multiple").each(function () {
var i = $(this).find("div.col").length;
var n = (i / 6) + 1;
$(this).append(`<div class="mb-3">
<div id="position_` + n + `" class="row align-items-start">
<div class="col col-4">
<textarea class="form-control" id="description_` + n + `" name="description_` + n + `" rows="1"></textarea>
</div>
<div class="col col-2">
<input type="text" class="form-control" id="date_` + n + `" name="date_` + n + `">
</div>
<div class="col col-1">
<input type="text" class="form-control" id="amount_` + n + `" name="amount_` + n + `">
</div>
<div class="col col-2">
<select class="form-select" id="type_` + n + `" name="type_` + n + `">
<option value="km" selected>Kilometer</option>
<option value="hours">Stunden</option>
<option value="misc">Sonstiges</option>
</select>
</div>
<div class="col col-1">
<input type="text" class="form-control" id="price_` + n + `" name="price_` + n + `" value="{{price_km}}">
</div>
<div class="col col-2">
<input type="text" class="form-control" id="sum_` + n + `" name="sum_` + n + `">
</div>
</div>
</div>`);
});
}
function removeItems() {
$("#multiple").each(function () {
var n = $(this).find("div.mb-3").length;
if (n != 0) {
$("#position_" + n).parents("div.mb-3").remove();
}
});
}
</script>
Only the initial items are "wired" the change event because you run
// this line loops only on the initial items
$("#multiple").each(function () {
To solve this you have to set an .on(event) function
// this is NOT a complete example
// 1. add a generic class to all the selects
<select class="form-select mytypeselect" id="type_0" name="type_0">
<option value="km" selected>Kilometer</option>
<option value="hours">Stunden</option>
<option value="misc">Sonstiges</option>
</select>
// 2. Set the on event, but all thing relative to the element (not fixed to the index or id
$('.mytypeselect').on('change', function () {
var self = $(this);
var row = self.closest(".row"); // find the row the select belongs at
if (self.val() === 'km') {
// find the input inside the row to change
row.find('.mypriceinput').val(formatter.format(km));
This is not optimal, but it solves my problem
// First row of the invoice
$('select#type_0').on('change', function () {
if ($(this).val() === 'km') {
$(this).parents('div').find('#price_0').val(formatter.format(km));
} else if ($(this).val() === 'hours') {
$(this).parents('div').find('#price_0').val(formatter.format(hours));
} else if ($(this).val() === 'misc') {
$(this).parents('div').find('#price_0').val(formatter.format(misc));
}
});
// Everytime the DOM changes
$("#multiple").bind("DOMSubtreeModified", function () {
$('.mytypeselect').on('change', function () {
var sibling = $(this).parents('div');
var n = (($(this).attr('id')).split('_'))[1];
if ($(this).val() === 'km') {
sibling.find('#price_' + n).val(formatter.format(km));
} else if ($(this).val() === 'hours') {
sibling.find('#price_' + n).val(formatter.format(hours));
} else if ($(this).val() === 'misc') {
sibling.find('#price_' + n).val(formatter.format(misc));
}
});
});
I am trying to create a dynamic Question List along with its dynamic options. With each option I maintain a flag using checkbox. If the checkbox is clicked the AnalysisFlag value should be true and if not then it should be false. However using the below mentioned method, I am always getting the false value whether I clicked the checkbox or not.
Can someone please take a look and suggest me how I can maintain the AnalysisFlag value along with its equivalent option?
function GetDynamicTextBox(value) {
var textBox = $("<input />").attr("type", "textbox").attr("name", "DynamicTextBox").attr("class", "form-control").attr("placeholder","Your Answer");
textBox.val(value);
debugger;
**var allVals = [];
$('[name="DynamicAnalysisFlag"]:checked').each(function () {
allVals.push($(this).val());
});**
return textBox, allVals;
}
var j = 66;
var x = 2;
var option = 'option' + x;
function AddTextBox() {
for (var i = j; i <= j; i++) {
$('#TextBoxContainer' + x).after("<br id='Removebr" + (x + 1) + "'><div class='input-group' id='TextBoxContainer" + (x + 1) + "'><div class= 'input-group-prepend'><div class='input-group-text'> " + String.fromCharCode(i) + " **<input type='checkbox' id='DynamicAnalysisFlag' value= 'true' name='DynamicAnalysisFlag' class='checklistitem''></div>**</div><input autocomplete='off' class='form-control test-option test-option" + x + " text-box single-line' data-val='true' data-val-required='Answer is required' id=" + option + " name='DynamicTextBox' placeholder='Your Answer' type='text' value=''><span class='field-validation-valid text-danger' data-valmsg-for='AnalysisFlag' data-valmsg-replace='true'></span></div>");
}
j++;
x++;
}
function RemoveTextBox() {
if (x != 2) {
$('#TextBoxContainer' + x).remove();
$('#Removebr' + x).remove();
--x;
--j;
}
}
$('#btnNext').on('click', function() {
var radioValue1 = $("input[name='AnalysisFlag']:checked").val();
var txtVal = $('.test-option' + radioValue1).val();
$('#hiddenRadioValue').val(txtVal);
});
$(function() {
var values = eval('#Html.Raw(ViewBag.Values)');
if (values != null) {
$("#TextBoxContainer").html("");
$(values).each(function() {
$("#TextBoxContainer").append(GetDynamicTextBox(this));
});
}
});
<div id="radio" class="col-xs-12">
<br id="Removebr2">
<div class="input-group" id="TextBoxContainer2">
<div class="input-group-prepend">
<div class="input-group-text">
A
<input type="checkbox" id="radio1" value="1" name="AnalysisFlag" onselect="alert('clicke')">
</div>
</div>
<input autocomplete="off" class="form-control test-option test-option1 text-box single-line" data-val="true" data-val-required="Option is required" id="opt1" name="opt1" placeholder="Your Answer" type="text" value="">
<span class="field-validation-valid text-danger" data-valmsg-for="opt1" data-valmsg-replace="true"></span>
<input data-val="true" data-val-required="The AnalysisFlag field is required." id="hiddenRadioValue" name="AnalysisFlag" type="hidden" value="">
<br>
</div>
</div>
<div class="card-footer">
<input type="submit" id="btnNext" value="Next »" class="btn btn-primary vigor-btn">
</div>
<button type="button" id="btnRemove" class="btn btn-primary vigor-btn" onclick="RemoveTextBox()">Remove Options</button>
<button type="button" id="btnAdd" class="btn btn-primary vigor-btn" onclick="AddTextBox()">Add Options</button>
I have edited the GetDynamicTextBox() function in which I am getting the DynamicAnalysisFlag value which I add at the time of adding another textbox in AddTextBox() function. But now the issue is, if I tick the checkbox I am getting the true value but if I don't tick the checkbox I am getting nothing. So, what changes should I do in this code so if I check the code, I get true and if not then I get false.
When I append div one by one, it's working properly. but when I delete the first one or any from the previous one, it's not deleting properly. And if once again I want to append another div div-number is not maintaining sequence. Actually, I want to build a system where users can add products and also can delete the product during invoice generation. so please help me with how these kinds of stuff can be maintained. Also, I need to calculate the subtotal amount of individual products with individual div. Here is my code:
<script type="text/javascript">
let divCount = 0;
$(function() {
$('#btnAddtoList').on('click', function(){
divCount++;
const div_title = divCount;
var newDiv = $(
`<div class=item-wrapper-${div_title}>` +
'<div class="container rounded bg-white mt-3 mb-3">' +
'<div class="row">' +
'<div class="col-md-12">' +
'<div class="row mt-3">' +
'<span><strong>পণ্যের বিবরণ #</strong></span>'+ div_title +
'</div>' +
'<div class="row mt-1 text-center">' +
'<select class="product_option form-control" id="product">' +
'<option disabled selected> -- পণ্য পছন্দ করুন (পণ্যের নাম | বিক্রয় মূল্য |
অ্যাভেলেবল আছে) --
</option>' +
'</select>' +
'</div>' +
'<div class="row mt-3">' +
'<label class="labels" style="font-size: 16px">পণ্যের নাম</label>
<input type="text" class="form-control" id="productName">' +
'</div>' +
'<div class="row mt-3">' +
'<label class="labels" style="font-size: 16px">বিক্রয় মূল্য</label>
<input type="number" class="form-control" id="sellPrice">' +
'</div>' +
'<div class="row mt-3">' +
'<label class="labels" style="font-size: 16px">পণ্য মজুদ আছে </label>
<input type="text" class="form-control" id="amount" ">' +
'</div>' +
'<div class="row mt-3">' +
'<label class="labels" style="font-size: 16px">পরিমাণ</label>
<input type="number" class="form-control quantity_pro" id="quantity" ">' +
'</div>' +
`<div class="mt-3 d-flex flex-column align-items-center text-center">
<button class="btn btn-danger deleteItem" id=del-${div_title}
type="button">মুছুন
</button>
</div>` +
'</div>' +
'</div>' +
'</div>' +
'</div>');
$('.productDiv').append(newDiv);
console.log(div_title);
$(".item-wrapper-" + div_title).find(".product_option").select2({
theme: "classic"
});
firebase.auth().onAuthStateChanged(function(user) {
console.log(user);
if (user) {
var user_id = user.uid;
firebase.database().ref('Products/').child(user_id).once('value')
.then(function(snapshot){
snapshot.forEach(function(childSnapshot) {
var product_name = childSnapshot.child("product_name").val();
var selling_price = childSnapshot.child("selling_price").val();
var amount = childSnapshot.child("product_quantity").val();
{#console.log(amount)#}
var total = product_name + " | " + selling_price + " | " + amount;
console.log(total);
$(".item-wrapper-" + div_title).find(".product_option").append('<option>'
+ total + '</option');
$(document).on("change", ".product_option", function () {
const valArr = $(`.item-wrapper-${div_title} .product_option
option:selected`).text().split(" | ");
$(`div.item-wrapper-${div_title} #productName`).val(valArr[0]);
$(`div.item-wrapper-${div_title} #sellPrice`).val(valArr[1]);
$(`div.item-wrapper-${div_title} #amount`).val(valArr[2]);
});
});
})
}
else{
window.location.href="{% url 'login' %}";
}
});
});
$("#subTotal").on('click', function (e) {
var subTotalAmount = 0;
for (var i = 1; i<=divCount; i++){
var getProductName = $(`div.item-wrapper-${i} #productName`).val();
var getSellingPrice = $(`div.item-wrapper-${i} #sellPrice`).val();
var getAmount = $(`div.item-wrapper-${i} #amount`).val();
var getQuantity = $(`div.item-wrapper-${i} #quantity`).val();
subTotalAmount += getSellingPrice*getQuantity;
}
var SellingPriceFloat = parseFloat(getSellingPrice);
var amountFloat = parseFloat(getAmount);
console.log(amountFloat)
var quantityFloat = parseFloat(getQuantity);
console.log(quantityFloat);
console.log(subTotalAmount)
if (quantityFloat>amountFloat){
alert("পর্যাপ্ত পরিমান পণ্য নেই ।");
}
else {
// executes only once
var subDiv = $(
'<div class="item-wrapper">' +
'<div class="container rounded bg-white mt-3 mb-3">' +
'<div class="row">' +
'<div class="col-md-12">' +
'<div class="row mt-3">' +
'<span class="col-md-12">সাব টোটালঃ</strong></span>'
+subTotalAmount +
'</div>' +
'<div class="row mt-3">' +
'<label class="labels" style="font-size: 16px">ডিসকাউন্ট(%)
</label><input type="text" class="form-control" id="productName">' +
'</div>' +
'<div class="row mt-3">' +
'<label class="labels" style="font-size: 16px">ভ্যাট(%)
</label><input type="text" class="form-control" id="sellPrice">' +
'</div>' +
'<div class="row mt-3">' +
'<span class="col-md-12"><strong>মোটঃ</strong></span>'+
'</div>' +
'<div class="mt-3 d-flex flex-column align-items-center text- center">
<button class="btn btn-info" type="button">মোট</button></div>' +
'</div>' +
'</div>' +
'</div>' +
'</div>');
$('.subTotalDiv').html(subDiv);
}
});
$(document).on("click", ".deleteItem", function() {
$(this).closest(`.item-wrapper-${divCount}`).remove();
divCount-=1;
});
});
</script>
here is my html:
<div class="productDiv"></div>
<div class="mt-3 text-center">
<button class="btn profile-button" style="color: white" type="button"
id="btnAddtoList">পণ্য যোগ করুন</button>
</div>
<div class="mt-3 text-center">
<button class="btn profile-button" style="color: white" type="button"
id="subTotal" >সাব টোটাল</button>
</div>
<div class="subTotalDiv"></div>
You can see that two div with the same div number:
Thanks in advance.
You have many important issues in that code.
You are creating some dynamic elements having always the same id.
An id must be unique. NEVER use an id in a loop or in an event handler that appends elements.Use a class instead.
When you have more than one or two lines of HTML concatenated in a string for some appending... Better use the .clone() method on a "template" hidden in the HTML.
That makes your code more readable and maintainable, since the "template" to clone will appear as regular HTML in your code editor, so you can see typos right away.
And the JS is then more concise.
The main advantage of using jQuery is its ease to "traverse" the DOM using easy and short methods.
From a user action (like from a event triggered on a <select> element)... Use the wide set of method like .parent(), .closest(), .find(), .siblings(), etc... to target the elements you want.
Reminder for your future coding: Every time you have to add a number to a class to make it unique... Take it as a symptom of a bad coding. While an id must be unique to target ONE element, a class must be "generic" to target a set of similar elements.
I COMPLETELY removed your "concept" of having the divCount an div_title variable in the below snippet.
Your issue was NOT about how to correctly use it... But how to NOT use it. ;)
Function nesting.
You used event delegation: $(document).on("change", ".product_option", function () {...}
Nice! But that is inside the Firebase callback.
And the Firebase request is inside the btnAddtoList click handler.
So every times the user click on the পণ্য যোগ করুন (Add products) button, there is a request made to the database (most probably with the same result). And an additional delegated handler for all .product_option select in the page is setted.
It does not looks too good right?
And that was due to your (failed) attempt to use some "unique" item-wrapper-* classes...
So below is your code changed a lot. I did not dive into your Firebase request because I really don't know the structure of the response. I "assumed" a response with the snapshot array of objects. You may have something quite different.
Have a close look at the code and all the comments.
console.clear();
$(function () {
// Add a cloned div
$("#btnAddtoList").on("click", function () {
// Clone the template and toggle some classes
let newDiv = $(".item-wrapper_template")
.clone()
.toggleClass("item-wrapper_template item-wrapper");
// Append
newDiv.find(".number").text($(".item-wrapper").length + 1);
$(".productDiv").append(newDiv);
// Instantiate Select2
newDiv.find(".product_option").select2({
theme: "classic"
});
});
// Delete a cloned div
$(document).on("click", ".deleteItem", function () {
// Remove the whole wrapper div that holds the .deleteItem button
$(this).closest(".item-wrapper").remove();
// Update the numbers of the other items
$(".item-wrapper").each(function (num) {
$(this)
.find(".number")
.text(num + 1);
});
});
// Calculate the sub total
$("#subTotal").on("click", function (e) {
// At each click event, start the calculation at zero
let subTotalAmount = 0;
// How many items now?
let itemCount = $(".item-wrapper").length;
// A flag to know if we break the loop
let loopBreak = false;
// Looping all the items
for (let i = 0; i < itemCount; i++) {
let getSellingPrice = parseFloat(
$(".item-wrapper").eq(i).find(".sellPrice").val()
);
let getAmount = parseFloat(
$(".item-wrapper").eq(i).find(".amount").val()
);
let getQuantity =
parseFloat($(".item-wrapper").eq(i).find(".quantity").val()) || 0;
// A condition check which may break the loop
if (getQuantity > getAmount) {
alert("পর্যাপ্ত পরিমান পণ্য নেই ।"); // There are not enough products.
loopBreak = true;
break;
} else {
subTotalAmount += getSellingPrice * getQuantity;
console.log("subTotalAmount", subTotalAmount);
}
} // END for loop
// If the loop was not broken
if (!loopBreak) {
$(".subTotalDiv").find(".subTotalAmount").text(subTotalAmount);
$(".subTotalDiv").show();
}
});
// Option change handler for ALL select element present on the page
$(document).on("change", ".product_option", function () {
const valArr = $(this).find("option:selected").text().split(" | ");
$(this).closest(".item-wrapper").find(".productName").val(valArr[0]);
$(this).closest(".item-wrapper").find(".sellPrice").val(valArr[1]);
$(this).closest(".item-wrapper").find(".amount").val(valArr[2]);
});
// =====
// Simulating the firebase database request
// Let assume some data to make this example working
let snapshot = [
{
product_name: "First Product",
selling_price: 10.57,
product_quantity: 42
},
{
product_name: "Second Product",
selling_price: 28.72,
product_quantity: 17
},
{
product_name: "Third Product",
selling_price: 11.48,
product_quantity: 8
}
];
/*
firebase.auth().onAuthStateChanged(function(user) {
console.log(user);
if (user) {
var user_id = user.uid;
firebase.database().ref('Products/').child(user_id).once('value')
.then(function(snapshot){
snapshot.forEach(function(childSnapshot) {
var product_name = childSnapshot.child("product_name").val();
var selling_price = childSnapshot.child("selling_price").val();
var amount = childSnapshot.child("product_quantity").val();
{#console.log(amount)#}
var total = product_name + " | " + selling_price + " | " + amount;
console.log(total);
$(".item-wrapper-" + div_title).find(".product_option").append('<option>'
+ total + '</option');
});
*/
// Here, I am simulating the option appending from the simulated snapshot array above
// Notice I append it to the template!
snapshot.forEach(function (item, index) {
// Format the text of the option
let optionText =
item.product_name +
" | " +
item.selling_price +
" | " +
item.product_quantity;
// Create the option and append
let option = $("<option>").text(optionText);
$(".item-wrapper_template").find(".product_option").append(option);
});
/*
})
}
else{
window.location.href="{% url 'login' %}";
}
});
*/
});
.item-wrapper_template{
display: none;
}
.subTotalDiv{
display: none;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
<div class="productDiv"></div>
<!-- That is a TEMPLATE -->
<div class=item-wrapper_template>
<div class="container rounded bg-white mt-3 mb-3">
<div class="row">
<div class="col-md-12">
<div class="row mt-3">
<span><strong>পণ্যের বিবরণ (Product Description) #</strong></span><span class="number">0</span>
</div>
<div class="row mt-1 text-center">
<select class="product_option form-control">
<option disabled selected> -- পণ্য পছন্দ করুন (পণ্যের নাম | বিক্রয় মূল্য | অ্যাভেলেবল আছে) -- </option>
<option disabled> -- Choose Product (Product Name | Sale Price | Available) -- </option>
</select>
</div>
<div class="row mt-3">
<label class="labels" style="font-size: 16px">পণ্যের নাম (Product name)</label> <input type="text" class="form-control productName">
</div>
<div class="row mt-3">
<label class="labels" style="font-size: 16px">বিক্রয় মূল্য (Sale price)</label> <input type="number" class="form-control sellPrice">
</div>
<div class="row mt-3">
<label class="labels" style="font-size: 16px">পণ্য মজুদ আছে (There are stockpiles of products)</label> <input type="text" class="form-control amount">
</div>
<div class="row mt-3">
<label class="labels" style="font-size: 16px">পরিমাণ (Amount)</label> <input type="number" class="form-control quantity_pro quantity">
</div>
<div class="mt-3 d-flex flex-column align-items-center text-center"> <button class="btn btn-danger deleteItem" type="button">মুছুন (Delete)</button> </div>
</div>
</div>
</div>
</div>
<!-- That is your "normal" HTML -->
<div class="mt-3 text-center">
<button id="btnAddtoList" class="btn profile-button" type="button">পণ্য যোগ করুন (Add products)</button>
</div>
<div class="mt-3 text-center">
<button id="subTotal" class="btn profile-button" type="button">সাব টোটাল (Sub Total)</button>
</div>
<!-- That is hidden by CSS but shown by JS -->
<div class="subTotalDiv">
<div class="container rounded bg-white mt-3 mb-3">
<div class="row">
<div class="col-md-12">
<div class="row mt-3">
<span class="col-md-12">সাব টোটালঃ (Sub Total:)</strong></span><span class="subTotalAmount">0</span>
</div>
<div class="row mt-3">
<label class="labels" style="font-size: 16px">ডিসকাউন্ট(%) (Discount (%))</label><input type="text" class="form-control">
</div>
<div class="row mt-3">
<label class="labels" style="font-size: 16px">ভ্যাট(%) (VAT (%))</label><input type="text" class="form-control sellPrice">
</div>
<div class="row mt-3">
<span class="col-md-12"><strong>মোটঃ (Total:)</strong></span>
</div>
<div class="mt-3 d-flex flex-column align-items-center text- center"> <button class="btn btn-info" type="button">মোট (Total)</button></div>
</div>
</div>
</div>
</div>
CodePen
I am cloning four field (sl no,stationery type ,quantity, Remove ) of a form by using java script.I can very well append or remove these field
I am not able to generate the serial no on the first column and if I delete any row in between this should also adjust the serial no.How can i achieve this My code is below
$(document).ready(function() {
$(document).on('click', '.add', function() {
var html = '';
html += '<tr>';
html += '<td><input type="text" name="item_name[]" class="form-control item_name" ></td>';
html += '<td><select name="item_unit[]" class="form-control item_unit" id="datalist"><option value="">Select Stationery Type</option><option value="A4 Green Ream">A4 Green Ream</option><option value="A4 Green Ream">A4 Green Ream</option><option value="Cellotape(Brown)">Cellotape(Brown)</option><option value="Cellotape(Transparent)">Cellotape(Transparent)</option><option value="Gluestick">Gluestick</option><option value="Highlighter">Highlighter</option><option value="Marker(Thick)">Marker(Thick)</option><option value="Marker(Thin)">Marker(Thin)</option><option value="Meeting Pen">Meeting Pen</option><option value="Normal Envelope">Normal Envelope</option></select></td>';
html += '<td><input type="text" name="item_quantity[]" class="form-control number_only item_quantity" /></td>';
html += '<td><button type="button" name="remove" class="btn btn-danger btn-sm remove"><span class="glyphicon glyphicon-minus"></span></button></td></tr>';
$('#item_table').append(html);
});
$(document).on('click', '.remove', function() {
$(this).closest('tr').remove();
});
$('#insert_form').on('submit', function(event) {
event.preventDefault();
var error = '';
$('.item_name').each(function() {
var count = 1;
if ($(this).val() == '') {
error += "<p>Enter Item Name at " + count + " Row</p>";
return false;
}
count = count + 1;
});
$('.item_quantity').each(function() {
var count = 1;
if ($(this).val() == '') {
error += "<p>Enter Item Quantity at " + count + " Row</p>";
return false;
}
count = count + 1;
});
$('.item_unit').each(function() {
var count = 1;
if ($(this).val() == '') {
error += "<p>Select Unit at " + count + " Row</p>";
return false;
}
count = count + 1;
});
var form_data = $(this).serialize();
if (error == '') {
$.ajax({
url: "insert.php",
method: "POST",
data: form_data,
success: function(data) {
if (data == 'ok') {
$('#item_table').find("tr:gt(0)").remove();
$('#error').html('<div class="alert alert-success">Item Details Saved</div>');
}
}
});
} else {
$('#error').html('<div class="alert alert-danger">' + error + '</div>');
}
});
$(document).on('keypress', '.number_only', function(e) {
return isNumbers(e, this);
});
function isNumbers(evt, element) {
var charCode = (evt.which) ? evt.which : event.keyCode;
if (
(charCode != 46 || $(element).val().indexOf('.') != -1) && // “.” CHECK DOT, AND ONLY ONE.
(charCode < 48 || charCode > 57))
return false;
return true;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<head>
</head>
<body>
<br />
<div class="container" style="border: 2px solid #B22222;border-radius: 10px;margin-top: 25px;margin-bottom: 15px;>
<div class=" row ">
<div class="col-md-4 ">
</div>
<div class="col-sm-12 ">
<h4 align="center "><b><u>Add Stationery Stock<b></u></h4>
<br />
<form method="post " id="insert_form ">
<div class="col-sm-6 ">
<input type="text " name="Order No. " class="form-control " placeholder="Order NO "/>
</div>
<div class="col-sm-6 ">
<input type="date " name="Date " class="form-control " placeholder="Date " />
</div>
<div> </div>
<div> </div>
<div> </div>
<h4 align="center "><b><u>Stationery Details<b></u></h4>
<div> </div>
<div class="table-repsonsive ">
<span id="error "></span>
<table class="table table-bordered " id="item_table ">
<tr>
<th>Sl.No.</th>
<th>Select Stationery Type</th>
<th>Enter Quantity</th>
<th><button type="button " name="add " class="btn btn-success btn-sm add "><span class="glyphicon glyphicon-plus "></span></button></th>
</tr>
</table>
<div align="center ">
<input type="submit " name="submit " class="btn btn-info "style="margin-bottom:20px " value="Insert " />
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Using
html += '<td><input type="text" name="item_name[]" class="form-control item_name"></td>';
you can do
const renum = () => {
let cnt = 0;
$(".item_name").each(function() {
this.value = ++cnt;
})
};
when needed
I fixed your invalid HTML (u and b not correctly closed and a missing quote on the first inline style)
I ALSO remove the name="submit" - you never want to have name="submit" on a form you plan to submit using script
const renum = () => {
let cnt = 0;
$(".item_name").each(function() {
this.value = ++cnt;
})
};
$(function() {
$("#item_table").on('click', '.add', function() {
var html = '';
html += '<tr>';
html += '<td><input type="text" name="item_name[]" class="form-control item_name" ></td>';
html += '<td><select name="item_unit[]" class="form-control item_unit" id="datalist"><option value="">Select Stationery Type</option><option value="A4 Green Ream">A4 Green Ream</option><option value="A4 Green Ream">A4 Green Ream</option><option value="Cellotape(Brown)">Cellotape(Brown)</option><option value="Cellotape(Transparent)">Cellotape(Transparent)</option><option value="Gluestick">Gluestick</option><option value="Highlighter">Highlighter</option><option value="Marker(Thick)">Marker(Thick)</option><option value="Marker(Thin)">Marker(Thin)</option><option value="Meeting Pen">Meeting Pen</option><option value="Normal Envelope">Normal Envelope</option></select></td>';
html += '<td><input type="text" name="item_quantity[]" class="form-control number_only item_quantity" /></td>';
html += '<td><button type="button" name="remove" class="btn btn-danger btn-sm remove"><span class="glyphicon glyphicon-minus"></span></button></td></tr>';
$('#item_table').append(html);
renum()
});
$(document).on('click', '.remove', function() {
$(this).closest('tr').remove();
renum()
});
$('#insert_form').on('submit', function(event) {
event.preventDefault();
var error = '';
$('.item_name').each(function() {
var count = 1;
if ($(this).val() == '') {
error += "<p>Enter Item Name at " + count + " Row</p>";
return false;
}
count = count + 1;
});
$('.item_quantity').each(function() {
var count = 1;
if ($(this).val() == '') {
error += "<p>Enter Item Quantity at " + count + " Row</p>";
return false;
}
count = count + 1;
});
$('.item_unit').each(function() {
var count = 1;
if ($(this).val() == '') {
error += "<p>Select Unit at " + count + " Row</p>";
return false;
}
count = count + 1;
});
var form_data = $(this).serialize();
if (error == '') {
$.ajax({
url: "insert.php",
method: "POST",
data: form_data,
success: function(data) {
if (data == 'ok') {
$('#item_table').find("tr:gt(0)").remove();
$('#error').html('<div class="alert alert-success">Item Details Saved</div>');
}
}
});
} else {
$('#error').html('<div class="alert alert-danger">' + error + '</div>');
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
<div class="container" style="border: 2px solid #B22222;border-radius: 10px;margin-top: 25px;margin-bottom: 15px;">
<div class="row">
<div class="col-md-4"></div>
<div class="col-sm-12">
<h4 align="center"><b><u>Add Stationery Stock</u></b></h4>
<form method="post" id="insert_form">
<div class="col-sm-6"><input type="text" name="Order No." class="form-control" placeholder="Order NO " /></div>
<div class="col-sm-6"><input type="date" name="Date" class="form-control" placeholder="Date" /></div>
<div> </div>
<div> </div>
<div> </div>
<h4 align="center"><b><u>Stationery Details</u></b></h4>
<div> </div>
<div class="table-repsonsive"><span id="error"></span>
<table class="table table-bordered" id="item_table">
<tr>
<th>Sl.No.</th>
<th>Select Stationery Type</th>
<th>Enter Quantity</th>
<th><button type="button" name="add" class="btn btn-success btn-sm add"><span class="glyphicon glyphicon-plus"></span></button></th>
</tr>
</table>
<div align="center"><input type="submit" class="btn btn-info" style="margin-bottom:20px" value="Insert" /></div>
</div>
</form>
</div>
</div>
</div>
var checkSum = 0;
var jsonData = {};
var pushData;
var trData = [];
var sumData = [];
var chkArray = [];
countTab2 = 1;
$(".add-customs").click(function() {
customsTable();
});
function customsTable() {
var markup = "<div class='col-md-1'>Custom</div>" +
"<div class='col-md-4'><input id='customReason" +
countTab2 +
"' type='text' value='' class='txt form-control'" +
"name='customReason' path='customReason' /></div>" +
"<div class='col-md-2'><input value='0' type='text' class='txt form-control'" +
"name='customAmount' id='customAmount" +
countTab2 +
"'></div>" +
"<div class='col-md-2'><input value='0' onchange='getCustomTotal();' type='text' class='txt form-control'" +
"name='customPenalty' id='customPenalty" +
countTab2 +
"'></div>" +
"<div class='col-md-1'><span id='customSum" +
countTab2 +
"'>0</span></div>" +
"<div class='col-md-2'></div>";
countTab2++;
$(".custom-table").append(markup);
}
//adding row for VAT
countTab3 = 1;
$(".add-vat").click(function() {
vatTable();
});
function vatTable() {
var markup = "<div class='col-md-1'>VAT</div>" +
"<div class='col-md-4'><input id='vatReason" +
countTab3 +
"' type='text' value='' class='txt1 form-control'" +
"name='vatReason' /></div>" +
"<div class='col-md-2'><input type='text' class='txt1 form-control'" +
"name='vatAmount' value='0' id='vatAmount" +
countTab3 +
"'></div>" +
"<div class='col-md-2'><input type='text' value='0' onchange='getVatTotal();' class='txt1 form-control'" +
"name='vatPenalty' id='vatPenalty" +
countTab3 +
"'></div>" +
"<div class='col-md-1'><span id='vatTotal" +
countTab3 +
"'></span></div>" +
"<div class='col-md-2'></div>";
countTab3++;
$(".vat-table").append(markup);
}
//adding row for Excise
countTab4 = 1;
$(".add-excise").click(function() {
exciseTable();
});
function exciseTable() {
var markup = "<div class='col-md-1'>Excise</div>" +
"<div class='col-md-4'><input id='exciseReason" +
countTab4 +
"' type='text' value='' class='txt2 form-control'" +
"name='exciseReason' /></div>" +
"<div class='col-md-2'><input type='text' class='txt2 form-control'" +
"name='exciseAmount' value='0' id='exciseAmount" +
countTab4 +
"'></div>" +
"<div class='col-md-2'><input type='text' onchange='getExciseTotal();' class='txt2 form-control'" +
"name='excisePenalty' value='0' id='excisePenalty" +
countTab4 +
"'></div>" +
"<div class='col-md-1'><span id='exciseTotal" +
countTab4 +
"'></span></div>" +
"<div class='col-md-2'></div>";
countTab4++;
$(".excise-table").append(markup);
}
customs = [];
function getListCustoms() {
for (i = 0; i < countTab2; i++) {
if ($("#customPenalty" + i).length) {
customs.push({
assessReason: $("#customReason" + i).val(),
assessAmount: $("#customAmount" + i).val(),
assessPenalty: $("#customPenalty" + i).val()
});
}
}
}
function getCustomTotal() {
var customTotal = 0;
getListCustoms();
customs.unshift({
assessReason: $("#customReason").val(),
assessAmount: $("#customAmount").val(),
assessPenalty: $("#customPenalty").val()
});
customTotal = customTotal + parseInt(customs[0].assessAmount) +
parseInt(customs[0].assessPenalty);
for (i = 1; i < customs.length; i++) {
customTotal = customTotal + parseInt(customs[i].assessAmount) +
parseInt(customs[i].assessPenalty);
customRowTotal = 0;
customRowTotal = parseInt($("#customAmount" + i).val()) +
parseInt($("#customPenalty" + i).val());
$("#customSum" + i).html(customRowTotal);
}
getTotalSum();
$('#tot').html(wholeTotal);
}
$("#customPenalty").change(
function() {
totalCustom = 0;
totalCustom = parseInt($("#customAmount").val()) +
parseInt($("#customPenalty").val());
$("#customSum").html(totalCustom);
});
function getVatTotal() {
var vatTotal = 0;
getVatList();
vats.unshift({
assessReason: $("#vatReason").val(),
assessAmount: $("#vatAmount").val(),
assessPenalty: $("#vatPenalty").val()
});
vatTotal = vatTotal + parseInt(vats[0].assessAmount) +
parseInt(vats[0].assessPenalty);
for (i = 1; i < vats.length; i++) {
vatTotal = vatTotal + parseInt(vats[i].assessAmount) +
parseInt(vats[i].assessPenalty);
vatRowTotal = 0;
vatRowTotal = parseInt($("#vatAmount" + i).val()) +
parseInt($("#vatPenalty" + i).val());
$("#vatTotal" + i).html(vatRowTotal);
}
getTotalSum();
$('#tot').html(wholeTotal);
}
$("#vatPenalty").change(
function() {
totalVat = 0;
totalVat = parseInt($("#vatAmount").val()) +
parseInt($("#vatPenalty").val());
$("#vatTotal").html(totalVat);
});
vats = [];
function getVatList() {
for (i = 0; i < countTab3; i++) {
if ($("#vatPenalty" + i).length) {
vats.push({
assessReason: $("#vatReason" + i).val(),
assessAmount: $("#vatAmount" + i).val(),
assessPenalty: $("#vatPenalty" + i).val()
});
}
}
}
excises = [];
function getExciseList() {
for (i = 0; i < countTab4; i++) {
if ($("#excisePenalty" + i).length) {
excises.push({
assessReason: $("#exciseReason" + i).val(),
assessAmount: $("#exciseAmount" + i).val(),
assessPenalty: $("#excisePenalty" + i).val()
});
}
}
}
$("#excisePenalty").change(
function() {
totalExcise = 0;
totalExcise = parseInt($("#exciseAmount").val()) +
parseInt($("#excisePenalty").val());
/* $("#tot").html(totalVat+totalCustom); */
$("#exciseTotal").html(totalExcise);
});
function getExciseTotal() {
var exciseTotal = 0;
getExciseList();
excises.unshift({
assessReason: $("#exciseReason").val(),
assessAmount: $("#exciseAmount").val(),
assessPenalty: $("#excisePenalty").val()
});
exciseTotal = exciseTotal + parseInt(excises[0].assessAmount) +
parseInt(excises[0].assessPenalty);
for (i = 1; i < excises.length; i++) {
exciseTotal = exciseTotal + parseInt(excises[i].assessAmount) +
parseInt(excises[i].assessPenalty);
exciseRowTotal = 0;
exciseRowTotal = parseInt($("#exciseAmount" + i).val()) +
parseInt($("#excisePenalty" + i).val());
$("#exciseTotal" + i).html(exciseRowTotal);
}
getTotalSum();
$('#tot').html(wholeTotal);
}
function getTotalSum() {
wholeTotal = 0;
var allList = customs.concat(vats, excises);
for (i = 0; i < allList.length; i++) {
wholeTotal += parseInt(allList[i].assessAmount) + parseInt(allList[i].assessPenalty);
}
console.log(wholeTotal);
}
//submit method now
$("form").submit(function() {
event.preventDefault();
getTotalSum();
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<form>
<div class="col-md-12" style="float: none;">
<!-- <button onclick="myFunction()" class="pull-right">+</button> -->
<div style="margin-bottom: 30px;">
<div class="form-group row">
<div class="col-md-1"></div>
<div class="col-md-4">
<label>Reason</label>
</div>
<div class="col-md-2">
<label>Amount</label>
</div>
<div class="col-md-2">
<label>Penalty</label>
</div>
<div class="col-md-1">Total</div>
<div class="col-md-2">Action</div>
</div>
<div class="custom-table row">
<div class="col-md-1">
<label>Customs</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control" id="customReason" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt" id="customAmount" value="0" name="abc" min="0" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt" id="customPenalty" onchange="getCustomTotal();" value="0" name="abc" min="0" />
</div>
<div class="col-md-1">
<span id="customSum">0</span>
</div>
<div class="col-md-2">
<button class="add-customs">+</button>
</div>
</div>
<div class="vat-table row">
<div class="col-md-1">
<label>VAT</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control" id="vatReason" name="vatReason" />
</div>
<div class="col-md-2">
<input type="text" class="form-control txt1" id="vatAmount" value="0" name="vatAmount" min="0" />
</div>
<div class="col-md-2">
<input type="text" class="form-control txt1" id="vatPenalty" value="0" name="vatPenalty" onchange="getVatTotal();" min="0" />
</div>
<div class="col-md-1">
<span id="vatTotal">0</span>
</div>
<div class="col-md-2">
<button class="add-vat">+</button>
</div>
</div>
<div class="excise-table row">
<div class="col-md-1">
<label>Excise</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control" id="exciseReason" name="exciseReason" />
</div>
<div class="col-md-2">
<input type="text" class="form-control txt2" id="exciseAmount" value="0" name="exciseAmount" min="0" />
</div>
<div class="col-md-2">
<input type="text" class="form-control txt2" id="excisePenalty" value="0" name="excisePenalty" onchange="getExciseTotal();" min="0" />
</div>
<div class="col-md-1">
<span id="exciseTotal">0</span>
</div>
<div class="col-md-2">
<button class="add-excise">+</button>
</div>
<div class="col-md-1 pull-right">
<label>Total:</label> <b> <span id="tot">0</span></b>
</div>
</div>
</div>
<button type="submit" class="btn btn-success pull-right">Submit</button>
</div>
</form>
I have the form looking like this:
The total of the respective row is shown successfully but the total of all the input field is not showing as expected. And when I clear one input field then its data is not subtracted from the total. I am not able to get the correct sum of all the input fields which are dynamic. How can I make the changes here?
UPDATE:
when I am typing some data in "amount" and "penalty" then the total is also coming just after Penalty "column".
Can I pass those individual Total to the array like
{
assessmentType: "PRE",
assessCatID: 1,
assessReason: "11",
assessAmount: "22",
assessPenalty: "33"
}
I need a new field customOneRowTotal:22+33 and need to be inserted in array
Updated code(December 9,2018):
I have a AJAX calling a API and it has successfully arrived in my console:
var table = $('#nepal')
.DataTable(
{
"processing" : true,
"ajax" : {
"url" : A_PAGE_CONTEXT_PATH
+ "/form/api/getSelectionByAssessmentOrNonAssessment",
dataSrc : ''
},
"columns" : [ {
"data" : "selectionId"
}, {
"data" : "selectionDate"
}, {
"data" : "selectedBy"
}, {
"data" : "eximPanNo"
}, {
"data" : "eximPanName"
}, {
"data" : "eximPanAddr"
}, {
"data" : "eximPanPhone"
}, {
"data" : "selectionType"
}, {
"data" : "auditorGroupName"
} ]
});
Data is shown recently on Datatable and when I click on the single row then it is selected and populated as:
The JSON Data coming through this Ajax Call is:(We need assessCatAmount data recently now from this whole JSON data)
{
"selectionId":1,
"selectionDate":"2075-08-15",
"selectedBy":"Department",
"eximPanNo":1234,
"eximPanName":"PCS",
"eximPanNameEng":"PCS",
"eximPanAddr":"KAPAN",
"eximPanAddrEng":"PCS",
"eximPanPhone":9843709166,
"selectionType":"consignment\r\n",
"consignmentNo":122,
"consignmentDate":"2018-2-6",
"productName":null,
"selectionFromDate":"2018-11-30",
"selectionToDate":"2018-11-28",
"agentNo":3,
"selectionStatus":"1",
"entryBy":"1",
"entryDate":"2018-11-25 11:25:11",
"rStatus":"1",
"custOfficeId":1,
"selectionAudit":null,
"letter":null,
"auditorGroupName":null,
"document":null,
"assessment":{
"assessmentNo":1,
"assessmentType":"PRE",
"offCode":null,
"assessmentDate":"2071",
"assessmentBy":null,
"totalAssessment":null,
"selectionId":1,
"assSec":null,
"assRule":null,
"parentAssessmentId":null,
"appealId":445,
"demandNo":null,
"eximCd":null,
"consignmentNo":null,
"assessFrom":null,
"assessTo":null,
"assessReason":null,
"reasonDesc":null,
"intCalUpto":"2070",
"assessBasis":null,
"entryBy":"PCS",
"rStatus":"1"
},
"assessCatAmount":[
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":1,
"assessReason":"A",
"assessAmount":1,
"assessPenalty":2,
"entryBy":"PCS",
"rStatus":"1"
},
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":1,
"assessReason":"D",
"assessAmount":3,
"assessPenalty":4,
"entryBy":"PCS",
"rStatus":"1"
},
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":2,
"assessReason":"B",
"assessAmount":5,
"assessPenalty":6,
"entryBy":"PCS",
"rStatus":"1"
},
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":2,
"assessReason":"E",
"assessAmount":7,
"assessPenalty":8,
"entryBy":"PCS",
"rStatus":"1"
},
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":3,
"assessReason":"C",
"assessAmount":9,
"assessPenalty":10,
"entryBy":"PCS",
"rStatus":"1"
},
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":3,
"assessReason":"F",
"assessAmount":10,
"assessPenalty":10,
"entryBy":"PCS",
"rStatus":"1"
}
]
}
Now we have this form as:
Now i need to populate those six assessCatAmount data into this table. how can i get this?
When i click on Datatable the action of clicking is happening by:
.selected {
background-color: #a7d8d3;
}
$('#nepal tbody').on('click', 'tr', function() {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
} else {
table.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
}
trDataSecondTable = table.row(this).data();
console.log(trDataSecondTable);
});
everything is stored in trDataSecondTable on click of row of the datatable.
$('#chooseButton')
.on(
'click',
function() {
$('.hidden')
.css('display', 'block');
$("#panEximName")
.html(
trDataSecondTable.eximPanNameEng);
$("#panEximPhone")
.html(
trDataSecondTable.eximPanPhone);
for (var i = 0; i < trDataSecondTable.document.length; i++) {
if ($("#invoice").val() == trDataSecondTable.document[i].docNameEng) {
$("#invoice").prop(
'checked', true);
} else if ($("#packingList")
.val() == trDataSecondTable.document[i].docNameEng) {
$("#packingList").prop(
'checked', true);
} else {
$("#invoice").prop(
'checked', false);
$("#packingList").prop(
'checked', false);
}
}
$("#inoutDate")
.val(
trDataSecondTable.letter[0].inoutDate);
});
You need to delegate and not use inline event handling
Delegate and clone - I changed the div class to match customs instead of custom
Sum on every change
Change all buttons to type="button" to not submit on [+]
I moved the grand total out of the excise row
function sumIt() {
$("#formContainer [type=number]").each(function() {
var $row = $(this).closest(".row");
var $fields = $row.find("[type=number]");
var val1 = $fields.eq(0).val();
var val2 = $fields.eq(1).val();
var tot = (isNaN(val1) ? 0 : +val1) + (isNaN(val2) ? 0 : +val2)
$row.find(".sum").text(tot);
});
var total = 0;
$(".sum").each(function() {
total += isNaN($(this).text()) ? 0 : +$(this).text()
});
$("#tot").text(total);
return total;
}
$(".customs-table .remove:lt(1)").hide();
$(".vat-table .remove:lt(1)").hide();
$(".excise-table .remove:lt(1)").hide();
$("#formContainer").on("click", "button", function() {
var selector = "div.row";
var $div = $(this).closest(selector);
if ($(this).is(".add")) {
var $newDiv = $div.clone();
$newDiv.find(":input").val(""); // clear all
$newDiv.find("[type=number]").val(0); // clear numbers
$newDiv.find(".sum").text(0); // clear total
$newDiv.insertAfter($div)
}
else {
$div.remove();
sumIt();
}
$(".customs-table .remove:gt(0)").show();
$(".vat-table .remove:gt(0)").show();
$(".excise-table .remove:gt(0)").show();
});
$("#formContainer").on("input", "[type=number]", sumIt);
$("form").submit(function() {
event.preventDefault();
var user_profile = [];
$(".row").each(function() {
var $fields = $(this).find(":input");
if ($fields.length > 0) {
var cat = $(this).find("div>label").eq(0).text(); // use the label of the row
var catId = ["","Customs","VAT","Excise"].indexOf(cat)
user_profile.push({
assessmentType: "PRE",
assessCatID : catId,
assessReason: $fields.eq(0).val(),
assessAmount: $fields.eq(1).val(),
assessPenalty: $fields.eq(2).val(),
assessTotal: +$fields.eq(1).val() + +$fields.eq(2).val() // the leading + makes it a number
});
}
});
console.log(user_profile);
/*
$.ajax({
url: "someserverfunction",
data: JSON.encode(user_profile),
success : function(data) { }
error: function() { }
});
*/
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<form id="myForm">
<div id="formContainer" class="col-md-12" style="float: none;">
<!-- <button onclick="myFunction()" class="pull-right">+</button> -->
<div style="margin-bottom: 30px;">
<div class="form-group row">
<div class="col-md-1"></div>
<div class="col-md-4">
<label>Reason</label>
</div>
<div class="col-md-2">
<label>Amount</label>
</div>
<div class="col-md-2">
<label>Penalty</label>
</div>
<div class="col-md-1">Total</div>
<div class="col-md-2">Action</div>
</div>
<div class="customs-table row">
<div class="col-md-1">
<label>Customs</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control customReason" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt customAmount" value="0" name="abc" min="0" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt customPenalty" value="0" name="abc" min="0" />
</div>
<div class="col-md-1">
<span class="sum">0</span>
</div>
<div class="col-md-2">
<button type="button" class="add">+</button>
<button type="button" class="remove">-</button>
</div>
</div>
<div class="vat-table row">
<div class="col-md-1">
<label>VAT</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control vatReason" name="vatReason" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt1 vatAmount" value="0" name="vatAmount" min="0" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt1 vatPenalty" value="0" name="vatPenalty" min="0" />
</div>
<div class="col-md-1">
<span class="sum">0</span>
</div>
<div class="col-md-2">
<button type="button" class="add">+</button>
<button type="button" class="remove">-</button>
</div>
</div>
<div class="excise-table row">
<div class="col-md-1">
<label>Excise</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control exciseReason" name="exciseReason" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt2 exciseAmount" value="0" name="exciseAmount" min="0" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt2 excisePenalty" value="0" name="excisePenalty" min="0" />
</div>
<div class="col-md-1">
<span class="sum">0</span>
</div>
<div class="col-md-2">
<button type="button" class="add">+</button>
<button type="button" class="remove">-</button>
</div>
</div>
<div class="col-md-12 pull-right">
<label>Total:</label> <b><span id="tot">0</span></b>
</div>
</div>
<button type="submit" class="btn btn-success pull-right">Submit</button>
</div>
</form>