Autocomplete does not work on adding remove inputs

Asked

Viewed 59 times

1

I am developing a quotation form and in it I add and remove lines to register products and in each line there are two autocomplete fields, where search the product by code or by name. The first line is always fixed to start the filling and in it the autocomplete works, whereas the others that are added as many times as the user wants is not working the autocomplete. They don’t 'capture the autocomplete event', they don’t seem to "see in the DOM".

Addition and removal lines code

  (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);

Code of the 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  
                    });

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

});

1 answer

0


The main error in your code is that it is repeating ids when adding new rows in the table. This way Autocomplete would only take the first id to find, ignored the rest. That’s because a id should be unique on the page, ie there can be no more than one id on the page with the same name.

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

Do the following:

First of all, change all the ids for 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[]"

Altered the ids to class, in the script, put 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, inside:

$(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 function ativaAC() to restart the 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;
};

Done all this, your code will work normally.

See the complete and corrected 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();

});
  • thank you very much, it worked perfectly. I had really forgotten the issue of ID so being unique. And thank you for the optimization of the code as well.

  • I had another problem, because then, for example I type the code and when clicking on the options it fills some fields of this line with the information related to it. Then I need to differentiate each class from the list, because otherwise it will fill in all the same. If I put a counter , incrementing a class will it work? Example: var Count = 1; <class="my-class '+Count+'"> But how would you also reference in the code? I also need to add the subtotals of each line and give total after

  • would look like this: $('table tbody'). Closest('tr'). find('. form_name_product'). val( product.product_name ); ?

  • Not so. By clicking on the autocomplete option, you should take this input where the autocomplete value will be inserted. Wait I’ll take a look here.

  • is because I use SELECT so that when clicked on the item it triggers this event: https://pastebin.com/q2Agb1bi

  • You have to add an event in the Autocomplete options.... I’ll add it in the reply...

  • At the beginning of ac_opts you add select: function(event){&#xA; $(event.target).closest("tr").find(".form_name_product").val("teste");&#xA; },&#xA;

  • I texted you on chat

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.