如何在每次选择更改时检索collection_select的ID并显示项目列表?

时间:2017-04-05 01:21:07

标签: javascript ruby-on-rails ajax

我有一张表格

_form.html.erb

= link_to "", post_path(post, anchor: "disqus_thread"), data: { "disqus-identifier" => "#{post.id.gsub('comments','')}" }, class: "no-underline bold blue label"

而且,每次选择框发生变化(即选择了不同的年份)时,我想显示所选年份的学生列表。该列表必须显示在同一页面中。

我不知道如何获取所选项目的ID并在视图/控制器中使用它以实现此目的..

以下是我的模特:

student.rb

<%= simple_form_for(@exam) do |f| %>
  <%= f.error_notification %>

  <div class="field">
    <%= f.label :Year %>
    <%= f.collection_select :year_id, Year.order(:name), :id, :name, prompt: true %>
  </div>


  <div class="form-inputs">
    <%= f.input :marks_secured %>
  </div>

  <div class="form-actions">
    <%= f.button :submit, "Submit" %>
  </div>
<% end %>

exam.rb

class Student < ApplicationRecord
  belongs_to  :year
  has_many  :exams
end

year.rb

class Exam < ApplicationRecord
  belongs_to  :year
  belongs_to  :student
end

1 个答案:

答案 0 :(得分:0)

我建议使用ajax,以便每次更改select选项时显示学生列表;为此,您需要进行一些更改。

首先,您需要确定您希望在视图中显示学生的位置,例如,尝试在表单中添加div

<%= simple_form_for(@exam) do |f| %>
  <%= f.error_notification %>

  <div class="field">
    <%= f.label :Year %>
    <%= f.collection_select :year_id, Year.order(:name), :id, :name, prompt: true %>
  </div>

  <div id="students"><!-- Students will be listed here --></div>

  <div class="form-inputs">
    <%= f.input :marks_secured %>
  </div>

  <div class="form-actions">
    <%= f.button :submit, "Submit" %>
  </div>
<% end %>

接下来,添加一个脚本(在form所在的同一视图上)以检测select何时更改,并更新(通过ajax)学生列表:

<script type="text/javascript">
  $(function () {
    function getStudents() {
      var year = $('#exam_year_id').val();

      $.ajax({
        headers: {
          'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
        },
        type: "GET",
        url: "<%= students_url %>",
        data: { year: year },
        success: function(response) {
          $('#students').html(html);
        }
      });
    }

    $('#exam_year_id').on('change', getStudents );
    getStudents();
  });
</script>

在此示例中,只要getStudents更改(select)和页面加载($('#exam_year_id').on('change', getStudents );)后就会调用函数getStudents();,因此默认年份的学生选中(即,首次加载页面时)列出。

另请注意,我们正在使用名为div的变量替换最近添加的html内容,该变量将由学生控制器在视图中传送(下一步)。

现在您需要更新学生控制器以获取所选年份的学生列表:

def index
  @Students = Student.where(year: params[:year])
end

使用学生列表创建您的视图:

var html = "<select name='exam[student_id]' id='exam_student_id'>";

<% @Students.each do |student| %>
  html = html + "<option value='<%= student.id %>'><%= student.name %></option>"
<% end %>

html = html + "</select>";

视图必须命名为index.js.erb(而不是index.html.erb),并且包含javascript;在此示例中,它仅包含带有学生列表的变量(html)(列表创建为另一个select框,但您可以更改它。)

最后,在您的考试控制器中添加update操作,以更新exam的详细信息:

def update
  exam = Exam.find(params[:id])
  exam.student_id = exam_params[:student_id]
  exam.year_id = exam_params[:year_id]
  exam.save!
end

private

def exam_params
  params.require(:exam).permit(:year_id, :student_id)
end

就是这样!希望这会有所帮助。