I used JavaScript to clone and add rows. How can separate validation be done for each row?
var i = 0;
function cloneRow() {
var row = document.getElementById("clone");
var table = document.getElementById("data");
var selectIndex = 1;
var clone = row.cloneNode(true);
table.appendChild(clone);
clone.setAttribute("style", "");
}
function deleteRow(btn) {
var result = confirm("Do you Want to delete this ?");
if (result) {
var row = btn.parentNode.parentNode;
row.parentNode.removeChild(row);
}
}
<div class="row">
<div class="col-sm-12">
<div class="col-sm-7"></div>
<div class="col-sm-2">
<button type="button"class="btn btn-primary default btn-xs" onclick="cloneRow()" >add more...</button>
</div>
</div>
</div><br><br>
<div class="row" id ="close">
<div class="col-sm-4"></div>
<div class='col-sm-4'>
<form id="NAME_VALUE" method="POST">
<table class="table-striped">
<tbody id="data">
<tr id ="clone" style="display:none;">
<td>
Name :<input type="text" name="INPUT_NAME" style="width:100px;" id="name" name="INPUT_NAME">
</td>
<td>
Value :<input type="text" name="INPUT_VALUE" style="width:100px;" id="value" name="INPUT_VALUE">
</td>
<td>
<button type="button"class="btn btn-primary default btn-xs" name ="delete" style="margin-left: 5px;" onclick="deleteRow(this); return false;">
<span class="glyphicon glyphicon-remove-circle" style="text-align:center" ></span>
</button>
</td>
</tr>
<tr>
<td>
Name :<input type="text" name="INPUT_NAME" style="width:100px;" id="name" name="INPUT_NAME">
</td>
<td>
Value :<input type="text" name="INPUT_VALUE" style="width:100px;" id="value" name="INPUT_VALUE">
</td>
<td>
<button type="button"class="btn btn-primary default btn-xs" name ="delete" style="margin-left: 5px;" onclick="deleteRow(this); return false;">
<span class="glyphicon glyphicon-remove-circle" style="text-align:center" ></span>
</button>
</td>
</tr>
</tbody>
</table><br>
<button type="button"class="btn btn-primary default btn-xs" style="margin-left: 5px;" onclick="submit_login(); return false;"> save.</button>
</form>
</div>
</div>
I'd like to create this type of validation for every row or <tr>.
When the add button is clicked a new input is dynamically added. However when the form is submitted only the first input field is validated. How can I validate the dynamically added inputs?
If you want to separate the validation for each row - you should create a row constructor.
Basically when you clone a new row - you clone the constructor with all its methods inside.
var Row = function () {
this.name = "";
this.value = "";
//add more properties
}
Create the methods:
Row.prototype.verify = function () {
return this.name !== `undefined` && this.value !== `undefined`;
}
In your clone function you just have to call it:
var rowInstance = new Row();
And you can use it like that:
if (rowInstance.verify()) {
//if the row information is valid then do something
}
Related
basically the objective of this request is to have a modal table that adds new table row/cells and pass the value of "var OBGyneID = $(this).attr("id"); " to first cell and value of "var billing_id = newID;" to second cell whenever new rows/cells is/are added. Seeking your help, thanks!
* MY MODAL*
<div id="myModal" class="modal fade card new-contact myModal" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="card profile">
<div class="profile__img">
<img src="img/profile2.jpg" alt="">
</div>
<div class="profile__info">
<h3 style="text-transform:capitalize;" id="pxname" name="pxname"></h3>
<ul class="icon-list">
<li>LAST <p name="consdates" id="consdates"></p></li>
<li>Last visit: </li>
<li><i class="zmdi zmdi-twitter"></i> #mallinda-hollaway</li>
</ul>
</div>
</div>
<div>
<div class="table-responsive">
<table id="billingTable" class="table table-inverse table-sm table-hover table-condensed" style="font-size:120%">
<thead>
<th>OBDYID</th>
<th>CK</th>
<th>PROCEEDURE</th>
<th>AMOUNT</th>
</thead>
<tbody id="billing_body" style="text-transform:capitalize;">
<form method="get" id="insert_form">
<tr>
<td width="10%"><input type="text" style="width:100%;" id="OBGyneID" name="OBGyneID"></td>
<td width="10%"><input type="text" style="width:100%;" id="AssessMentEntryID" name="AssessMentEntryID"></td>
<td width="60%"><input type="text" style="width:100%;" class="ExamDesc" type="text" id="ExamDesc" name="ExamDesc"></td>
<td width="20%"><input type="text" style="width:100%;" class="Price" type="text" id="Price" name="Price"></td>
</tr>
</form>
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<input type="submit" name="insert" id="insert" value="Insert" class="btn btn-success" />
<input type="submit" id="addRow" value="add" name="add" class="btn btn-info" />
<button type="button" class="btn btn-link" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
* MY JS to add new rows/cells*
$(document).ready(function () {
$("#addRow").click(function () {
$("#billingTable").append('<tr><td width="10%"><input type="text" style="width:100%;" id="OBGyneID" name="OBGyneID" ></td>'+
'<td width="10%"><input type="text" style="width:100%;" id="AssessMentEntryID" name="AssessMentEntryID"></td>'+
'<td width="60%"><input type="text" style="width:100%;" class="ExamDesc" type="text" id="ExamDesc" name="ExamDesc"></td>'+
'<td width="20%"><input type="text" style="width:100%;" class="Price" type="text" id="Price" name="Price"></td></tr>');
jQuery(".ExamDesc").autocomplete({
source: 'php/billingentry.php'
});
});
});
* Pass values to Modal * this will only pass value when modal pops-up but cant pass value whenever new rows/cells are added.
$(document).on('click', '.billing_data', function(){
var OBGyneID = $(this).attr("id");
var newID = new Date().getUTCMilliseconds();
var billing_id = newID;
$.ajax({
url:"php/billing_fetch.php",
method:"GET",
data:{OBGyneID: OBGyneID},
dataType:"json",
success:function(data){
$('#AssessMentEntryID').val(data.AssessMentEntryID);
$('#ExamDesc').val(data.ExamDesc);
$('#Price').val(data.Price);
$('#pxservice').val(data.pxservice);
$('#companyname').val(data.companyname);
$('#chiefcomplain').val(data.chiefcomplain);
document.getElementById("OBGyneID").value = OBGyneID;
document.getElementById("AssessMentEntryID").value = billing_id;
document.getElementById("pxname").innerHTML = (data.fname)+" "+(data.mi)+" "+(data.lname);
document.getElementById("consdates").innerHTML = (data.obgyneDate);
$('#myModal').modal('show');
}
});
});
whenever you are adding a new row HTML in billing table, you are using the same id for OBGyneID, AssessMentEntryID,ExamDesc and Price. And if you added two rows, DOM will not be able to work properly as there are multiple same ids out there. So I will suggest you to replace that with class and use class name to set values. Check below code:
$(document).ready(function () {
$("#addRow").click(function () {
$("#billingTable").append('<tr><td width="10%"><input type="text" style="width:100%;" class="OBGyneID" name="OBGyneID" ></td>'+
'<td width="10%"><input type="text" style="width:100%;" class="AssessMentEntryID" name="AssessMentEntryID"></td>'+
'<td width="60%"><input type="text" style="width:100%;" class="ExamDesc" type="text" name="ExamDesc"></td>'+
'<td width="20%"><input type="text" style="width:100%;" class="Price" type="text" name="Price"></td></tr>');
jQuery(".ExamDesc").autocomplete({
source: 'php/billingentry.php'
});
});
});
One you have added HTML code, then you can find out last row of billingTable and can set vales in that. Check below code:
$(document).on('click', '.billing_data', function(){
var OBGyneID = $(this).attr("id");
var newID = new Date().getUTCMilliseconds();
var billing_id = newID;
$.ajax({
url:"php/billing_fetch.php",
method:"GET",
data:{OBGyneID: OBGyneID},
dataType:"json",
success:function(data){
$("#billingTable").find(".AssessMentEntryID:last").val(data.AssessMentEntryID);
$("#billingTable").find(".ExamDesc:last").val(data.ExamDesc);
$("#Price").find(".Price:last").val(data.Price);
$("#billingTable").find(".consdates:last").html(data.obgyneDate);
//and so on
$('#myModal').modal('show');
}
});
});
Also, I would suggest you to use HTMl template tag for making clone for row. Appending HTML in JS is not a recommended way. Hope it helps you.
I have created a textbox that has a "+" (Add button) and a "-" (delete button) . And when i click on + , i get one more text-box . And when i click on - , i delete that textbox with its value. To capture the value of the text-box , i use ngModel. I tried it without using a Form. Here the issues i am facing are -
[1.]
When i click on '+' button, i get the textbox successfully and i get its value also. But for subsequent additions when done using "+' button, i get the same value . And when i change its value, the value changes on every other text box done using " + " button.
[2.] I don't know how to delete the value of the text-box from the array-variable.
Please help
code -
app.component.html
<div *ngIf="addContainer">
<p style="margin-left: 200px; font-size:18px">Please enter the API
Object -</p>
<table align="center">
<tbody>
<tr >
<td >
<input type="text" placeholder="Enter a Node" [(ngModel)]= "firstValue">
</td>
<td >
<button type="button" style="margin-left: 10px" (click)="addOne(firstValue)" class="btn btn-success"> + </button>
</td>
<td>
<button type="button" style="margin-left: 10px" (click)="deleteOneMore()" class="btn btn-danger"> - </button>
</td>
</tr>
<tr *ngFor="let container of containers; let i = index;" #myElement>
<ng-container >
<td id="1myElement">
<input *ngIf="addMore" type="text" placeholder="Enter a Node" [(ngModel)]= "addedValue">
</td>
<td id="1myElement">
<button type="button" style="margin-left: 10px" (click)="addOneMore($event)" class="btn btn-success"> + </button>
</td>
<td>
<button type="button" style="margin-left: 10px" (click)="deleteOneMore()" class="btn btn-danger"> - </button>
</td>
</ng-container>
</tr>
<tr>
<td style="text-align:center">
<button type="button" (click)="showGraphs(firstValue,addedValue)" class="btn btn-dark">Search</button>
</td>
</tr>
</tbody>
</table>
</div>
app.component.ts
addOne(firstDropdValue) {
console.log("inside addOne = firstDropdValue = ",
firstDropdValue);
this.addMore = true;
this.containers.push(this.containers.length);
}
addOneMore(addedValue)
{
this.moreValues.push(addedValue);
console.log("Inside AddOneMore More Values = ",
this.moreValues);
}
deleteOneMore(){
this.containers.splice(this.index, 1);
}
showGraphs(firstV, addedV) {
console.log("inside showGraphs()");
console.log("firstValue =", firstV, "addedValue = ", addedV);
this.showEwayBill = true;
this.showCollection = true;
this.EwayBill();
this.Collection();
}
Image -
You should maintain an array for the newly added values like below and your add and remove should look like below
values = ["sometext"];
addOneMore() {
this.values.push("sivakumar");
}
deleteOneMore(index) {
this.values.splice(index, 1);
}
In the template file you can use that values or containers array to loop like below
<table>
<tr>
<td>
<input type="" [(ngModel)]='values[0]'>
</td>
<td>
<button type="button" style="margin-left: 10px" (click)="addOneMore(firstValue)" class="btn btn-success"> + </button>
</td>
<td>
<button type="button" style="margin-left: 10px" (click)="deleteOneMore(i)" class="btn btn-danger"> - </button>
</td>
</tr>
<ng-container *ngFor="let value of values; let i = index;">
<tr *ngIf="i > 0">
<td id="1myElement">
<input type="text" placeholder="Enter a Node" [(ngModel)]="values[i]">
</td>
<td id="1myElement">
<button type="button" style="margin-left: 10px" (click)="addOneMore()" class="btn btn-success"> + </button>
</td>
<td>
<button type="button" style="margin-left: 10px" (click)="deleteOneMore(i)" class="btn btn-danger"> - </button>
</td>
</tr>
</ng-container>
</table>
But, in this solution, still there is one issue that, in the textbox, we are allowing to enter one word at a time, I am not able to figure it out the reason, if anyone can, welcoming you to edit the answer ;-)
Working stackblitz is here
I am doing an exercise to learn JavaScript. I am having issues making my program dynamic. What I want to do here is:
Create two input to let the user set up the new product data.
Create a button. This button will have assigned a click event that will: 1- Get the data from the inputs. 2- Create a new product row with the data we stored.
Be able to delete all items and decrease total price based on the price of reminding item. In case there is no item, total price should be 0.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Shoping</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="js/index.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<header>
<h1 class="h1 text-center mb">Shoping<span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span></h1>
</header>
<table class="table mb">
<thead>
<tr>
<th>Products:</th>
<th>Price:</th>
<th>Quantity:</th>
<th>Total:</th>
<th>
</th>
</tr>
</thead>
<tbody id="soyTBody">
<tr id="itemSubject">
<th scope="row"><span id="productName">T-Shirts</span></th>
<td class="price1"> <span class="dolar">$</span><span id="product">15</span></td>
<td class="qty1">
<form class="form-inline">
<div class="form-group">
<label for="inputQty">QTY</label>
<input type="text" id="qty" class="form-control mx-sm-3" maxlength="3" aria-describedby="qtyItem1">
</div>
</form>
</td>
<td <span class="dolar">$</span><span id="total">0.00</span></td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" onclick="removeItem()" value="delate">
<input id ="delateButton" class="delateItem" type="button" value="Delate">
</button>
</td>
</tr>
<tr id="itemSubject2">
<th scope="row"><span id="productName">Stickers</span></th>
<td class="price2"> <span class="dolar">$</span><span id="product2">2</span></td>
<td class="qty2">
<form class="form-inline">
<div class="form-group">
<label for="inputQty">QTY</label>
<input type="text" id="qty2" class="form-control mx-sm-3" maxlength="3" aria-describedby="qtyItem2">
</div>
</form>
</td>
<td <span class="dolar">$</span><span id="total2">0.00</span></td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" onclick="removeItem2()" value="delate">
<input id ="delateButton" class="delateItem" type="button" value="Delate">
</button>
</td>
</tr>
<!-- <tr>
<th scope="row">Stickers</th>
<td class="price2">$1</td>
<td class="qty2">
<form class="form-inline">
<div class="form-group">
<label for="inputPassword4">QTY</label>
<input type="text" id="qty2text" class="form-control mx-sm-3" aria-describedby="passwordHelpInline">
</div>
</form>
</td>
<td class="total-2">$0.00</td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" value="delate">
<span class="delateButton"><strong>Delate</strong></span>
</button>
</td>
</tr> -->
<!-- <tr>
<th scope="row">Flags</th>
<td class="price3">$2</td>
<td class="qty3"><form class="form-inline">
<div class="form-group">
<label for="inputPassword4">QTY</label>
<input type="text" id="qty3text" class="form-control mx-sm-3" aria-describedby="passwordHelpInline">
</div>
</form>
</td>
<td class="total3">$0.00</td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" value="delate">
<span class="delateButton"><strong>Delate</strong></span>
</button>
</td>
</tr> -->
</tbody>
</table>
<div class="row text-right">
<button class="delate btn btn-success" onclick="getPrice();getPrice2();totalPrice2()" type="submit" value="calculatePriceButton" >
<input id ="calc-prices-button" class="calculator" type="button" value="Calculate Prices">
<!-- <span class="delateButton"><strong>Calculate Prices</strong></span> -->
</button>
</div>
<h2 class="text-center">Total Price: $<span id="totalPrice"></span></h2>
</div>
</body>
</html>
JS:
// qty
function getQty() {
var qty = document.querySelector("#qty").value;
document.querySelector("#total").innerHTML = qty;
return qty;
}
getQty();
// qty2
function getQty2() {
var qty2 = document.querySelector("#qty2").value;
document.querySelector("#total2").innerHTML = qty2;
return qty2;
}
getQty();
// Price
function getPrice() {
var price = parseInt(document.querySelector("#product").innerHTML);
document.querySelector("#total").innerHTML = price * getQty();
}
getPrice();
// Price 2
function getPrice2() {
var price2 = parseInt(document.querySelector("#product2").innerHTML);
document.querySelector("#total2").innerHTML = price2 * getQty2();
}
getPrice2();
// total Price
function totalPrice2() {
var total = parseInt(document.querySelector("#total").innerHTML);
var total2 = parseInt(document.querySelector("#total2").innerHTML);
document.querySelector("#totalPrice").innerHTML = total + total2;
}
totalPrice2();
//Romove Item
function removeItem() {
var remove = document.querySelector("#itemSubject").remove("itemSubject");
// setTimeout(function() { alert("Your shopping cart is empty"); }, 1000);
}
removeItem();
function removeItem2() {
var remove = document.querySelector("#itemSubject2").remove("itemSubject2");
// setTimeout(function() { alert("Your shopping cart is empty"); }, 1000);
}
removeItem2();
For your getPrice() and getPrice2() functions, we can make them dynamic by changing the following:
var price = parseInt(document.querySelector("#product").innerHTML);
and
var price2 = parseInt(document.querySelector("#product2").innerHTML);
These lines looks for elements with static names, instead we should give all inputs a common class name and loop through them. That way, we don't have to rely on static element IDs. For example, if we gave each input the class 'quantityinput', we can do the following:
var elements = document.getElementsByClassName("quantityinput");
for(var i=0; i<elements.length; i++) {
// Select this element and get its quantity
var this_total = elements[i].value;
// Get the price for this element by selecting the price td, then its second child
var this_price = elements[i].parentElement.parentElement.parentElement.previousSibling.childNodes[2].value;
// Select the total label for this row
var this_total_label = elements[i].parentElement.parentElement.parentElement.childNodes[1];
// Now update the total label for this row by multiplying the price and the quantity
this_total_label.value = this_total * this_price;
}
Now we don't have to worry about a certain row missing, since we iterate through all existing rows. A similar approach can be taken when calculating the total price for all rows, just loop through each rows total price, add them together then assign the total to the total price label.
how can do separate validation in each row in java script i used in clone for add more function but i can't do validation for every row.how is this ?
help me
var i = 0;
function cloneRow() {
var row = document.getElementById("clone");
var table = document.getElementById("data");
var selectIndex = 1;
var clone = row.cloneNode(true);
table.appendChild(clone);
clone.setAttribute("style", "");
}
function deleteRow(btn) {
var result = confirm("Do you Want to delete this ?");
if (result) {
var row = btn.parentNode.parentNode;
row.parentNode.removeChild(row);
}
}
<div class="row">
<div class="col-sm-12">
<div class="col-sm-7"></div>
<div class="col-sm-2">
<button type="button"class="btn btn-primary default btn-xs" onclick="cloneRow()" >add more...</button>
</div>
</div>
</div><br><br>
<div class="row" id ="close">
<div class="col-sm-4"></div>
<div class='col-sm-4'>
<Form id="NAME_VALUE" method="POST" >
<table class="table-striped" >
<tbody id="data">
<tr id ="clone" style="display:none;">
<td>
Name :<input type="text" name="INPUT_NAME" style="width:100px;" id="name" name="INPUT_NAME">
</td>
<td>
Value :<input type="text" name="INPUT_VALUE" style="width:100px;" id="value" name="INPUT_VALUE">
</td>
<td>
<button type="button"class="btn btn-primary default btn-xs" name ="delete" style="margin-left: 5px;" onclick="deleteRow(this);
return false;">
<span class="glyphicon glyphicon-remove-circle" style="text-align:center" ></span></button>
</td>
</tr>
<tr>
<td>
Name :<input type="text" name="INPUT_NAME" style="width:100px;" id="name" name="INPUT_NAME">
</td>
<td>
Value :<input type="text" name="INPUT_VALUE" style="width:100px;" id="value" name="INPUT_VALUE">
</td>
<td>
<button type="button"class="btn btn-primary default btn-xs" name ="delete" style="margin-left: 5px;" onclick="deleteRow(this);
return false;">
<span class="glyphicon glyphicon-remove-circle" style="text-align:center" ></span></button>
</td>
</tr>
</tbody>
</table><br>
<button type="button"class="btn btn-primary default btn-xs" style="margin-left: 5px;" onclick="submit_login();
return false;"> save.</button>
</Form>
</div>
</div>
$(document).ready($.validator.addMethod("valueNotEquals", function (value, element, arg) {
return arg != value;
},
"Value must not equal arg."));
$(function () {
$("#NAME_VALUE").validate({
errorClass: "validation-error-class",
// Specify the validation rules
rules: {
INPUT_NAME: {
required: true,
maxlength: 64
},
INPUT_VALUE: {
required: true,
maxlength: 64
}
},
// Specify the validation error messages
messages: {
INPUT_NAME: {
required: "[your name ?]",
maxlength: "[Your name cannot exceed 64 characters]"
},
INPUT_VALUE: {
required: "[ value ?]",
maxlength: "[Your password cannot exceed 64 characters]"
}
},
errorElement: "div",
wrapper: "div",
errorPlacement: function (error, element) {
error.appendTo(element.parent("td"));
error.css('color', 'red');
error.css('text-align', 'center');
}
});
});
function submit_login( )
{
if ($("[id='name'],[id='value']").valid()) {
alert("Successfully saved");
}
}
i like to create this type of validation every row or tr so please help me..]1]1
i put this one but if i write in one text field every validation gone..
I have a form with 2 fields with an add row button. When this button is clicked it simply clones the row and adds another row consisting of the 2 form fields. How do I save these newly added fields in my ajax post? Right now, it only ever saves the last row in my form.
<form action="." method="post">
<table class="table table-condensed" id="pa">
<thead>
<tr>
<th class="col-xs-2">Description</th>
<th class="col-xs-2">Expected %</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="form-group">
<input class="text-box single-line" data-val="true" data-val-required="The Description field is required." id="Description" name="Description" value="" type="text">
</div>
</td>
<td>
<div class="form-group">
<div class="input-group">
<input class="text-box single-line" data-val="true" data-val-number="The field Expected must be a number." id="Expected" name="Expected" value="100" type="number">
</div>
</div>
</td>
<td class="vert-align"> <a class="btn btn-danger btn-xs remove-row-pa">x</a>
</td>
</tr>
</tbody>
</table>
<div class="pull-right">
<p> <a href="#" id="add-pa-row" class="btn btn-success btn-xs">
<i class="fa fa-plus-circle"></i> Add row
</a>
</p>
</div>
<div class="form-group">
<p>
<input value="Save" class="btn btn-success" type="submit">
</p>
</div>
</form>
function Qs2Dict(qs) {
var pairs = qs.split('&');
var dict = {};
pairs.forEach(function (pair) {
var kv = pair.split('=');
dict[kv[0]] = decodeURIComponent(kv[1].replace(/\+/g, "%20"));
});
return dict;
}
// Add row
$("#add-row").click(function () {
$('#pa tbody>tr:last').clone(true).insertAfter('#pa tbody>tr:last');
$('#pa tbody>tr:last #Description').val('');
$('#pa tbody>tr:last #Expected').val('');
return false;
});
$('#modal').click(function (e) {
e.preventDefault();
var url = $(this).data('url');
var data = $('form').serialize();
var dict = Qs2Dict(data);
$.ajax({
type: "POST",
url: url,
data: {
"Description": dict.Description,
"EffectiveDate": dict.EffectiveDate,
"Expected": dict.Expected,
},
success: function (result) {},
});
});
Change their name attribute, since it defines/enumerates the fields to save.
If they are equal, which they are if you clone, only the last one is taken.
Or use arrays i.e. name="Expected[]"
EDIT: more specifically: I assume they get "lost" due to above reason during $('form').serialize();