Creating a dynamic dropdown in a Rails application using the simple_form gem

In my Rails application, I have a straightforward has_many and belongs_to relationship. Using simple_form, I am looking to dynamically adjust the dropdown options based on the selection made by the user.

Models

 class Processor < ApplicationRecord
   has_many :processor_bank_accounts
 end

 class ProcessorBankAccount < ApplicationRecord
   belongs_to :processor
 

Form inputs

<%= simple_form_for [@customer, @transaction] do |f| %>
<%= f.error_notification %>

<div class="form-inputs">
  <%= f.input :status, :collection => ["payment request"], include_blank: false %>
  <%= f.input :processor, collection: @processors ,label_method: :name,value_method: :id,label: "Processor" , include_blank: false %>
  <%= f.input :processor_bank_account, collection: @bank_accounts , label_method: :bank_name, value_method: :id, label: "Processor Bank Account" , include_blank: true %>
  <%= f.input :tcurrency, collection: @currencies, include_blank: false, label: 'currency' %>
  <%= f.input :amount, as: :decimal, label: 'amount' %>
</div>

<div class="form-actions text-center">
  <%= f.button :submit, "Add transaction", class: "form-button"%>
</div>
<% end %>

To clarify, I would like the processor_bank_account dropdown to be populated based on the processor selected by the user. The console command for this is: ProcessorBankAccount.where(processor: processor).

I believe I need to use JSON and implement JavaScript to load the options accordingly, but I'm uncertain about the next steps. Any guidance in this matter would be greatly appreciated.

Answer №1

To simplify the process, you can utilize jQuery for an AJAX call to a controller action in Rails and then generate the necessary content with an erb template.

On your website, trigger the action through AJAX when the form is submitted:

<script>
    $(document).ready(function() {
        $('#processor_id').on('change', function() {
            $.ajax({
                url: '/transactions/get_processor_bank_accounts',
                type: 'GET',
                data: {
                    processor_id: this.value
                },
                dataType: 'script',
                error: function() {
                    alert('An error occurred retrieving bank accounts for the selected processor.');
                }
            });
        });
    });
</script>

Note that #processor_id corresponds to the ID of your dropdown element.

In the controller action, retrieve and assign the bank accounts:

def get_processor_bank_accounts
  @processor_bank_accounts = ProcessorBankAccount.where(processor_id: params[:processor_id])
end

Lastly, design a view that will populate your dropdown with the retrieved bank account options:

$select_list = $('#processor_id');
$select_list.empty();

<% @processor_bank_accounts.each do |pba| %>
  $select_list.append($('<option value="<%= pba.id %>"><%= pba.name %></option>'));
<% end %>

Answer №2

Here is the solution I devised:

1) Implemented a new method in my processors controller to generate JSON formatted inputs for the dynamic dropdown:

def processor_bank_accounts
 render json: @processor.processor_bank_accounts.map { |bap| { id: bap.id, name: bap.name } }
end

2) Linked this method to a new route in config/routes:

get 'api/bankaccounts', to: 'processors#processor_bank_accounts', as: 'bankaccounts'

3) Developed a JavaScript function to call the route with the selected processor's ID from the first dropdown and populate the second dropdown with data from the JSON array:

// select elements
const processor = document.getElementById("transaction_processor");
const bapSelect = document.getElementById("transaction_processor_bank_account");

function update_baps(processor_id) {
 const url = `INSERTWEBURLHERE/api/bankaccounts?id=${processor_id}`;
 fetch(url)
 .then(response => response.json())
 .then(data => {
  bapSelect.innerHTML = ""; // clear second dropdown
  data.forEach(bap => { // iterate through all BAPs
  const elem = `<option value="${bap.id}">${bap.bank_name}</option>`; // create option elements for the second dropdown using bank_name as the label
  bapSelect.insertAdjacentHTML("beforeend", elem); // insert options into the dropdown
  });
 });
}

4) Set up the JS event listener to trigger the function when the first dropdown field is changed:

processor.addEventListener('change', () => {
 update_baps(parseInt(processor.value));
});

Answer №3

Make sure to assign unique identifiers (IDs) to your select options in order to easily target them with your script.

$('select#cpu').on('change', function() {
      var cpu_id = this.value;
      var cpu_bank_account = $('select#cpu_bank_account');

      $.ajax({
        type: "POST", 
        url: <%= api_path %> ,
        data: { cpu_id: cpu_id },
        success: function(response, status, xhr){
          cpu_bank_account.empty();
          var new_option = new Option(response.bank_name, response.id, false, false);
          cpu_bank_account.append(new_option);
        },
        error: function(xhr, status, error){...}
      });
 });

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

Troubleshooting an issue with Laravel's Bootstrap 5.2 dropdown functionality

After setting up a pre-configured navbar from the Bootstrap website, I noticed that the dropdown feature is not working. This issue arose with the latest version of Bootstrap 5.2 which was integrated into my Laravel project without any modifications to the ...

Discover how to efficiently load and display a JSON array or object using JavaScript

I am new to learning about json and d3, having just started a few hours ago. While I have basic knowledge of javascript, I need help with loading a json file and displaying all the arrays and objects on the console using d3. I tried to do it myself but unf ...

The issue I'm facing is that the ng-click functionality in Angular JS is not functioning properly when the

Upon loading the page, my JavaScript function creates a tree structure from JSON data and generates a list of anchor tags which look like this: <a ng-click="shareParent(4619)">Some data</a> Despite associating the ng-click directive with the ...

Issue with decodeURI function causing hyperlinks to display as plain text

I have been developing a Sharepoint App that includes a feature to extract contact details from a list on the Sharepoint site. Below is a snippet of my code: var currentOpeningContent = '<h4 onclick="ShowJobDetail(\'' + encodeURI(cu ...

The application monitored by nodemon has halted - awaiting modifications in files before restarting the process

1. My ProductController Implementation: const Product = require('../models/product') //Creating a new product => /ap1/v1/product/new exports.newProduct = async(req, res, next) => { const product = await Product.create(req.body); re ...

Validation messages in an Angular application using Typescript are failing to display or disappear sporadically when applied to an HTML form that has

I am currently working on a simple app that retrieves website content from a CMS [Umbraco]. After making an Ajax call, the form comes back to me as plain HTML. I then append the form to the page and use the Angular $compile service to compile the result. T ...

Remove text from input field and deactivate button upon clicking in AngularJS

I am facing an issue where I want to disable the submit button until some text is entered in the input box. <div id="app-id-input-container" ng-form="appIdInput"> <div class="input-group"> <input id="app-id-input" name="appIdInp ...

Having trouble passing a jQuery variable containing a string value to PHP through the jQuery AJAX function?

Below is the jQuery function code snippet: function processMessage() { if (textValue != "") { messageString='<div class="alert-box round"><p class="text-left">' + username + ':' + textValue + '</p>< ...

A guide on updating the SQL order value through a select option using PHP and jQuery

To modify the arrangement of SQL data according to the chosen select option, I am looking to adjust the ORDER value. Within my action.php file, I retrieve values from the database and aim to incorporate a sorting select option that allows for changing the ...

Adding new users to the Ajax Chat Script is an essential process that can enhance communication

After downloading the standalone version of the script from , I realized that it lacked a register page for adding new users. Taking matters into my own hands, I decided to create one myself. User information is stored in chat\lib\data\users ...

Asynchronous handling of Three.JS geometry operations

I've been developing a browser-based game that retrieves terrain data from a remote server. My current implementation involves creating a PlaneGeometry with 100x100 segments based on the received data. However, when the terrain is added to the game ...

Guide on uploading a file to Amazon Glacier with Node.js

While browsing through the Amazon AWS documentation, I stumbled upon this helpful example. var glacier = new AWS.Glacier(), vaultName = 'YOUR_VAULT_NAME', buffer = new Buffer(2.5 * 1024 * 1024); // 2.5MB buffer var params = {vaultName: ...

What are the steps to implement string interpolation within a template element in Vue.js?

Currently, I am looping through a dictionary that is imported from a .json file and I want to compare an attribute in my props with a value in the dictionary. The first div defines the attribute variable to be one of the values in the dictionary, specifica ...

Steering clear of using relative paths for requiring modules in Node.js

When it comes to importing dependencies, I like to avoid using excessive relative filesystem navigation such as ../../../foo/bar. In my experience with front-end development, I have found that using RequireJS allows me to set a default base path for "abso ...

Custom value in Field for radio type in Redux form

Can anyone help me figure out how to input text into a radio field using Redux form? Here are the fields I am working with: <Field name={some.name1} value={'text1'} component={renderRadioElement} type="radio" /> <Field name= ...

Button to close Jquery Dialog

I've set up a custom alert UI using jQuery UI, but I'm having trouble getting the close button to work properly. Here's my code snippet where I'm trying to override the default alert() function with jQuery UI dialog as described in this ...

Display XML information when a row in the table is selected

I am working with an XML data sheet and utilizing ajax to extract information from it in order to generate specific tabs and construct a table of data. However, I am encountering a challenge when attempting to display details in adjacent divs once a row of ...

Implement a functionality where data is fetched from a MYSQL database using JSON when an item is clicked on the list

As a newcomer to android development, I am facing some challenges in incorporating a basic feature into my project. The application I am working on is designed for professors to view a list of students who are under probation in the database. My goal is ...

At times, Mongoose may return null, while other times it returns data frequently

I have designed a unique mongoose schema for managing contacts, with a custom defined ID. Here is the schema structure: const mongooseSchema = new mongoose.Schema({ _id:{ type:String, unique:true, required:true }, firstN ...

After refreshing the page, the ngRoute white page is displayed

I've encountered an issue with my Angular website. I built it using ngRoute, but when I click on a link, a white page appears. Only after refreshing the page does the content actually show up. Even in the browser's DevTools, you can see the html ...