【问题标题】:Filter field based on previous field selection根据先前的字段选择过滤字段
【发布时间】:2013-11-24 20:57:34
【问题描述】:

如何使用 simple_form 根据之前的字段值过滤字段?

例如,我有一个 Opportunities 表单,其中包含两个字段,Company 和 Contact。

公司领域:

  <div class="form-group">
    <%= f.association :company, collection: Company.all.order(:account), prompt: "", :label_method => :account, :value_method => :id %>
  </div>

联系方式:

  <div class="form-group">
    <%= f.association :contact, collection: Contact.all.order(:first_name), prompt: "", :label_method => lambda { |contact| "#{contact.first_name} #{contact.last_name}" }, :value_method => :id %>
  </div>

这是我想要做的:如果我从上面的公司字段中选择一家名为“Deviant”的公司,我希望联系人字段只显示与名为“Deviant”的公司相关联的那些联系人。

我正在尝试这样的事情,但无法让它工作:

  <div class="form-group">
    <%= f.association :contact, collection: Contact.where("company_id = ?", params[:id]), prompt: "", :label_method => lambda { |contact| "#{contact.first_name} #{contact.last_name}" }, :value_method => :id %>
  </div>

我不知道如何引用公司字段中的值。

我该怎么做?

谢谢。

更新

有人吗?这肯定是可能的。这是任何形式的关键功能。我希望我不需要 jQuery 什么的。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 simple-form


    【解决方案1】:

    我认为最好的方法是在公司选择的值发生变化时使用 ajax 请求动态更新您的联系人集合。

    首先,您需要在联系人控制器中执行操作:

    app/controllers/contacts_controller.rb

    class ContactsController < ApplicationController
      def contacts_list
        if params[:company_id]
          @contacts = Contact.where(company_id: params[:company_id])
        else
          @contacts = Contact.all
        end
    
        respond_with(@contacts) do |format|
          format.json { render :json => @contacts.to_json(:only => [:id, :first_name, :last_name]) }
        end        
      end
    end
    

    将此添加到您的路线中:

    config/routes.rb

      post 'contacts_list' => "contacts#contacts_list", as: :contacts_list
    

    然后使用下面的咖啡脚本代码来填充您的联系人集合:

    app/assets/javasctipts/companies.js.coffee

    $(document).ready ->
      if $("#opportunity_company_id")
        populate_contacts()
        $("#opportunity_company_id").change ->
          populate_contacts()
    
    populate_contacts = ->
      $contacts_select = $("select#opportunity_contact_id")
      $contacts_select.attr "disabled", "disabled"
      company_id = $("select#opportunity_company_id").val()
      if company_id is ""
        $contacts_select.html "<option value=\"\">(select the company first)</option>"
      else
        $contacts_select.html "<option value=\"\">(loading contacts...)</option>"
        data = {company_id: company_id}
        data[window._auth_token_name] = window._auth_token
        $.ajax "/contacts_list",
          type: "post"
          dataType: "json"
          data: data
          success: (contacts) ->
            _html = '<option value="">Select the contact:</option>'
            _html += '<option value="'+contact.id+'">'+contact.first_name + ' ' + contact.last_name + '</option>' for contact in contacts
            $contacts_select.html _html
            $contacts_select.removeAttr "disabled"
          error: ->
            alert 'Error trying to load contacts.'
    

    最后,在你的 html 的 head 标签内:

    <% if protect_against_forgery? %>
      <script>
        window._auth_token_name = "<%= request_forgery_protection_token %>";
        window._auth_token = "<%= form_authenticity_token %>";
      </script>
    <% end %>
    

    希望对你有帮助...

    更新: 将以下行添加到您的 ApplicationController (app/controllers/application_controller.rb):

    respond_to :html, :xml, :json, :js
    

    【讨论】:

    • 我已经很接近了,但它卡在“正在加载联系人...”上。我可以在终端中看到它似乎正在执行正确的查询 SELECT contacts.* FROM contacts` WHERE contacts.company_id = '1'` 但它不会显示数据。
    • 嗨,Meebix,我已经用应用程序控制器的附加行更新了答案,还修复了咖啡脚本代码 (companies.js.coffee) 中的一些错误
    • 说得太早了。在生产中不起作用。它无法正确验证令牌...(使用设计)
    • 但是在开发中工作?您是否在应用程序布局文件中设置了“csrf_meta_tag”?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多