10

我一直在尝试让一些动态选择功能正常工作,但是尽管有许多不同的教程,我还没有让它工作。为了便于阅读,我将代码示例归结为基础。任何建议将不胜感激。

在故障页面上,我需要为故障分配公司和联系人,但我只想能够看到与所选公司关联的联系人

Fault - belongs_to :company, :user, :contact
User - has_many :faults
Contacts - has_and_belongs_to_many :companies
Company - has_and_belongs_to_many :contacts, has_many :faults

/faults/_form.html.erb

<%= f.label :company, "Company:" %>

<%= collection_select(:fault,:company_id,@companies,:id,:full_name, :prompt => "Please select a company") %></br>

<%= f.label :contact, "Contact:" %>

<%= f.collection_select :contact_id, @contacts, :id, :name, :prompt => "Select a Contact" %>

<%= link_to "Add New Contact", {:controller => "companies", :action => "index"}, :confirm => "To add a contact for a company you need to do this from the companies page." %></br>
4

2 回答 2

25

明白了。使用 UJS,您可以通过 5 个步骤动态填充您的选择。

  1. 将类名添加到视图中的选择
  2. 添加 JavaScript(或 CoffeeScript)以观察 select 元素的变化
  3. 根据您的选择创建一个控制器方法来获取您需要的信息
  4. 添加路由以匹配您的新控制器方法
  5. 创建一个 UJS 视图以更新您的联系人选择

所以,

  1. 添加类名:

    <%= f.label :company, "Company:" %>
    <%= collection_select(:fault,:company_id,@companies,:id,:name, {:prompt => "Please select a company"}, {:class => "company_selection"}) %>
    <%= f.label :contact, "Contact:" %>
    <%= f.collection_select :contact_id, @contacts, :id, :name, {:prompt => "Select a Contact"}, {:class=>"contact_selection"} %>
    
  2. 加入一些 CoffeeScript ( app/assets/javascripts/faults.js.coffee)

    $(document).ready ->
      $(".company_selection").on "change", ->
        $.ajax
          url: "/faults/get_contacts"
          type: "GET"
          dataType: "script"
          data:
            company_id: $('.company_selection option:selected').val()
    
  3. 更新您的故障控制器

    def get_contacts
      @company = Company.find params[:company_id]
      @contacts = @company.contacts
    end
    
  4. 为您的新方法添加路线

    resources :faults do
      collection do
        get 'get_contacts', to: "faults#get_contacts"
      end 
    end
    
  5. 添加 UJS 文件 ( app/views/faults/get_contacts.js.erb)

    $('.contact_selection').empty();
    $('.contact_selection').append( $('<option>Select the Contact</option>'));
    <% @contacts.each do |contact| %>
      $('.contact_selection').append($('<option value="<%= contact.id %>"><%= contact.name %></option>'));
    <% end %>
    
于 2013-11-11T20:09:22.147 回答
1

香草 JS 选项

这只能通过 vanilla javascript 来实现。确保有一条路线companies/[id]/contacts.json可以返回正确的数据。

const select = document.querySelector('#company_id');
select.addEventListener('change',function(e) {
  axios.get(`/companies/${e.target.value}/contacts.json`)
    .then((res) => {
      let contactSelect = document.querySelector('#contact_id')
      contactSelect.innerHTML = ''
      res.data.map((model, i) => {
        contactSelect.options[i] = new Option(model.name, model.id);
      })
    })
});
于 2020-08-30T03:47:56.350 回答