在Rails、HAML与simple_form中实现可输入文本的选择框是否可行?
当然可以实现!
你想要的是一个支持搜索、允许自定义输入新选项的选择框,结合你已经在用的select2插件,只需要对现有代码做几处调整就能达成需求。下面是具体的实现方案:
第一步:修改simple_form的输入配置
首先,我们需要给select2开启「标签(tags)」功能,同时确保表单字段关联正确的属性(如果person是Office的关联,建议用person_id而非person来绑定字段):
= simple_form_for [:admin, office] do |f| = f.input :person_id, label: "Select Person", collection: People.all, label_method: -> (person) { person.name }, value_method: :id, # 确保提交的是Person的ID input_html: { data: { plugin: "select2", tags: true, # 开启自定义输入 placeholder: "Select or enter a new person" } } = f.submit "Set Person", class: "btn btn-primary btn-block"
第二步:配置select2支持自定义标签创建(可选但推荐)
如果需要更灵活的自定义输入逻辑,可以在你的JS文件里添加select2的初始化配置,比如控制新标签的格式:
$(document).on('turbolinks:load', function() { $('[data-plugin="select2"]').select2({ tags: true, // 自定义新标签的生成逻辑 createTag: function(params) { return { id: params.term, text: params.term, isNew: true // 标记这是用户新建的选项 }; }, // 可选:限制只能输入未存在的选项 matcher: function(params, data) { if ($.trim(params.term) === '') return data; if (data.text.toLowerCase().includes(params.term.toLowerCase())) return data; return null; } }); });
第三步:后台处理自定义输入
当用户输入一个不存在的Person名称时,表单会提交这个文本值(而非已存在的Person ID),所以需要在你的Admin::OfficesController里处理这个情况,自动创建新的Person记录:
def update @office = Office.find(params[:id]) person_input = params[:office][:person_id] if person_input.present? # 先检查是否存在该Person person = Person.find_by(id: person_input) || Person.find_by(name: person_input) # 如果都不存在,创建新的Person person ||= Person.create(name: person_input) @office.person_id = person.id end if @office.save redirect_to admin_office_path(@office), notice: 'Person updated successfully.' else render :edit end end # 对应的create动作也可以用类似逻辑 def create @office = Office.new(office_params.except(:person_id)) person_input = office_params[:person_id] if person_input.present? person = Person.find_by(id: person_input) || Person.find_by(name: person_input) || Person.create(name: person_input) @office.person_id = person.id end if @office.save redirect_to admin_offices_path, notice: 'Office created successfully.' else render :new end end private def office_params params.require(:office).permit(:person_id, # 这里添加你的其他Office字段...) end
这样调整后,用户既可以从现有Person列表中选择,也可以直接输入新的名称,后台会自动创建对应的Person记录并关联到Office上。
内容的提问来源于stack exchange,提问作者Aimee Fritz
相关产品推荐
相关产品推荐

