Filter select fields using other selects with Ruby on Rails

Asked

Viewed 737 times

1

Good afternoon, I have a problem to solve here in my application. The problem is to filter the select HTML "Solution" field, based on the values of the other selected fields above it. The image shows an example of these fields. Exemplo dos campos do formulário

Currently, the application is pulling the values of the database referring to the tables Area, Region, Associate, Solution and playing all areas, regions, associates and solutions in the fields. What the user wants to be changed is that when he selects an area, a region, and an associate, the "Solution" field shows only the solutions to that associate who is in that region and within that area.

Edit:

I’m almost there! I made several changes to my application. The image form fields above are populated by action: new and by the method popula_selects which is called by the parameter before_action :popula_selects, only: [:new, :edit]. I created a new method to be called by AJAX and update the "Solution" field. Follow the codes below:

    Atendiments_Controller  < ApplicationController

      before_action :popula_selects, only: [:new, :edit]

        def new 
            @atend = Atendiment.new
        end

        def atualiza_solucao #AJAX
            @solutions = Atendiment.joins(:solution).where("atendiment_area_id = ? and atendiment_region_id = ? and atendiment_assoc_id = ?", params[:atendiment_area_id], params[:atendiment_region_id], params[:atendiment_assoc_id])
            respond_to do |format|
              format.js 
          end
        end

        private

        def popula_selects
              @atendiment_area = AtendimentArea.where(status: true, user_id: current_user.id)
              @atendiment_region = AtendimentRegion.where(status: true, user_id: current_user.id)
              @atendiment_assoc = AtendimentRegionAssoc.where(status: true, assoc_id: current_user.entidade_id).where(atendiment_region_id: @atendiment_region.map(&:atendiment_region_id))
              @solutions = Atendiment.joins(:solution).where("atendiment_area_id = ? and atendiment_region_id = ? and atendiment_assoc_id = ?", params[:atendiment_area_id], params[:atendiment_region_id], params[:atendiment_region_assoc_id])

   end
end

Form Code (app/views/atendiments/_form.html.erb

<div class="atendiment-form">
  <%= form_for :atendiment, url: {action: "new"}, html: {method: "get"} do |f| %>

  <div class="col-xs-6">
    <%= f.select :atendiment_area_id, options_for_select(@atendiment_area.collect { |c| [ c.atendiment_area.name, c.id ] }, 1), {:prompt=>"Área"}, { :class => 'form-control', :required => true, id: 'atendiment_atendiment_area_id' } %>
      </div>
        <div class="col-xs-6">
          <%= f.select :atendiment_region_id, options_for_select(@atendiment_region.collect { |c| [ c.atendiment_region.name, c.id ] }, 1), {:prompt=>"Região"}, { :class => 'form-control', :required => true, id: 'atendiment_atendiment_region_id' } %>
        </div>
      </div>
    </div>

    <div class="field">
      <%= f.select :atendiment_assoc_id, options_for_select(@atendiment_assoc.collect { |c| [ c.atendiment_region.name, c.id ] }, 1), {:prompt=>"Associado"}, { :class => 'form-control', :required => true, id: 'atendiment_atendiment_assoc_id' } %>
    </div>
    <div class="field">
      <%= f.select :solution_id, options_for_select(@solutions.collect { |solution| [solution.name, solution.id] }, 0), {:prompt=>"Solução"}, { :class => 'form-control', :required => true, id: 'atendiment_solution_id' } %>
    </div>
  </div>

Route to the new method:

resources :atendiments do
collection do
  get :atualiza_solucao
  end
end

I created an Ajax Jquery function to call the new method and update the Solution field (app/Assets/javascript/atendiment.js.coffee)

exibe_solucoes = ->

$.ajax 'atualiza_solucao',
type: 'GET'
dataType: 'script'
data: {
  atendiment_area_id: $("#atendiment_atendiment_area_id").val()
  atendiment_region_id: $("#atendiment_atendiment_region_id").val()
  atendiment_assoc_id: $("#atendiment_atendiment_assoc_id").val()
}
error: (jqXHR, textStatus, errorThrown) ->
  console.log("AJAX Error: #{textStatus}")
success: (data, textStatus, jqXHR) ->
  console.log("OK!")

$(document).ready ->

  $('#atendiment_atendiment_assoc_id').on 'change', ->
    exibe_solucoes()

I then created a file . coffee to render the partial that will update the Solution field (app/views/atendiment/actualiz_solucao.coffee)

$("#atendiment_solution_id").empty()
  .append("<%= escape_javascript(render :partial => 'solucao') %>")

And, finally, I created the partial that will be rendered and will be placed in the "option" tag of the "solution" field (app/views/atendiments/_solucao.html.erb

<option value="<%= solution.id %>" selected="selected"><%= solution.nome %></option>

However, for some reason the partial is not rendered and the "solution" field is worthless (probably because of the method empty(). On the console, you can see the error "500 (Internal Server Error)". I don’t know why you’re making this mistake. One thing I realized is that the application doesn’t print or what’s in the console.log() of the "error" in the AJAX function, nor what is in the "Success". Another thing I realized is that when I change the html of the partial "solution", doing something like this:

<option value="foo" selected="selected">bar</option>

It works and displays "bar" in the "Solution" field. Only with the built-in ruby code it doesn’t work... If anyone can give me an idea of what to do,.

NOTE: I am using version 4.2.1 of Rails in this application. Thank you for everyone’s attention and for the time devoted to reading this issue, which has been longer than it should have been.

2 answers

2


Thanks for the personal answers. I solved this problem by creating a function Ajax calling a method in the controller which searches in the BD the dice I need to throw in the fields select and returns in format JSON. So I take this JSON and update the option of the fields select. The code can be seen at this link, which is the same question, but is in stackoverflow in English.

0

  • Quote directly in your post what the site says instead of just putting the link. The link over time can be disabled/edited losing its meaning and making your comment useless.

  • Okay, I’ll fix it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.