I'm trying to make a three input select menu that allows a user to filter down to one course in the database to select. So the user first selects the location, and based on that selection is given all the options of courses that are in that location. He can then press select and be brought to that course. The dynamic part has my mind bent a little. I'd love any help if possible. I understand some AJAX will probably be required but I'm lost on that end. Any advice please.
Code so far. View.
<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>
Controller just pulls in variable for all locations and courses.
Then models have associations as below.
course
belongs_to :location
location
has_many :courses, dependent: :destroy
I can see all the courses and locations from the dropdown but I need to be able to select a location and then only see courses that are in that location please. If any AJAX code is responded i'd love an explanation of what's happening in the code if you have time. Thanks a million.
You can follow my instructions to add dynamic dependent drop down list to your rails applications -
Step -1. Add an action to route file for getting all courses for a specific location.
# 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
Step -2. Create courses controller with get_courses_by_location action
# 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
Step -3. Create a js file for populating the courses dropdown list with changes the location dropdown.
# 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");
});
}
});
}
});
});
Step - 4. Now add the courses js to application.js file bellow the jquery file.
# app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require courses
//= require_tree .
Step - 5. Here the course search form
# 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>
Step - 6. Now you have to create a course_list partial file to display all courses
# app/views/courses/_course_list.html.erb
<% courses.each do |course| %>
<%= course.id %>
<%= course.title %>
<hr />
<% end %>
Step - 7. Create a js view file for display courses for ajax search form submit.
# app/views/courses/course_search.js.erb
$('#course_listing').html('<%= j render partial: "course_list", locals: {courses: @courses} %>')
I hope it should work.