How to create a dependent dropdown in Ruby on Rails?
In the form as is
<%= f.select(:project_id, Project.all.collect {|p| [p.name, p.id]}, {prompt: "Select"}, {class: 'form-control'}) %> <%= f.select(:task_id, Tasks.all.collect {|t| [t.name, t.id]}, {}, {class: 'form-control'}) %>
and those fields generated HTML is
<select class="form-control" name="hour[project_id]" id="hour_project_id"> <option value="">Select</option> <option value="1">Real Estate</option> <option value="2">Time Sheet App</option> </select> <select class="form-control" name="hour[task_id]" id="hour_task_id" disabled=""> <option value="3">Developer</option> <option value="4">Design</option> <option value="6">Backend</option> </select>
that’s it in the form, now JS, Ajax & controller
The JS / Ajax is
$("#hour_task_id").prop("disabled", true); // second dropdown is disable while first dropdown is empty $("#hour_project_id").change(function(){ var project = $(this).val(); if(project == ''){ $("#hour_task_id").prop("disabled", true); }else{ $("#hour_task_id").prop("disabled", false); } $.ajax({ url: "/tasks", method: "GET", dataType: "json", data: {project: project}, error: function (xhr, status, error) { console.error('AJAX Error: ' + status + error); }, success: function (response) { console.log(response); var tasks = response["tasks"]; $("#hour_task_id").empty(); $("#hour_task_id").append('<option>Select Task</option>'); for(var i = 0; i < tasks.length; i++){ $("#hour_task_id").append('<option value="' + tasks[i]["id"] + '">' +tasks[i]["name"] + '</option>'); } } }); });
and in the controller into action
if params[:project].present? @tasks = Project.find(params[:project]).tasks else @tasks = Task.all end if request.xhr? respond_to do |format| format.json { render json: {tasks: @tasks} } end end
That’s it