Tengo una entrada en el HTML cuando se carga la página, mientras que otras se crean dinámicamente a través del código JS.
La función de autocompletar funciona perfectamente solo en la primera entrada, pero no en las creadas dinámicamente. ¿Por qué es esto?
<table class="table table-bordered" id="dynamic_field"> <tr> <td><input type="text" autocomplete="off" id="example" name="example[]" placeholder="Example" class="exampleInput" required/></td> <td><textarea name="ex[]" cols="8" rows="2" placeholder="Example" class="exampleTxtArea" required/></textarea></td> <td><button type="button" name="addElement" id="addElement" class="btnAddElement">+</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" class="exampleInput" required/></td> <td><textarea name="ex[]" cols="8" rows="2" placeholder="Example" class="exampleTxtArea" required/></textarea></td> <td><button type="button" name="remove" id="'+i+'" class="btn_removeRow">-</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(); }); });El principal problema es que solo vincula el autocomplete() cuando se carga la página. No se aplica automáticamente al contenido nuevo que append() . Tienes que hacer esto manualmente.
Además, hay algunos otros cambios que debe realizar para mejorar la calidad del código. En primer lugar, evite poner HTML en JS. Puede usar una template para esto en su lugar.
Además, nunca coloque atributos de id en el contenido que se pueda repetir dinámicamente. Esto se debe a que la id debe ser única en el DOM, y repetir los mismos elementos significará que su HTML no es válido.
Del mismo modo, no use atributos de id incrementales que cree en tiempo de ejecución. Hace que el código sea más complejo de lo que debe ser y normalmente crea variables globales innecesarias que también deben evitarse. Utilice atributos de class comunes para agrupar elementos por comportamiento y utilice DOM transversal en su lógica JS para relacionar los elementos dentro de los controladores de eventos.
Con esas mejoras en mente, su código se vería así:
<table class="table table-bordered" id="dynamic_field"> <tr> <td><input type="text" autocomplete="off" name="example[]" placeholder="Example" class="exampleInput" required /></td> <td><textarea name="ex[]" cols="8" rows="2" placeholder="Example" class="exampleTxtArea" required></textarea></td> <td><button type="button" name="addElement" id="addElement" class="btnAddElement">+</button></td> </tr> </table> <template id="row-template"> <tr> <td><input type="text" autocomplete="off" id="example" name="example[]" placeholder="Example" class="exampleInput" required /></td> <td><textarea name="ex[]" cols="8" rows="2" placeholder="Example" class="exampleTxtArea" required></textarea></td> <td><button type="button" name="remove" class="btn_removeRow">-</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(); }); });