jQuery autocomplete动态新增input字段仅首个生效问题解决
问题根因
动态新增的输入框无法触发自动补全,是几处代码错误共同导致的:
- 重复加载两个版本的jQuery:先引入jQuery 3.5.1之后又引入jQuery 1.10.2,低版本覆盖高版本会引发插件兼容性问题
- 违反HTML id唯一规范:所有姓名输入框都使用了相同的id
automplete-2,jQuery通过id选择器只会匹配页面中第一个符合条件的元素 - 初始化时机错误:仅在页面初始加载时给第一个存在的输入框绑定了autocomplete,后续动态追加的DOM元素从未执行过autocomplete初始化逻辑,自然无法触发效果
- 额外结构错误:初始HTML里的
ui-widget容器标签嵌套错误,td未正常闭合,会导致表格渲染错乱
修复方案
- 删除重复的低版本jQuery引用,仅保留一个jQuery版本即可
- 放弃用id选择器绑定autocomplete,给需要自动补全的姓名输入框新增专属类名
autocomplete-name,通过类选择器定位元素,避免id重复冲突 - 每次点击「Add More」按钮追加完新的输入行后,立刻给新行里的姓名输入框初始化autocomplete实例
- 修正错误的HTML标签嵌套结构
修正后的核心代码
首先调整head部分的资源引用,删除重复的jQuery:
<head> <title>Dynamic add/remove input fields in PHP Jquery AJAX</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 仅保留一个jQuery版本,删除重复的1.10.2引用 --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <link href="https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel="stylesheet"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> <script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> </head>
然后修正表格部分的HTML结构,给姓名输入框添加专属类名:
<table class="table table-bordered table-hover" id="dynamic_field"> <tr> <td> <div class="ui-widget"> <input type="text" name="name[]" placeholder="Enter your Name" class="form-control name_list autocomplete-name" /> </div> </td> <td><input type="text" name="email[]" placeholder="Enter your Email" class="form-control name_email"/></td> <td><button type="button" name="add" id="add" class="btn btn-primary">Add More</button></td> </tr> </table>
最后修正JS逻辑,抽离公共初始化方法,新增元素后补绑autocomplete:
<script type="text/javascript"> $(document).ready(function(){ // PHP输出自动补全数据源 <?php $js_array = json_encode($name); echo "var availableTutorials = ". $js_array . ";\n"; ?> // 抽离autocomplete初始化逻辑,避免重复编码 function initAutocomplete($el) { $el.autocomplete({ source: availableTutorials, autoFocus: true }); } // 页面初始化时给第一个已存在的姓名输入框绑定自动补全 initAutocomplete($('.autocomplete-name')); var i = 1; $("#add").click(function(){ i++; // 追加新行,给新的姓名输入框加上autocomplete-name类 var newRow = `<tr id="row${i}"> <td> <div class="ui-widget"> <input type="text" name="name[]" placeholder="Enter your Name" class="form-control name_list autocomplete-name"/> </div> </td> <td><input type="text" name="email[]" placeholder="Enter your Email" class="form-control name_email"/></td> <td><button type="button" name="remove" id="${i}" class="btn btn-danger btn_remove">X</button></td> </tr>`; $('#dynamic_field').append(newRow); // 仅对新添加的行内姓名输入框初始化autocomplete initAutocomplete($('#row'+i).find('.autocomplete-name')); }); $(document).on('click', '.btn_remove', function(){ var button_id = $(this).attr("id"); $('#row'+button_id).remove(); }); $("#submit").on('click',function(e){ e.preventDefault(); var formdata = $("#add_name").serialize(); $.ajax({ url :"action.php", type :"POST", data :formdata, cache :false, success:function(result){ alert(result); $("#add_name")[0].reset(); } }); }); }); </script>
注意:jQuery UI的autocomplete是插件实例化方法,不是原生DOM事件,不能通过
$(document).on()的事件委托方式绑定,必须在元素插入DOM之后单独对新元素执行初始化方法,这也是很多同类方案没生效的核心原因。
内容的提问来源于stack exchange,提问作者Nishant
相关产品推荐
相关产品推荐

