Rails 5嵌套Cocoon表单autocomplete失效问题求助
解决Rails 5+Cocoon嵌套表单自动补全失效问题
看起来你遇到的核心问题是动态生成的嵌套字段无法被JavaScript正确选中并初始化自动补全,毕竟Cocoon生成的嵌套表单元素ID是动态带索引的(比如program_programlines_attributes_0_exercise_name),你原来的JS选择器完全匹配不到这些元素。下面一步步给你修复方案:
第一步:修正视图字段,添加统一标识类
先给嵌套表单的文本字段加一个专属类,方便JS统一选中,不管是静态还是动态生成的字段都能匹配到:
<%= f.text_field :exercise_name, data: {autocomplete_source: Exercise.order(:exe_desc).map(&:exe_desc)}, class: "form-control exercise-autocomplete", # 新增exercise-autocomplete类 placeholder: "Exercise", autofocus: true %>
第二步:重构JavaScript逻辑,适配动态元素
放弃原来的focus事件监听,改用Cocoon官方提供的cocoon:after-insert回调来初始化新添加的嵌套字段,同时处理页面加载时已存在的字段:
jQuery(function($) { // 初始化页面加载时已存在的嵌套字段 initAutocomplete('.exercise-autocomplete'); // 监听Cocoon新增嵌套项的事件,初始化新字段 $(document).on('cocoon:after-insert', function(e, insertedItem) { initAutocomplete(insertedItem.find('.exercise-autocomplete')); }); // 封装自动补全初始化逻辑 function initAutocomplete(element) { $(element).autocomplete({ source: function() { return $(this).data('autocomplete-source'); } }); } });
为什么这样改?
- 选择器问题:原来的
programline_exercise_name是无效选择器,而且Cocoon生成的字段ID是动态的,用类选择器exercise-autocomplete才能稳定匹配所有目标字段。 - 动态元素适配:Cocoon新增的元素是动态插入DOM的,
cocoon:after-insert是官方推荐的回调时机,能精准捕获新添加的嵌套项并初始化。 - 避免重复初始化:原来的
focus事件每次触发都会重新初始化自动补全,容易导致冲突,封装成独立函数后更可控。
额外优化建议(非必须)
你的模型里find_by_exe_desc可以改成Rails 5推荐的语法,更规范:
def exercise_name=(exe_desc) self.exercise = Exercise.find_by(exe_desc: exe_desc) if exe_desc.present? end
现在重启服务器,刷新页面后,不管是已有的嵌套字段还是新添加的,点击文本框应该都能正常触发自动补全了。
内容的提问来源于stack exchange,提问作者Son Kurc
相关产品推荐
相关产品推荐

