I'm a little new to JQuery but I seem to be running into a challenge with cross-browser functionality. I have the following code inserted at the head of the form:
<script>
$(document).ready(function(){
/*wraps the action field in the Completed div with link to section*/
$('input[id^="tfa_5660"]').val(function(i,origText) {
$(this).wrap('Review this section');
return "";
});
/*wraps the action field in the To-Do div with link to section*/
$('input[id^="tfa_5714"]').val(function(i,origText) {
$(this).wrap('Start this section');
return "";
});
});
</script>
The jQuery function works on Chrome and Safari, but when I test it on Firefox, rather than wrapping it with the link from the input value it wraps the input with the url of the page itself. Any idea what might be causing the issues with Firefox but not Chrome or Safari?
See below for screenshots demonstrating the issue
Firefox:
Screenshot of Firefox not working
Below is the HTML of the form itself, generated by a WYSIWYG form editor called Form Assembly
<div class="htmlSection" id="tfa_5655"><div class="htmlContent" id="tfa_5655-HTML">Below is a list of the sections you've already completed.</div></div>
<table class="gridLayout ">
<thead><tr class="headerRow">
<th scope="col" id="tfa_5657[0]-GRID" class="">Section </th>
<th scope="col" id="tfa_5658[0]-GRID" class=""><b>Description</b> </th>
<th scope="col" id="tfa_5659[0]-GRID" class=""><b>Due Date</b> </th>
<th scope="col" id="tfa_5660[0]-GRID" class=""><b>Action </b> </th>
<th scope="col" id="tfa_5661[0]-GRID" class=" wf-acl-hidden">Click here to name this section </th>
</tr></thead>
<tbody>
<tr id="tfa_5656[0]" class="section repeat alternate-0 " data-repeatlabel=" ">
<td class=""><div class="oneField field-container-D " id="tfa_5657-D[0]"><div class="inputWrapper"><input type="text" id="tfa_5657[0]" name="tfa_5657[0]" value="Contact Information" placeholder="" default="Contact Information" readonly title="Section " class="readonly"></div></div></td>
<td class=""><div class="oneField field-container-D " id="tfa_5658-D[0]"><div class="inputWrapper"><textarea id="tfa_5658[0]" name="tfa_5658[0]" readonly title="Description " class="readonly">Tell us about yourself</textarea></div></div></td>
<td class=""><div class="oneField field-container-D " id="tfa_5659-D[0]"><div class="inputWrapper"><input type="text" id="tfa_5659[0]" name="tfa_5659[0]" value="" placeholder="" readonly title="Due Date " class="readonly"></div></div></td>
<td class=""><div class="oneField field-container-D " id="tfa_5660-D[0]"><div class="inputWrapper"><input type="text" id="tfa_5660[0]" name="tfa_5660[0]" value="" placeholder="" readonly title="Action " class="formula=LinkReview+IDReview readonly"></div></div></td>
<td class=" wf-acl-hidden"><fieldset id="tfa_5661[0]" class="section wf-acl-hidden">
<legend id="tfa_5661[0]-L">Click here to name this section </legend>
<div class="oneField field-container-D " id="tfa_5662-D[0]">
<label id="tfa_5662[0]-L" for="tfa_5662[0]" class="label preField "><b>ID</b> </label><br><div class="inputWrapper"><input type="text" id="tfa_5662[0]" name="tfa_5662[0]" value="00To000001mtE3aEAE" placeholder="" default="00To000001mtE3aEAE" readonly title="ID " class="calc-IDReview readonly"></div>
</div>
<div class="oneField field-container-D " id="tfa_5663-D[0]">
<label id="tfa_5663[0]-L" for="tfa_5663[0]" class="label preField "><b>Link</b> </label><br><div class="inputWrapper"><input type="text" id="tfa_5663[0]" name="tfa_5663[0]" value="https://www.tfaforms.com/4605490?what_id=" placeholder="" default="https://www.tfaforms.com/4605490?what_id=" readonly title="Link " class="calc-LinkReview readonly"></div>
</div>
Here is a link to the form itself, realized I probably should have included this from the start: https://www.tfaforms.com/4605382?contact_id=003o000000v6WOF
Related
So this is a kind of follow up to another post I made earlier, I have this application I'm working on where I have a dynamic html form, where a user can add and remove rows. I am trying to come up with a way to capture this data when the user posts it, but I am falling short on how to do this. My idea right now is to capture a JavaScript variable from the html page that keeps track of row numbers, and capture the one row at a time, parse the row for an email, then send it to my function. Where I'm at a loss is how to capture the JavaScript variable, and from there how to I separate the rows into separate objects and loop through them. If someone can direct me towards resources that can help me resolve this or if someone can point me in the right direction, I would highly appreciate it! Please find below the html for the dynamic form, the JavaScript with this form and the post mapping for the page (the code for the post mapping is incomplete, this is really where I need aid). Thank you all in advance for any and all help!!!!
<form th:action="#{/patienthome/contact-trace-report}" method="post">
<div class="card shadow border-start-primary py-2" data-bss-hover-animate="" style="width: auto;height: auto; margin-bottom:50px;">
<div class="form-group mb-3">
<div id="formdiv-1">
<div class="row" style="margin-right:0px;margin-left:0px;padding-top:24px;">
<div class="col-md-8 offset-md-1" style="padding-right: 0px;padding-left: 0px;margin-left: 27.828px;">
<p style="margin-left: 2%;font-family: Roboto, sans-serif;font-size: 47px;text-align: left;"><strong>Contacted Individuals</strong></p>
</div>
</div>
<!-- Here html for addeable rows -->
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-bordered table-hover" id="tab_logic">
<thead>
<tr >
<th class="text-center">
#
</th>
<th class="text-center">
First Name
</th>
<th class="text-center">
Last Name
</th>
<th class="text-center">
Email
</tr>
</thead>
<tbody>
<tr id='addr0'>
<td>
1
</td>
<td>
<input type="text" name='firstName' placeholder='First Name' class="form-control"/>
</td>
<td>
<input type="text" name='lastName' placeholder='Last Name' class="form-control"/>
</td>
<td>
<input type="text" name='email' placeholder='Email Adress' class="form-control"/>
</td>
</tr>
<tr id='addr1'></tr>
</tbody>
</table>
</div>
</div>
<a id="add_row" class="btn btn-default pull-left">Add Row</a>
<a id='delete_row' class="pull-right btn btn-default">Delete Row</a>
</div>
<!-- Here is end of html for addeable rows -->
<div class="row d-md-flex d-xxl-flex justify-content-md-center align-items-md-center justify-content-xxl-center align-items-xxl-center" style="margin-right: 0px;margin-left: 0px;padding-top: 24px;width: auto;">
<div class="col-12 col-md-4 offset-md-4 d-xxl-flex justify-content-xxl-center align-items-xxl-center" style="width: auto;margin-left: 0;padding-left: 0;padding-right: 0px;"><button class="btn btn-light btn-lg text-center d-xxl-flex justify-content-xxl-center align-items-xxl-center" style="margin-left: 0px;width: auto;height: auto;color: rgb(255,252,252);background: rgb(231,74,59);" type="submit">Submit </button></div>
</div>
</div>
</div>
</div>
</form>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js">
</script>
<script>
var i=1;
$(document).ready(function(e){
$("#add_row").click(function()
{
$('#addr'+i).html("<td>"+ (i+1) +"</td><td><input name='firstName"+i+"' type='text' placeholder='First Name' class='form-control input-md' /></td><td><input name='lastName"+i+"' type='text' placeholder='Last Name' class='form-control input-md'></td><td><input name='email"+i+"' type='text' placeholder='Email Address' class='form-control input-md'></td>");
$('#tab_logic').append('<tr id="addr'+(i+1)+'"></tr>');
i++;
})});
$(document).ready(function(e){
$("#delete_row").click(function()
{
if(i>1)
{
$("#addr"+(i-1)).html('');
i--;
}
})});
</script>
//Post Mapping Contract Trace Report
#PostMapping("/patienthome/contact-trace-report")
public ModelAndView contractTraceReportPost(ModelAndView modelAndView, User user, #RequestParam String email, #RequestParam String firstName, #RequestParam String lastName ) throws IOException, ParseException
{
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Patient patient = patientRepo.findByEmail(authentication.getName());
//Will capture variable i from javascript so we know how many rows to capture
//Will try to capture rows as an object, then parse the email from the row
//Will then use the email to find the patient object and send it tot he list
while(i>0)
{
//capturing row as Object
//Parsing Row for email
//Need to capture as many emails as there are rows
Patient contact =patientRepo.findByEmail(email);
//Will add the user to the list
patient.addContactTraceFrom(contact);
i--;
}
modelAndView = new ModelAndView("redirect:/patienthome");
modelAndView.addObject("confirmationMessage", "Patient Profile Was Updated");
return modelAndView;
}
I am builing an invoice where user can enter the product and its quantity. Once the user checks the warranty fields should be populate for entry of sku.
for eg: if checks the warranty and there is 10 quantity for products, user should be able enter 10 sku
I am stuck in a section where I would like get the sku for the products. I can get sku in each row but I would like to
get it as an array and map it to corresponding row id, so that I an keep the invoice simple.
I have tried several methods, but unfortunately none seem to work,
Try 1: Used Checkbox as identifier to display the input field for entry,
Issue: The checkbox isn't sending the value of unchecked box,
so I am getting mismatch of the array result
Try 2: Tried DropDown,
Issue: was not able to bind the element to
particular dropdown. Also the dropdown is acting weird.
While Searching internet, I cannot find any reference of my model. Am I reinventing the wheel or stick to old style ?
//Intiate the dropdown
$('select').formSelect();
$(function() {
var i = 1;
$("#add_row").on("click", function(e) {
e.preventDefault();
b = i - 1;
$("#addr" + i).html($("#addr" + b).html());
$(".tab_logic").append('<tr id="addr' + (i + 1) + '"></tr>');
i++;
warrantyDetails();
$('select').formSelect();
});
$("#delete_row").click(function() {
if (i > 1) {
$("#addr" + (i - 1)).html("");
i--;
}
});
});
function warrantyDetails() {
$('.warrantyonClick, .warranty').on('change', function() {
console.log(this);
var warranty = $('.warranty').find(":selected").val();
if (warranty == 1) {
console.log(this);
$(this).find(".warranty_details").show();
$(this).formSelect();
} else {
$(this).find(".warranty_details").hide();
}
});
}
// I am unable to bind the element because the this points to .waaranty and the .warrantyonClick is outside of the parent.
// Also I am unable to populate the fields based on the quantity
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<table class="tab_logic" id="tab_logic">
<thead class="orange ">
<tr>
<th>
Product Name
</th>
<th>
HSN Code
</th>
<th class="center">
GST
</th>
<th>
Quantity
</th>
<th>
Rate(per Nos)
</th>
<th>
Warranty
</th>
<th>
Amount
</th>
</tr>
</thead>
<tbody id="tab_logic_body">
<tr id='addr0' class="addr0">
<td>
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<input type="text" class="product_name autocomplete" placeholder="Product Name">
<input type="hidden" name="product_id[]" class="product_id">
</div>
</div>
</div>
</td>
<td>
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<input type="text" class="hsn_code autocomplete" placeholder="HSN Code">
<input type="hidden" name="hsn_code_id[]" class="hsn_code_id">
</div>
</div>
</div>
</td>
<td>
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<input type="text" class="gst autocomplete" placeholder="GST" name="gst[]" readonly="readonly">
<input type="hidden" class="gst_price">
</div>
</div>
</div>
</td>
<td>
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<input type="number" name='quantity[]' placeholder='Enter Qty' class="form-control qty" step="0" min="0" required />
</div>
</div>
</div>
</td>
<td>
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<input type="number" name='product_price[]' placeholder='Enter Price' class="form-control product_price" step="0" min="0" required />
</div>
</div>
</div>
</td>
<td class="warrantyonClick">
<div class="row">
<div class="input-field col s12">
<select class="warranty no-autoinit" name="warranty[]">
<option value="1">Yes</option>
<option value="0" selected>No</option>
</select>
</div>
</div>
<div class="warranty_details" style="display:none">
<input type="text" name='sku[]' placeholder='Serial No' class="form-control sku" />
<input type="number" name='sku_warranty_time[]' placeholder='Time Period' class="form-control sku_warranty_time" />
</div>
</td>
<td>
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<input type="number" name='row_total_amount[]' placeholder='Total Amount' class="form-control row_total_amount" step="0" min="0" readonly="readonly" />
</div>
</div>
</div>
</td>
</tr>
<tr id='addr1' class="addr1"></tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>
<th class="right">
<button type="button" class="btn z-depth-1" id="add_row"><i
class="material-icons">add_box</i>
</button>
<button type="button" class="btn z-depth-1 red" id="delete_row"><i
class="material-icons">remove</i> </button>
</th>
</th>
</tr>
</thead>
</table>
I need to create multiple groups in the form. when i create a childgroup and enter an input value the same value reflect in another group i known this is due to ngModel but how to overcome this issue. there is another issue i am facing under childGroup there is 2 table when i create another childGroup and add a new table row to that childGroup this will reflect in another childGroup also.
HTML
<fieldset *ngFor="let task of tasks; let a = index">
<legend>childGroup</legend>
<button (click)="deleteRow(a)" class="btn btn-sm btn-circle btn-danger actionMargin rmv-btn">X</button>
<div class="row">
<section class="col col-6">
<label class="label">Name</label>
<label class="input">
<input type="text" class="input-sm" [(ngModel)]="task.Name" name="task[a].Name" required>
</label>
</section>
<section class="col col-6">
<label class="label">Comm</label>
<label class="input">
<input type="text" class="input-sm" [(ngModel)]="task.Config.command" name="task[a].Config.command" required>
</label>
</section>
</div>
<!--Table-->
<section>
<h2>ABC</h2>
<table class="table table-bordered">
<thead>
<tr>
<th class="name">S no.</th>
<th class="name">Label</th>
<th class="name">Value</th>
<th class="name">Dynamic</th>
<th class="name">Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of task.ports; let i = index">
<td align="center"><label>{{i + 1}}</label></td>
<td><input type="text" [(ngModel)]="item.Label" name="item[i].Label" [ngModelOptions]="{standalone: true}"
class="inputborder" required></td>
<td><input type="number" [disabled]="item[i].boolean" [(ngModel)]="item[i].Value" name="item.Value"
[ngModelOptions]="{standalone: true}" class="inputborder" required></td>
<td><input type="checkbox" [(ngModel)]="item[i].boolean" name="item[i].boolean" class="check"
[ngModelOptions]="{standalone: true}" required><span class="yes">Yes</span></td>
<td align="center"><button (click)="deleteRow(i,'port')" placement="top" tooltip="Remove Port" class="btn btn-sm btn-circle btn-danger actionMargin rmv-btn">X</button></td>
</tr>
</tbody>
</table>
<button type="button" (click)="Addrow('port')" placement="top" tooltip="Add Port" class="btn btn-sm btn-primary posi">Add
abc</button>
</section>
</fieldset>
TS.
tasks= [];
taskObj = { //click on a blue + button i am pushing this object to tasks
Name: "",
Config: {
command: ""
},
artifacts : [],
ports : []
};
// to add a table row
Addrow(i) {
if (i == 'port') {
let num = 0;
this.taskObj.ports.push({
Label: '',
Value: num,
boolean: true
});
} else {
this.taskObj.artifacts.push({
Source: '',
Relative: ''
})
}
console.log(this.tasks);
}
//remove the table row
deleteRow(index, i) {
if (i == "port") {
this.taskObj.ports.splice(index, 1);
} else {
this.taskObj.artifacts.splice(index, 1);
}
}
I the HTML code i have not add 'XYZ' table code because its same as 'ABC' table. how to implement validation to this loop within loop. Please help me with this issue.
I have a page with two radio buttons. One radio button is checked by default but if the other radio button is checked, without pressing a button, I want the header in my table to change.
Here are some snippets:
<table class="table table-sm table-secondary" style="margin-bottom: 0">
<thead style="background-color: #cb5797">
<tr>
<th scope="col" class="text-center">Duration (min)</th>
<th scope="col" class="text-center hideme" data-period="outdoor">
Speed1
</th>
<th scope="col" class="text-center">Incline (%)</th>
</tr>
</thead>
</table>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-secondary active">
<input
type="radio"
name="environment"
id="indoor"
value="indoor"
checked="checked"
/>
Indoor
</label>
<label class="btn btn-secondary">
<input type="radio" name="environment" id="outdoor" value="outdoor" />
Outdoor
</label>
</div>
I have tried to get this example to work but was not successful
Show/hide DIV based on selected with data-toggle="buttons" input radio button bootstrap 3
FYI, I'm new to javascript, therefore please provide plenty of details with your answer.
Every radio button (or checkbox) has an event called onchange. For radiobuttons and checkboxes, the onchange event occurs when the checked state has been changed. You can create two functions and add them as in the snippet below.
Since your table header has the data-period="outdoor" attribute, I'm guessing this is what you want to change. This can be done using the getElementById and setAttribute functions. I also added a bit of code to change the header background-color, for learning purposes.
function toggleIndoor() {
console.log("toggleIndoor changed!");
// Change the header data-period attribute
var headerCell = document.getElementById("tochange");
headerCell.setAttribute("data-period", "indoor");
printHeaderDataPeriod();
// Change the header color
var tableHeader = document.getElementById("table-head");
tableHeader.style.backgroundColor = "#cb5797";
}
function toggleOutdoor() {
console.log("toggleOutdoor changed!");
var headerCell = document.getElementById("tochange");
headerCell.setAttribute("data-period", "outdoor");
printHeaderDataPeriod();
// Change the header color
var tableHeader = document.getElementById("table-head");
tableHeader.style.backgroundColor = "#aa00bb";
}
function printHeaderDataPeriod() {
var headerCell = document.getElementById("tochange");
var headerAttr = headerCell.getAttribute("data-period");
console.log("Table has data-period: " + headerAttr);
}
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-secondary active">
<input type="radio" name="environment" id="indoor" value="indoor" checked="checked" onchange="toggleIndoor()"> Indoor
</label>
<label class="btn btn-secondary">
<input type="radio" name="environment" id="outdoor" value="outdoor" onchange="toggleOutdoor()"> Outdoor
</label>
</div>
<table class="table table-sm table-secondary" style="margin-bottom: 0">
<thead style="background-color: #cb5797" id="table-head">
<tr>
<th scope="col" class="text-center">Duration (min)</th>
<th scope="col" class="text-center hideme" data-period="outdoor" id="tochange">Speed1</th>
<th scope="col" class="text-center">Incline (%)</th>
</tr>
</thead>
</table>
If you want to change the header style (color, size etc.), it can be easily done using the setAttribute function or doing element.style.<css-property-name> = <value>, once you got your element by class or by id. Stack overflow has thousands of question like this, about triggering or changing element properties using java-script.
Cheers!
I'm new to AngularJs and I'm stuck in multi ng-repeat.
HTML CODE
<table class="table table-bordered tdPaddingNull verTop">
<thead>
<tr>
<th width="200px">Product Details </th>
<th width="250px">Current Availability</th>
<th width="200px">Batch </th>
<th>Quantity</th>
<th>Rate INR </th>
<th>Amt. INR</th>
<th>Converted Amount</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(i,product) in listproducts track by $index">
<td style="padding: 7px;">
<input auto-complete ui-items="prductdetail" ng-model="formData.product_name[i]" class="form-control form-white" my-id="{{i}}"/>
<input id="product_id{{i}}" placeholder="productid" type="hidden" value="" ng-model="formData.product_id[i]" my-id="{{i}}"/>
<a ng-click="addProductBatch()" title="Add Another Batch Quantity" style="float:right;"><i class="fa fa-plus" aria-hidden="true"></i> ADD BATCH </a>
</td>
<td class="line-item-column item-currentavail transferorder-lineitem">
<div class="row text-muted font-sm">
<div class="col-md-6">
Source Stock
</div>
<div class="separationline col-md-6">
Destination Stock
</div>
</div>
<div class="row font-xs">
<div class="col-md-6">
0.00 Units
</div>
<div class="separationline col-md-6">
0.00 Units
</div>
</div>
</td>
<td style="padding: 7px;">
<div style="display:inline-block;width:100%;" ng-repeat="addBatch in listAddbatches">
<select class="form-control form-white selectNor" ng-model="formData.batch_id[i]" ng-change="changedBatchValue(formData.batch_id)" style="margin-bottom: 5px;width: 88%;float: left;">
<option value="">Select Batch</option>
<option value="{{blist.batch_id}}" ng-repeat="blist in batchList">{{blist.batch_number}}</option>
</select>
<a class="inputTabel1" ng-click="removeBatch($index)" title="Remove Batch" style="float:left;margin-left: 4px;"> <i class="fa fa-times-circle-o" aria-hidden="true" ></i>
</a>
</div>
</td>
<td style="padding: 7px;">
<input class="form-control form-white" type="text" value="" ng-model="formData.product_count[i]" ng-repeat="addBatch in listAddbatches" style="margin-bottom: 5px;"/>
</td>
<td style="padding: 7px;">
<input class="form-control form-white " placeholder="Selling Price" type="text" value="0.00" ng-model="formData.sel_inr_rate[i]">
</td>
<td>
<input class="form-control form-white form-Tabel" placeholder="Amount in INR" type="text" value="0.00" ng-model="formData.sel_inr_amount[i]" readonly />
</td>
<td class="Amount ">
<input class="form-control form-white form-Tabel" placeholder="" type="text" value="0.00" ng-model="formData.exc_total_amount[i]" readonly />
<button class="inputTabel" ng-click="removeProduct($index)"> <i class="fa fa-times-circle-o" aria-hidden="true"></i>
</button>
</td>
</tr>
</tbody>
</table>
ANGULAR CODE
/****************ADD ANOTHER BATCH QUANTITY**************/
$scope.addAnotherProduct = function(listproducts,$event) {
newItemNo = $scope.listproducts.length+1;
$scope.listproducts.push({'batch_id[newItemNo]':'','product_count[newItemNo]':''});
};
$scope.removeProduct = function(index) {
/*var lastItem = $scope.listproducts.length-1;
$scope.listproducts.splice(lastItem);
$scope.listAddbatches = '';*/
$scope.listproducts.splice(index,1);
};
$scope.removeBatch = function(index) {
/*var lastItem = $scope.listAddbatches.length-1;
$scope.listAddbatches.splice(lastItem);
$scope.listAddbatches = '';*/
$scope.listAddbatches.splice(index,1);
};
$scope.addProductBatch = function() {
var newItemNo = $scope.listAddbatches.length+1;
$scope.listAddbatches.push({'id':'batch'+newItemNo});
};
Here when I click ADD ANOTHER PRODUCT it should create an entire row in the table without the columns of Batch and Quantity, but now it's appearing as it in before row created.
Then when I click ADD BATCH it should create under the table column Batch and Quantity of the corresponding row, but now it's adding in all the rows and when I remove added batch, it should remove the corresponding batch, but now it's removing the last added batch.
The same happens when I remove added product (Entire Row), it should remove the corresponding row of the product but now it's removing lastly added Product row.
How can I fix all the aforementioned issues?
Please help me
There are multiple issues with your approach:
1) You are using a global array listAddbatches but you want to add the batches by product, so why shouldn't you use product.listAddbatches array?
2) When using track by $index you will not able to delete correct element from array or object since compiler directive is not re-compiling the element when its data attribute changes.
3) Using array length to generate id like var newItemNo = $scope.listAddbatches.length + 1; is not a good idea since the array length could change (when removing items) in a way that you will have the same ids for different elements.
4) This line is very strange {'batch_id[newItemNo]':'','product_count[newItemNo]':''}, since you are calculating newItemNo, but this is a simple string 'batch_id[newItemNo]'. Why do you need this?
5) Do not recommend to use $index to remove items, since it could point to some other element in case of filtering.
Your code could like this (simplified version), hope this helps:
angular.module('plunker', [])
.controller('MainCtrl', function($scope) {
$scope.listproducts = [];
$scope.addAnotherProduct = function(listproducts) {
listproducts.push( {
listAddbatches: []
});
};
$scope.removeProduct = function(product) {
var index = $scope.listproducts.indexOf(product);
if (index >= 0)
$scope.listproducts.splice(index, 1);
};
$scope.removeBatch = function(product, batch) {
var index = product.listAddbatches.indexOf(batch);
if (index >= 0)
product.listAddbatches.splice(index, 1);
};
$scope.addProductBatch = function(product) {
product.listAddbatches.push({ });
};
});
<script src="https://code.angularjs.org/1.6.4/angular.js" ></script>
<html ng-app="plunker">
<body ng-controller="MainCtrl">
<table class="table table-bordered tdPaddingNull verTop">
<thead>
<tr>
<th width="200px">Product Details </th>
<th width="250px">Current Availability</th>
<th width="200px">Batch </th>
<th>Quantity</th>
<th>Rate INR </th>
<th>Amt. INR</th>
<th>Converted Amount</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(i, product) in listproducts">
<td style="padding: 7px;">
<input auto-complete ui-items="prductdetail" ng-model="formData.product_name[i]" class="form-control form-white" my-id="{{i}}"/>
<input id="product_id{{i}}" placeholder="productid" type="hidden" value="" ng-model="formData.product_id[i]" my-id="{{i}}"/>
<a ng-click="addProductBatch(product)" title="Add Another Batch Quantity" style="float:right;"><i class="fa fa-plus" aria-hidden="true"></i> ADD BATCH </a>
</td>
<td class="line-item-column item-currentavail transferorder-lineitem">
<div class="row text-muted font-sm">
<div class="col-md-6">
Source Stock
</div>
<div class="separationline col-md-6">
Destination Stock
</div>
</div>
<div class="row font-xs">
<div class="col-md-6">
0.00 Units
</div>
<div class="separationline col-md-6">
0.00 Units
</div>
</div>
</td>
<td style="padding: 7px;">
<div style="display:inline-block;width:100%;" ng-repeat="addBatch in product.listAddbatches">
<select class="form-control form-white selectNor" ng-model="formData.batch_id[i]" ng-change="changedBatchValue(formData.batch_id)" style="margin-bottom: 5px;width: 88%;float: left;">
<option value="">Select Batch</option>
<option value="{{blist.batch_id}}" ng-repeat="blist in batchList">{{blist.batch_number}}</option>
</select>
<a class="inputTabel1" ng-click="removeBatch(product, addBatch)" title="Remove Batch" style="float:left;margin-left: 4px;"> <i class="fa fa-times-circle-o" aria-hidden="true" ></i>
</a>
</div>
</td>
<td style="padding: 7px;">
<input class="form-control form-white" type="text" value="" ng-model="formData.product_count[i]" ng-repeat="addBatch in product.listAddbatches" style="margin-bottom: 5px;"/>
</td>
<td style="padding: 7px;">
<input class="form-control form-white " placeholder="Selling Price" type="text" value="0.00" ng-model="formData.sel_inr_rate[i]">
</td>
<td>
<input class="form-control form-white form-Tabel" placeholder="Amount in INR" type="text" value="0.00" ng-model="formData.sel_inr_amount[i]" readonly />
</td>
<td class="Amount ">
<input class="form-control form-white form-Tabel" placeholder="" type="text" value="0.00" ng-model="formData.exc_total_amount[i]" readonly />
<button class="inputTabel" ng-click="removeProduct(product)"> <i class="fa fa-times-circle-o" aria-hidden="true"></i>
</button>
</td>
</tr>
</tbody>
</table>
<button ng-click="addAnotherProduct(listproducts)">Add Another Product</button>
</body>
</html>