What is the process of obtaining the ID and displaying the subsequent field based on that ID in Ruby on Rails?

I'm utilizing rails4 and I am looking for a more efficient way to display the sub-category list based on the category selected in a form. Currently, I have used JavaScript for this functionality but I believe there may be a better solution. Any suggestions?

Users should be able to choose a category from the following:

<div class="field">
    <%= f.label :Category %><br>
    <%= f.collection_select :category_id, Category.all, :id, :name, { :prompt => true, :selected => @product.category_id } %>
</div>  

Once a category is selected, the next field should update accordingly. Currently, #women_category & #men_category are hidden.

<div class="field" id="women_category">
  <%= f.label :sub_category %><br>
  <%= f.collection_select  :sub_category_id, @first_category.sub_categories.all,:id ,:name%>
</div>
<div class="field" id="men_category">
  <%= f.label :sub_category %><br>
  <%= f.collection_select  :sub_category_id, @second_category.sub_categories.all,:id ,:name%>
</div>

If category_id=1 is selected, #women_category is displayed. If category_id=2 is selected, #men_category is shown using JavaScript.

$("select[name='product[category_id]']").change(function(){  
  if(this.value == '1'){
    $("#women_category").show();
    $("#men_category").hide();
  }else if(this.value == '2'){
    $("#women_category").hide();
    $("#men_category").show();
  }
});

If the categories list grows, managing this setup could become complex. Is there a simpler way to code this? Please provide guidance.

Answer №1

Within the controller

@categories = Category.include(:sub_categories).all

Inside the view

<div class="field">
  <%= f.label :Product_Category %><br>
  <%= f.collection_select :category_id, @categories, :id, :name, { :prompt => true, :selected => @product.category_id } %>
</div>  

<div id="subcategory-selects">
  <% @categories.each do |category| %>
    <div class="field sub-category-select" data-category-id="<%= category.id %>" style="display:none;" disabled="disabled">
      <%= f.label :Subcategory %><br>
      <%= f.collection_select  :sub_category_id, category.sub_categories,:id ,:name %>
    </div>
  <% end %>
</div>

Javascript functionality

$("select[name='product[category_id]']").change(function(){  
  //get the subcat select with this category id, show and disable it, and hide and disable its siblings
  $(".sub-category-select[data-category-id="+$(this).val()+"]").show().removeAttr("disabled").siblings().hide().attr("disabled", "disabled");
});

The rationale behind disabling/enabling the subcategory selects, as well as showing/hiding them, is to prevent hidden elements from contributing to the parameters when the form is submitted. Since all the subcategory selects share the same name attribute, only the visible and enabled one will be considered in the params.

Please note that a field is considered "disabled" if it has the "disabled" attribute, regardless of the attribute's value. Setting it to "disabled" simply serves as a clear indicator of its status.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Typescript gives you the ability to create a versatile writing interface that includes all

Think about this: interface Options { length?: number, width?: number } interface Action { performAction ({length, width}: Options): void } const myObject: Action = { performAction ({length, width}) { // do something without returning ...

Executing 'npm run bundle' with Webpack results in an ERR! with code ELIFECYCLE

As someone new to using Webpack with AngularJS apps, I am eager to learn but facing some challenges. Following the guide by Ken Howard has been helpful, but I encounter an error when attempting to run the bundle. Article by Ken Howard that I've been ...

Verify if the username is already in use

Is it possible to validate the existence of a username while the user is entering it in a textbox or immediately after they finish typing? Should I use Jquery or Ajax for this task? Does anyone have any examples demonstrating how this can be done? ...

Selecting a webpage from a dropdown list to display its specific content within an iframe

I have a dropdown menu similar to this: <form name="change"> <SELECT NAME="options" ONCHANGE="document.getElementById('frame1').src = this.options[this.selectedIndex].value"> <option value="">Choose</option> <opti ...

"Implement a feature where HTML elements trigger a function instead of using the

<%- include("partials/header") %> <p> this is main page</p> <% let cpp= 6 %> <% for (let i=0;i<cpp;i++){ %> <div class="card"> <li><%= cards[i].name %></li> <li>< ...

Transitioning between modals using Tabler/Bootstrap components in a ReactJS environment

Currently, I am constructing a Tabler dashboard and incorporating some ReactJS components into it. Initially, I used traditional HTML pages along with Jinja2 templates. However, I have now started integrating ReactJS for certain components. I prefer not t ...

Attempting to conceal the select input and footer components of the Calendar component within a React application

I am currently working on customizing a DatePicker component in Antd and my goal is to display only the calendar body. Initially, I attempted to use styled components to specifically target the header and footer of the calendar and apply display: none; st ...

Can you explain the functionality of `module.exports = mongoose model` in a NodeJs environment

Coming from a front-end React background, I am familiar with statements like import and exports. However, as I delve into learning Backend (NodeJs) with mongoDB, I find myself curious about the mechanics of import and export in this new environment. I hav ...

Angular Logout does not reset local storage items

My ng-click logout function in the view: <div class="navbar navbar-default"><div class="container"> <div id="navbar-main"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> <li ng-show=" ...

Ensure that all asynchronous code within the class constructor finishes executing before any class methods are invoked

Looking to create a class that takes a filename as a parameter in the constructor, loads the file using XmlHttpRequest, and stores the result in a class variable. The problem arises with the asynchronous nature of request.onreadystatechange, causing the ge ...

The @Input decorator in Angular 2/4 is designed to only transfer fundamental values and not collections or complex data

I have encountered an issue while attempting to use @Input with a list of objects, where the @Input variable ends up being undefined. What is functioning properly can be seen in home.component.html: <p> <it-easy [mycount]="countItem" (result ...

Prevent Node.js Express from automatically creating sessions

When I activate the session option in express using app.use(express.session({secret: "12345"}));, a session cookie is automatically created when the user visits a page for the first time. Is there a way to turn off this automatic behavior and have more co ...

The Angular JavaScript code displays the message variable in the web browser

When using Angular JavaScript, the browser displays {{message}}. I have tried multiple approaches but it still doesn't work as expected. var myApp=angular.module("mod",[]); myApp.controller("con", function($scope){ $scope.message = "hhhhhhhh"; }); ...

Is it possible to apply the active class to the current list menu item in Mark using server-side techniques instead of client-side JS

When a menu item is clicked, I want to add the active class to that specific menu item. For example, if someone clicks on the contact page, the contact option in the menu should receive the active class. I am currently working with NodeJS and Koa. Below is ...

The submission form is being triggered immediately upon the page loading

I have a form on the landing page that sends parameters to Vuex actions. It functions correctly when I click the submit button and redirects me to the next page as expected. However, there seems to be a problem. Whenever I open or refresh the page, the par ...

Storing the closed state of a pop-up box in localStorage for future reference

I'm struggling to get localStorage working properly on my website (). Here's what I need to achieve: A newsletter subscription pop-up on every page - this part is functioning correctly An option for users to click 'X' to close the po ...

Tips for binding to a single input box within an ngFor loop

Can anyone lend a hand with some code? I'm working on a straightforward table using ngFor, but I'm facing an issue with input binding. The problem is that all the input fields generated by ngFor display the same value when typing. How can I preve ...

I am looking to incorporate a password recovery page into my login process, but I am facing difficulty navigating to it once the code has been modified

I'm looking to include a forgotten password option on my login page, but I'm facing an issue when trying to navigate to it after updating the code. The website is throwing the following error message: [vue-router] uncaught error during rout ...

Leveraging the power of node pkg to generate standalone executables while configuring npm

I have successfully used pkg to create an executable file for my node js application. Everything is working fine in that aspect. However, I am also utilizing the config module to load yaml configuration files based on the environment. During the packaging ...

Is there a way to verify if the request query value is empty like ""?

When creating a Node.js component, I encountered an issue with one of my APIs that sometimes returns empty query values like "". In order to handle this scenario, I need to implement a conditional statement. For example, the query may look like this: { ...