AutoComplete does not work on add remove inputs

1

I'm developing a budget form and I add and remove rows to register products in each row and have two autocomplete fields, where you search for the product by code or by name. The first line is always fixed to start the fill and in it the autocomplete works, and the others that are added as many times as the user wants is not working autocomplete. They do not 'catch the autocomplete event', it does not seem to 'see the DOM'.

Addition and removal of rows

  (function($) {

  RemoveTableRow = function(handler) {
    var tr = $(handler).closest('tr');

    tr.fadeOut(400, function(){ 
      tr.remove(); 
    }); 

    return false;
  };

  AddTableRow = function() {

      var newRow = $("<tr>");
      var cols = "";

      cols += '<td width="13%"> <div class="form-group"> <div class="input-group"> <div class="input-group-addon"><i class="ti-search"></i></div><input type="text" class="form-control input-sm" name="form_code_product[]" id="form_code_product" placeholder="0002"> </div></div></td>';
      cols += '<td width="30%"> <div class="form-group"> <div class="input-group"> <div class="input-group-addon"><i class="ti-search"></i></div><input type="text" class="form-control input-sm" name="form_name_product[]" id="form_name_product" placeholder="Mesa"> </div></div> </td>';
      cols += '<td><input type="text" class="form-control input-sm" name="form_price_product" id="form_price_product"> </td>';
      cols += '<td><input type="text" class="form-control input-sm" name="form_quantity_product" id="form_quantity_product"> </td>';
      cols += '<td><input type="text" class="form-control input-sm" name="form_total_product" id="form_total_product"> </td>';
      cols += '<td><input type="text" class="form-control input-sm" name="form_obs_product"> </td>';

      cols += '<td class="actions">';
      cols += '<button class="btn btn-large btn-danger" onclick="RemoveTableRow(this)" type="button"> <i class="fa fa-close"></i></button>';
      cols += '</td>';

      newRow.append(cols);

      $("#products-table").append(newRow);

      return false;
  };

})(jQuery);

Autocomplete

$(document).ready(function() {
    $("#form_code_product, #form_name_product").autocomplete({

        width: 260,
        matchContains: true,
        selectFirst: false,
        appentTo: '#form_register_budget',

        source: function(request, response){

          $.ajax({
            url: "filter/product_code",
            type: 'get',
            dataType: 'html',
            data:{'term' : request.term }
          }).done(function( products ){

              if( products.length > 0 ){

                 products = products.split( ',' );

                 response( $.each( products, function( key, item ){
                    return({
                        label: item  
                    });

                 }));
              }
          });
        }
     });

});
    
asked by anonymous 20.06.2018 / 15:27

1 answer

0

The main error in your code is that it is repeating id s when adding new rows in the table. This way Autocomplete would only get the first id to find, ignoring the rest. This is because a id must be unique on the page, ie there can not be more than id on the page with the same name.

In addition to that, as you said, when adding new elements in the DOM, Autocomplete needs to be restarted to include these new elements.

Do the following:

First of all, change all id s to class in JavaScript and HTML:

$(".form_code_product, .form_name_product").autocomplete(...

In the case of HTML, just include the name of what was id within the element class list:

                                                       ↓
<input type="text" class="form-control input-sm form_code_product" name="form_code_product[]"

Changed the id s to class , in the script, place all the code within the same scope. Instead of doing as you are doing, thus creating two scopes:

(function($) {
  // código
})(jQuery);

$(document).ready(function() {
  // código
});

Put everything in the same scope, within:

$(document).ready(function() {
  // todo o código
});

Now create an object with the Autocomplete options:

var ac_opts = {
     width: 260,
     matchContains: true,
     selectFirst: false,
     appentTo: '#form_register_budget',

     source: function(request, response){

       $.ajax({
         url: "filter/product_code",
         type: 'get',
         dataType: 'html',
         data:{'term' : request.term }
       }).done(function( products ){

           if( products.length > 0 ){

              products = products.split( ',' );

              response( $.each( products, function( key, item ){
                 return({
                     label: item  
                 });

              }));
           }
       });
     }
}

Create a function where Aucomplete will be started:

function ativaAC(){
    $(".form_code_product, .form_name_product").autocomplete(ac_opts);
}

In the function where lines are added, call the ativaAC() function to restart Autocomplete:

AddTableRow = function() {

   var newRow = $("<tr>");
   var cols = "";

   cols += '<td width="13%"> <div class="form-group"> <div class="input-group"> <div class="input-group-addon"><i class="ti-search"></i></div><input type="text" class="form-control input-sm form_code_product" name="form_code_product[]" placeholder="0002"> </div></div></td>';
   cols += '<td width="30%"> <div class="form-group"> <div class="input-group"> <div class="input-group-addon"><i class="ti-search"></i></div><input type="text" class="form-control input-sm form_name_product" name="form_name_product[]" placeholder="Mesa"> </div></div> </td>';
   cols += '<td><input type="text" class="form-control input-sm" name="form_price_product" classs="form_price_product"> </td>';
   cols += '<td><input type="text" class="form-control input-sm" name="form_quantity_product" class="form_quantity_product"> </td>';
   cols += '<td><input type="text" class="form-control input-sm" name="form_total_product" class="form_total_product"> </td>';
   cols += '<td><input type="text" class="form-control input-sm" name="form_obs_product"> </td>';

   cols += '<td class="actions">';
   cols += '<button class="btn btn-large btn-danger" onclick="RemoveTableRow(this)" type="button"> <i class="fa fa-close"></i></button>';
   cols += '</td>';

   newRow.append(cols);

   $("#products-table").append(newRow);

   ativaAC();

   return false;
};

All this done, your code will function normally.

See the complete and patched code:

$(document).ready(function() {

  RemoveTableRow = function(handler) {
    var tr = $(handler).closest('tr');

    tr.fadeOut(400, function(){ 
      tr.remove(); 
    }); 

    return false;
  };

  AddTableRow = function() {

      var newRow = $("<tr>");
      var cols = "";

      cols += '<td width="13%"> <div class="form-group"> <div class="input-group"> <div class="input-group-addon"><i class="ti-search"></i></div><input type="text" class="form-control input-sm form_code_product" name="form_code_product[]" placeholder="0002"> </div></div></td>';
      cols += '<td width="30%"> <div class="form-group"> <div class="input-group"> <div class="input-group-addon"><i class="ti-search"></i></div><input type="text" class="form-control input-sm form_name_product" name="form_name_product[]" placeholder="Mesa"> </div></div> </td>';
      cols += '<td><input type="text" class="form-control input-sm form_price_product" name="form_price_product"> </td>';
      cols += '<td><input type="text" class="form-control input-sm form_quantity_product" name="form_quantity_product"> </td>';
      cols += '<td><input type="text" class="form-control input-sm form_total_product" name="form_total_product"> </td>';
      cols += '<td><input type="text" class="form-control input-sm" name="form_obs_product"> </td>';

      cols += '<td class="actions">';
      cols += '<button class="btn btn-large btn-danger" onclick="RemoveTableRow(this)" type="button"> <i class="fa fa-close"></i></button>';
      cols += '</td>';

      newRow.append(cols);

      $("#products-table").append(newRow);

      ativaAC();

      return false;
  };

   var ac_opts = {
        width: 260,
        matchContains: true,
        selectFirst: false,
        appentTo: '#form_register_budget',

        source: function(request, response){

          $.ajax({
            url: "filter/product_code",
            type: 'get',
            dataType: 'html',
            data:{'term' : request.term }
          }).done(function( products ){

              if( products.length > 0 ){

                 products = products.split( ',' );

                 response( $.each( products, function( key, item ){
                    return({
                        label: item  
                    });

                 }));
              }
          });
        }
   }

   function ativaAC(){
       $(".form_code_product, .form_name_product").autocomplete(ac_opts);
   }

   ativaAC();

});
    
20.06.2018 / 19:54