动态 select 下拉列表 Rails 5 / AJAX

Dynamic select dropdown Rails 5 / AJAX

我正在尝试制作一个三输入 select 菜单,允许用户过滤到数据库中的一门课程 select。因此,用户首先 select 位置,并基于该位置 selection 获得该位置的所有课程选项。然后他可以按 select 并被带到该课程。动态部分让我有点弯曲。如果可能的话,我很乐意提供任何帮助。我知道可能需要一些 AJAX 但我迷路了。请任何建议。

到目前为止的代码。看法。

<div class="row no-gutters wow slideInUp" data-wow-duration="1s">
  <div class="col-md-12 home-form">
    <form class="form-inline">
      <select class="custom-select mb-0 mr-sm-0 mb-sm-0">
        <option selected>Location</option>
        <%= @locations.each do |location| %>
                <option value="<%= location.id %>"><%= location.header %></option>
        <% end %>
      </select>
      <select class="custom-select mb-0 mr-sm-0 mb-sm-0">
        <option selected>Course Type</option>
        <%= @courses.each do |course| %>
                <option value="<%= course.id %>"><%= course.course_type %></option>
        <% end %>
      </select>

      <select class="custom-select mb-0 mr-sm-0 mb-sm-0">
        <option selected>Course</option>
        <%= @courses.each do |course| %>
                <option value="<%= course.id %>"><%= course.title %></option>
        <% end %>
      </select>
      <button type="submit" class="btn btn-primary">Submit</button>
    </form>
  </div>
</div>

控制器只是为所有位置和课程引入变量。

然后模型有如下关联。

课程

belongs_to :location

位置

has_many :courses, dependent: :destroy

我可以从下拉列表中看到所有课程和位置,但我需要能够 select 一个位置,然后只能看到位于该位置的课程。如果任何 AJAX 代码得到响应,如果您有时间,我很乐意解释代码中发生的事情。太感谢了。

您可以按照我的说明将动态依赖下拉列表添加到您的 rails 应用程序 -

步骤-1。向路由文件添加操作以获取特定位置的所有课程。

# config/routes.rb

Rails.application.routes.draw do

  get 'get_courses_by_location/:location_id', to: 'courses#get_courses_by_location'  
  get '/course_search' => 'courses#course_search'

 end

步骤-2。使用 get_courses_by_location 操作

创建课程控制器
# app/controllers/courses_controller.rb

class CoursesController < ApplicationController

  def get_courses_by_location
    @courses = Course.where("location_id = ?", params[:location_id])
    respond_to do |format|
      format.json { render :json => @courses }
    end
  end 
  def course_search
    if params[:location].present? && params[:location].strip != ""
      @courses = Course.where("location_id = ?", params[:location])
    else
      @courses = Course.all
    end
  end

end

步骤-3。创建一个 js 文件,用于填充课程下拉列表并更改位置下拉列表。

# app/assets/javascripts/courses.js

$(function() {

   if ($("select#location").val() == "") {
    $("select#course option").remove();
    var row = "<option value=\"" + "" + "\">" + "Course" + "</option>";
    $(row).appendTo("select#course");
   }
   $("select#location").change(function() {
    var id_value_string = $(this).val();
    if (id_value_string == "") {
     $("select#course option").remove();
     var row = "<option value=\"" + "" + "\">" + "Course" + "</option>";
     $(row).appendTo("select#course");
    } else {
     // Send the request and update course dropdown
     $.ajax({
      dataType: "json",
      cache: false,
      url: '/get_courses_by_location/' + id_value_string,
      timeout: 5000,
      error: function(XMLHttpRequest, errorTextStatus, error) {
       alert("Failed to submit : " + errorTextStatus + " ;" + error);
      },
      success: function(data) {
       // Clear all options from course select
       $("select#course option").remove();
       //put in a empty default line
       var row = "<option value=\"" + "" + "\">" + "Course" + "</option>";
       $(row).appendTo("select#course");
       // Fill course select
       $.each(data, function(i, j) {
        row = "<option value=\"" + j.id + "\">" + j.title + "</option>";
        $(row).appendTo("select#course");
       });
      }
     });
    }
   });

  });

步骤 - 4. 现在将课程 js 添加到 application.js 文件的 jquery 文件下方。

# app/assets/javascripts/application.js

//= require jquery
//= require jquery_ujs
//= require courses
//= require_tree .

步骤 - 5. 这里是课程搜索表单

# app/views/courses/course_search.html.erb

<div class="row no-gutters wow slideInUp" data-wow-duration="1s">
  <div class="col-md-12 home-form">
    <%= form_tag(course_search_path, method: "get", class: "form-inline", remote: true) do %>
    <%= select_tag "location", options_from_collection_for_select(Location.all, "id", "header"), prompt: "Location", class: "custom-select mb-0 mr-sm-0 mb-sm-0" %>
    <%= select_tag "course_type", options_from_collection_for_select(Course.all, "id", "course_type"), prompt: "Course Type", class: "custom-select mb-0 mr-sm-0 mb-sm-0" %>
    <%= select_tag "course", options_from_collection_for_select(Course.all, "id", "title"), prompt: "Course", class: "custom-select mb-0 mr-sm-0 mb-sm-0" %>
    <%= submit_tag("Search", class: "btn btn-primary") %>
<% end %>
  </div>
</div>

<div class="row" id="course_listing">
  <%= render partial: "course_list", locals: {courses: @courses} %>
</div>

第 6 步。现在您必须创建一个 course_list 部分文件来显示所有课程

# app/views/courses/_course_list.html.erb
<% courses.each do |course| %>
  <%= course.id %>
  <%= course.title %>
  <hr />
<% end %>

步骤 - 7. 为 ajax 搜索表单提交的显示课程创建一个 js 视图文件。

# app/views/courses/course_search.js.erb
$('#course_listing').html('<%= j render partial: "course_list", locals: {courses: @courses} %>')

我希望它能奏效。