【问题标题】:Rails - Drop down list with 'other' that allows creation of new model objectRails - 允许创建新模型对象的“其他”下拉列表
【发布时间】:2014-04-12 01:15:12
【问题描述】:

我目前有一个相当复杂的_request_form 用于在我的网站中创建新的Requests。目前,在创建请求时,员工必须从下拉菜单中选择他们的姓名,如下所示:

<%= f.collection_select :name, Employee.all(:order => 'name'), :name, :name %>

此选择将正确的Employee 放入Request。但是,如果员工不在数据库中,我希望collection_select 中有一个other 选项,它会生成两个文本框(对于员工nameemail),并且在提交表单时会生成新的Employee

我认为这需要某种花哨的Ajax,但我有限的 Rails 知识并没有延伸到那么远!

编辑:

这是我的完整视图:

<%= javascript_include_tag :defaults, "nested_form" %>
<div class="request_form">
<% if !@request.errors.empty? %>
  <div class="alert alert-error">
    <ul>
      <% @request.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>
<div class="well">
  <%= nested_form_for @request, html: { multipart: true } do |f| %>
    <%= f.label :title %><br />
    <%= f.text_field :title %><br /><br />
    <%= f.label :name, 'Submitted By' %><br />
    <%= f.select :name, Employee.sorted_employees_list.map { |value| [ value, value ] }, :id => "employee_box" %><br />
    <div id="new_employee_data">
    </div>
    <%= f.label :description %><br />
    <%= f.text_area :description %><br /><br />
    <%= f.label :attachment_uploader, 'Attachments' %><%= f.file_field :attachment_uploader, :multiple => true, name: "data_files[attachment_uploader][]" %><br />
    <% unless @request.data_files.empty? %>
      <%= f.label :attachment_uploader, 'Current Attachments:' %><br />
    <% end %>
    <%= f.fields_for :data_files do |attachment| %>
      <% if !attachment.object.new_record? %>
        <%= attachment.label :attachment_uploader, 'Delete: ' + attachment.object.attachment_uploader_url.split("/").last %>
        <%= attachment.check_box :_destroy %>
      <% end %>
    <% end %>
</div>
</div>
<script>
$(document).ready(function(){
  $('#employee_box').append("<option>Other</option>");
});

$('#employee_box').change(function() {
  if( $('#employee_box').val() === 'other' ) {
    $('#new_employee_data').append("<input type='text' id='employee_name' placeholder='Employee Name'> <br/> <br /></input><input type='email' id='employee_email' placeholder='Employee Email'>  </input>");
  }else {
    $('#employee_name').remove();
    $('#employee_email').remove();
  }
});
</script>

这包括@Kirti 的建议。但是,我似乎无法让它工作!

【问题讨论】:

    标签: ruby-on-rails model ruby-on-rails-4 collection-select


    【解决方案1】:

    我认为弹出对话框是不错的选择!

    1) 添加到您的 Gemfile,然后运行 ​​bundle:

    gem 'jquery-ui-rails'
    

    2)激活jquery-ui javascript(application.js):

    //= require jquery.ui.dialog
    

    3) 链接 jquery-ui 样式表(application.css):

      *= require jquery.ui.dialog
    

    4) 为选择准备数据 (employees_controller.rb)

      def new
        @prices = Price.all.map{|p| [p.price, p.id] }
        @prices << ['Create New', 'new_id']    
      end
    

    5) 在视图上显示选择组件 (employees/new.html.erb):

      <%= select_tag :employee, options_for_select(@employees) %>
    
      <div id="new_employee_dialog">
        <label for="name"   type="text">Employee name:</label>
        <input name="name"  type="text"/>
        <label for="email"  type="text">Employee email:</label>
        <input name="email" type="email"/>
      </div>
    

    6) 此 javascript 与对话框窗口一起使用并发送 ajax 请求 (assets/javascripts/employees.js.coffee):

    $ ->
        $("#new_employee_dialog").dialog
          modal: true
          width: 400
          height: 300
          autoOpen: false
          draggable: false
          dialogClass: "without-header"
          buttons: [
            text: "Cancel"
            click: ->        
              $(this).dialog "close"
          ,
            text: "Ok"
            click: ->
              modalForm = $(this)
              $.post "/users/form_create",
                employee_name: $(modalForm).find("input[name='name']").val()
                employee_email: $(modalForm).find("input[name='email']").val()          
              , (data, status) ->          
                if data['status'] == 'ok'
                  modalForm.dialog "close"
                  alert "Ok"
                else
                  alert "Oops"
          ]
    
        $('#employee').change ->
          selected_employee_id = jQuery("#employee").val()
          console.log('selected id: ' + selected_employee_id )
          if selected_employee_id == 'new_id'
            $("#new_employee_dialog").dialog("open");
    

    7) 创建在服务器端捕获 ajax 请求的方法 (employees_controller.rb):

    def form_create
        employee_name = params[:employee_name]
        employee_email = params[:employee_email]
        # create new user..
        respond_to do |format|
          format.json { render :json => {status: 'ok'} }
        end
      end
    

    8) 将其添加到 routes.rb:

      post 'users/form_create' => 'users#form_create'
    

    【讨论】:

      【解决方案2】:

      添加一个空的div 标记(占位符),您要在其中生成两个输入字段:

      <div id="new_employee_data">
      
      </div>
      

      在视图底部添加以下jQuery

      <script>
      $(document).ready(function(){
        $('#request_name').append("<option value='other'>Other</option>");
      });
      
      $('#request_name').change(function() {
        if( $('#request_name').val() === 'other' ) {
          $('#new_employee_data').append("<input type='text' id='employee_name' placeholder='Employee Name'> <br/> <br /></input><input type='email' id='employee_email' placeholder='Employee Email'>  </input>");
        }else {
          $('#employee_name').remove();
          $('#employee_email').remove();
        }
      });
      </script>
      

      在哪里, 将#request_name 替换为为您的collection_select 生成的id

      您还需要在action 中添加用于创建新员工的代码,该代码在提交表单时执行。

      注意:我不是 AJAX 专家,但您可以修改上面的 jQuery 并从那里获取。

      【讨论】:

      • 在让 JQuery 工作时遇到了一点麻烦,我用我的完整表单添加了一个编辑。你能检查一下我做的一切都正确吗?干杯!
      • 将值添加到选项 Other$('#employee_box').append("&lt;option value='other'&gt;Other&lt;/option&gt;"); 你错过了那部分。
      • 另外,删除:id =&gt; "employee_box" 因为f.select 会为您生成一个ID。您将需要在 javascript 中使用 THIS id。您可以通过在浏览器中执行 Page View Source 找到该 ID。
      • 谢谢,原来#request_name 是id,我不需要更改它,或者添加我自己的!你能详细说明action吗?我认为它不仅仅是在Employee Controller 中编写create 函数?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-30
      • 1970-01-01
      相关资源
      最近更新 更多