Bom dia, estou com um problema para resolver aqui na minha aplicação. O problema consiste em filtrar o campo select HTML “Solução”, baseado nos valores dos outros campos selects acima dele. Atualmente, a aplicação está puxando os valores do banco de dados referente às tabelas Área, Região, Associado, Solução e jogando todas as áreas, regiões, associados e soluções nos campos.
O que o usuário quer que seja mudado é que, quando ele seleciona uma área, uma região e um associado, o campo “Solução” mostre apenas as soluções para aquele associado que está naquela região e dentro daquela área.Fiz várias alterações na minha aplicação. Os campos do formulário da imagem acima são populados pela action: “new” e pelo método popula_selects que é chamado pelo parâmetro before_action :popula_selects, only: [:new, :edit]
. Criei um método novo para ser chamado pelo AJAX e atualizar o campo “Solução”. Seguem os códigos abaixo:
Atendments_Controller < ApplicationController
before_action :popula_selects, only: [:new, :edit]
def new
@atend = Atendment.new
end
def atualiza_solucao #AJAX
@solutions = Atendment.joins(:solution).where("atendment_area_id = ? and atendment_region_id = ? and atendment_assoc_id = ?", params[:atendment_area_id], params[:atendment_region_id], params[:atendment_assoc_id])
respond_to do |format|
format.js
end
end
private
def popula_selects
@atendment_area = AtendmentArea.where(status: true, user_id: current_user.id)
@atendment_region = AtendmentRegion.where(status: true, user_id: current_user.id)
@atendment_assoc = AtendmentRegionAssoc.where(status: true, assoc_id: current_user.entidade_id).where(atendment_region_id: @atendment_region.map(&:atendment_region_id))
@solutions = Atendment.joins(:solution).where("atendment_area_id = ? and atendment_region_id = ? and atendment_assoc_id = ?", params[:atendment_area_id], params[:atendment_region_id], params[:atendment_region_assoc_id])
end
end
Código do Formulário (app/views/atendments/_form.html.erb):
<div class="atendment-form">
<%= form_for :atendment, url: {action: "new"}, html: {method: "get"} do |f| %>
<div class="col-xs-6">
<%= f.select :atendment_area_id, options_for_select(@atendment_area.collect { |c| [ c.atendment_area.name, c.id ] }, 1), {:prompt=>"Área"}, { :class => 'form-control', :required => true, id: 'atendment_atendment_area_id' } %>
</div>
<div class="col-xs-6">
<%= f.select :atendment_region_id, options_for_select(@atendment_region.collect { |c| [ c.atendment_region.name, c.id ] }, 1), {:prompt=>"Região"}, { :class => 'form-control', :required => true, id: 'atendment_atendment_region_id' } %>
</div>
</div>
</div>
<div class="field">
<%= f.select :atendment_assoc_id, options_for_select(@atendment_assoc.collect { |c| [ c.atendment_region.name, c.id ] }, 1), {:prompt=>"Associado"}, { :class => 'form-control', :required => true, id: 'atendment_atendment_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: 'atendment_solution_id' } %>
</div>
</div>
Rota para o novo método:
resources :atendments do
collection do
get :atualiza_solucao
end
end
Criei uma função JQuery Ajax pra chamar o novo método e atualizar o campo Solução (app/assets/javascript/atendment.js.coffee)
exibe_solucoes = ->
$.ajax 'atualiza_solucao',
type: 'GET'
dataType: 'script'
data: {
atendment_area_id: $("#atendment_atendment_area_id").val()
atendment_region_id: $("#atendment_atendment_region_id").val()
atendment_assoc_id: $("#atendment_atendment_assoc_id").val()
}
error: (jqXHR, textStatus, errorThrown) ->
console.log("AJAX Error: #{textStatus}")
success: (data, textStatus, jqXHR) ->
console.log("OK!")
$(document).ready ->
$('#atendment_atendment_assoc_id').on 'change', ->
exibe_solucoes()
Criei então um arquivo .coffee para renderizar o parcial que vai atualizar o campo Solução (app/views/atendment/atualiza_solucao.coffee)
$("#atendment_solution_id").empty()
.append("<%= escape_javascript(render :partial => 'solucao') %>")
E, por último, criei o partial que será renderizado e será colocado na tag “option” do campo “solução” (app/views/atendments/_solucao.html.erb):
<option value="<%= solution.id %>" selected="selected"><%= solution.nome %></option>
Porém, por alguma razão o partial não é renderizado e o campo “solução” fica sem valor (provavelmente por causa do método empty(). No console, é possível ver o erro “500 (Internal Server Error)”. Não sei porque está dando este erro. Uma coisa que percebi é que a aplicação não printa nem o que está no console.log() do “error” na função AJAX, nem o que está no “success”. Outra coisa que eu percebi é que, quando eu altero o html do partial “solucao”, fazendo algo assim:
<option value="foo" selected="selected">bar</option>
Ele funciona e exibe “bar” no campo “Solução”. Só com o código ruby embutido ele não funciona… Se alguém puder me dar uma ideia do que fazer, agradeço muito.
OBS.: Estou utilizando a versão 4.2.1 do rails nesta aplicação. Obrigado pela atenção de todos e pelo tempo dedicado a ler esta questão, que ficou mais longa do que deveria.