Home > front end >  Autocomplete not working on dynamically created input element
Autocomplete not working on dynamically created input element

Time:07-03

I have one input in the HTML when the page loads, while others are created dynamically through the JS code.

The autocomplete function works perfectly on only the first input, but not on the dynamically created ones. Why is this?

<table  id="dynamic_field">
  <tr>
    <td><input type="text" autocomplete="off" id="example" name="example[]" placeholder="Example"  required/></td>
    <td><textarea name="ex[]" cols="8" rows="2" placeholder="Example"  required/></textarea></td>
    <td><button type="button" name="addElement" id="addElement" > </button></td>
  </tr>
</table>
$(document).ready(function() {
  var i = 1;
  $('#addElement').click(function() {
    i  ;
    $('#dynamic_field').append('<tr id="row' i '"><td><input type="text" 
       autocomplete="off" id="example" name="example[]" 
       placeholder="Example"  required/></td>
       <td><textarea name="ex[]" cols="8" rows="2" 
       placeholder="Example"  
       required/></textarea></td>  
       <td><button type="button" name="remove" id="' i '" 
       >-</button></td></tr>');
    });

    $('#example'   i   '').autocomplete({
      source: 'input_search.php',
    });

    $(document).on('click', '.btn_removeRow', function() {
      var button_id = $(this).attr("id");
      $('#row'   button_id   '').remove();
    });
  });

CodePudding user response:

The main problem is because you only bind the autocomplete() when the page loads. It doesn't automatically apply itself to the new content you append(). You need to do this manually.

In addition, there's some other changes you should make to improve the quality of the code. Firstly, avoid putting HTML in JS. You can use a template for this instead.

In addition, never put id attributes in content which can be dynamically repeated. This is because id have to be unique in the DOM, and repeating the same elements will mean your HTML is invalid.

Similarly, don't use incremental id attributes which you create at runtime. It makes the code more complex than it needs to be and normally creates unnecessary global variables which should also be avoided. Use common class attributes to group elements by behaviour, and use DOM traversal in your JS logic to relate the elements within the event handlers.

With those improvements in mind, your code would look something like this:

<table  id="dynamic_field">
  <tr>
    <td><input type="text" autocomplete="off" name="example[]" placeholder="Example"  required /></td>
    <td><textarea name="ex[]" cols="8" rows="2" placeholder="Example"  required></textarea></td>
    <td><button type="button" name="addElement" id="addElement" > </button></td>
  </tr>
</table>

<template id="row-template">
  <tr>
    <td><input type="text" autocomplete="off" id="example" name="example[]" placeholder="Example"  required /></td>
    <td><textarea name="ex[]" cols="8" rows="2" placeholder="Example"  required></textarea></td>  
    <td><button type="button" name="remove" >-</button></td>
  </tr>
</template>
jQuery($ => {
  let rowTemplate = $('#row-template').html();

  $('#addElement').on('click', () => {
    let $content = $(rowTemplate).appendTo('#dynamic_field');
    $content.find('.exampleInput').autocomplete({
      source: 'input_search.php'
    });
  });

  $('.exampleInput').autocomplete({
    source: 'input_search.php'
  });

  $(document).on('click', '.btn_removeRow', e => {
    $(e.target).closest('tr').remove();
  });
});
  • Related