I have a 3 category/subcategory/subsubcategory dependant dropdowns everything works fine but I have a small issue. the second dropdown (subcategories) does not always have subsubcategories so I want to hide the last dropdown and only show it when there is a subsubcategory so it only shows based on the user selection of the subcategory
I would appreciate if someone can help.
my categories table
create_table :categories do |t|
t.string "name", limit: 255
t.text "description", limit: 65535
t.integer "parent_id", limit: 4
t.boolean "important", default: false
t.integer "position", limit: 4, default: 0
t.timestamps
end
in modules category.rb
class Category < ApplicationRecord
validates :name, presence: true
has_many :jobs
belongs_to :parent, foreign_key: :parent_id, class_name: 'Category' , :optional => true
has_many :subcategories, foreign_key: :parent_id, class_name: 'Category'
has_many :subsubcategories, foreign_key: :parent_id, class_name: 'Category'
end
in modules job.rb
class Job < ApplicationRecord
validates :title,:category_id, :description, presence: true
validates :category, :presence => true
belongs_to :user
belongs_to :category , -> { order("name") }
belongs_to :subcategories, class_name: "Category"
belongs_to :subsubcategories, class_name: "Category"
end
dropdown_controller.js
import { Controller } from "@hotwired/stimulus";
// connect to data-controller="dropdown"
export default class extends Controller {
submit () {
this.element.requestSubmit();
}
}
in my jobs_controller.rb
class JobsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
before_action :set_categories
def index
@jobs = Job.all
end
def new
@category = Category.find_by(id: params[:category])
@categories = Category.where(parent_id: nil)
@subcategories = @category.subcategories if @category
@subsubcategories = Category.where(:parent_id => params[:subcategories])
@job = Job.new
end
def create
@job = Job.new(job_params.merge({ user: current_user }))
if @job.save
format.html { redirect_to root_path, notice: "Job was successfully created." }
else
render :new, status: :unprocessable_entity
end
end
private
def job_params
params.require(:job).permit(:title, :description,:category_id).merge(user: current_user)
end
def set_categories
@category = Category.find_by(id: params[:category].presence)
@subcategory = Category.find_by(id: params[:subcategories])
@subsubcategory = Category.find_by(id: params[:subsubcategories])
end
end
views/jobs/new.html.erb
<%= turbo_frame_tag "form" do %>
<%= form_tag new_job_path, method: :get, data: { controller: "dropdown", action: "change->dropdown#submit" } do %>
<%= select_tag :category, options_from_collection_for_select(@categories, "id", "name", @category&.id ), prompt: "Select a category" %>
<%= select_tag :subcategories, options_from_collection_for_select(@subcategories || [], "id" , "name", @subcategory&.id), prompt: "Select a subcategories category" %>
<%= select_tag :subsubcategories, options_from_collection_for_select(@subsubcategories || [], "id" , "name", @subsubcategory&.id), prompt: "Select a subsubcategories category" %>
<% end %>
<% end %>
CodePudding user response:
Why don't you hide it definitely. Like changing views/jobs/new.html.erb to something like this :
<%= turbo_frame_tag "form" do %>
<%= form_tag new_job_path, method: :get, data: { controller: "dropdown", action: "change->dropdown#submit" } do %>
<%= select_tag :category, options_from_collection_for_select(@categories, "id", "name", @category&.id ), prompt: "Select a category" %>
<%= select_tag :subcategories, options_from_collection_for_select(@subcategories || [], "id" , "name", @subcategory&.id), prompt: "Select a subcategories category" %>
<% if @subsubcategories.any? %>
<%= select_tag :subsubcategories, options_from_collection_for_select(@subsubcategories || [], "id" , "name", @subsubcategory&.id), prompt: "Select a subsubcategories category" %>
<% end %>
<% end %>
<% end %>
CodePudding user response:
I actually got it working exactly as I want without Javascript:
<% if [email protected]? %>
<%= select_tag :subsubcategories , options_from_collection_for_select(@subsubcategories || [], "id" , "name", @subsubcategory&.id), prompt: "Select a subsubcategories category" %>
<% end %>