I've now worked on this for 3 days, searching high and low for a solution without success.
I have a dynamic HTML table that has 5 inputs in a row. The inputs are named in the array convention (i.e. name=part_no[], name=cost[], and so on). Using jQuery, a button is displayed at the end of the initial row that allows the user to add a new row. When a new row is added, another button is created to allow the user to remove the row. Here is the code for the table and "add row" button:
<div class="row">
<table id="part_numbers" class="table">
<tbody>
<tr>
<td width="16.66%">
<!--part number-->
<label for="part_no[]" class="control-label">Part No</label>
<input class="form-control part_no" type="text" name="part_no[]">
</td>
<td width="16.66%">
<!--list price-->
<label for="list_price[]" class="control-label">Suggested List Price</label>
<span class="calc_prices" data-toggle="popover" title="Calculated Pricing" data-content="This is where the data will go" data-placement="top"><i class="fa fa-question-circle" aria-hidden="true"></i></span>
<input class="form-control" type="text" name="list_price[]">
</td>
<td width="16.66%">
<!--lot charge-->
<label for="lot_charge[]" class="control-label">Lot Charge</label>
<input class="form-control" type="text" name="lot_charge[]">
</td>
<td width="16.66%">
<!--lead time eng-->
<label for="lead_time_eng[]" class="control-label">Lead Time (ENG)</label>
<input class="form-control" type="text" id="lead_time_eng[]" name="lead_time_eng[]">
</td>
<td width="16.66%">
<!--lead time production-->
<label for="lead_time_prod[]" class="control-label">Lead Time (PROD)</label>
<input class="form-control" type="text" id="lead_time_prod[]" name="lead_time_prod[]">
</td>
<td width="16.66%"> </td>
</tr>
</tbody>
</table>
</div>
<div class="row">
<div class="col-sm-12">
<a href="javascript: void(0);" class="btn btn-success btn-sm hidden-print addCF">Add Row</a>
</div>
</div>
Here is the code to add and remove a new row:
$('.addCF').click(function(e) {
e.preventDefault();
$('#part_numbers').append('<tr><td width="16.66%"><input class="form-control part_no" type="text" name="part_no[]"></td><td width="16.66%"><input class="form-control" type="text" name="list_price[]"></td><td width="16.66%"><input class="form-control" type="text" name="lot_charge[]"></td><td width="16.66%"><input class="form-control" type="text" name="lead_time_eng[]"></td><td width="16.66%"><input class="form-control" type="text" name="lead_time_prod[]"></td><td width="16.66%"><a href="javascript:void(0)" class="btn btn-danger btn-sm hidden-print remCF">Remove</a></td></tr>');
});
$('#part_numbers').on('click', '.remCF', function(e) {
e.preventDefault();
$(this).parent().parent().remove();
});
When the user starts typing in the part_no field, autocomplete is triggered and a list of matching part numbers are shown. When a part is selected, I'm updating a popover with calculated pricing.
I have no issues bringing the data in on the first row - autocomplete works perfectly, and the popover is updated. However when a new row is added and I start typing in the "part_no[]" field, autocomplete does not trigger. I've tried every variation I can think of for iterating through the input fields to trigger the autocomplete and nothing works.
Here is the autocomplete code. jQuery version is 2.03. jQuery UI version is 1.12.1. Any help is greatly appreciated:
$("[name^=part_no").each(function(index) {
$(this).on('focus',function() {
$(this).autocomplete({
delay: 500,
minLength: 3,
autoFocus: true,
source: "items.php",
select: function(event, ui) {
event.preventDefault();
var item_no = ui.item.label;
var std_cost = ui.item.std_cost;
var std_part_price = ui.item.std_part_price;
var custom_price = ui.item.custom_price;
var existing_price = ui.item.existing_price;
$(this).val(item_no);
$('.calc_prices').popover("destroy").popover({
trigger: 'manual'
}).popover("show").on('shown.bs.popover', function() {
$('.popover-title').text("Calculated Pricing for " + item_no);
$('.popover-title').append('<button type="button" class="close popovercloseid">×</button>');
var popover = $(this);
var contentEl = popover.next(".popover").find(".popover-content");
contentEl.html("Cost: " + std_cost + "<br />Standard: " + std_part_price + "<br />Custom: " + custom_price + "<br />Existing: " + existing_price);
})
return false;
},
change: function(event, ui) {
event.preventDefault();
var item_no = ui.item.label;
var std_cost = ui.item.std_cost;
var std_part_price = ui.item.std_part_price;
var custom_price = ui.item.custom_price;
var existing_price = ui.item.existing_price;
$(this).val(item_no);
$(".calc_prices").popover("destroy").popover({
trigger: 'manual'
}).popover("show").on("shown.bs.popover", function() {
$(".popover-title").text("Calculated Pricing for " + item_no);
$(".popover-title").append('<button id="popovercloseid" type="button" class="close">×</button>');
var popover = $(this);
var contentEl = popover.next(".popover").find(".popover-content");
contentEl.html("Cost: " + std_cost + "<br />Standard: " + std_part_price + "<br />Custom: " + custom_price + "<br />Existing: " + existing_price);
})
return false;
}
});
});
});