daveomcd
daveomcd

Reputation: 6555

How to modify form based on drop down list selection in Rails?

I have a form that asks the user to evaluated a person based on the position they have within the company. However, the user needs the option to evaluate the person at a different position they don't currently occupy also. While I have a drop-down-list to allow them to select the other position, my form currently doesn't update the questions it gives to the user to evaluate based on the new position. How would I incorporate that?

reports_controller.rb

def new

  # Find or create a new report
  @report = Report.unscoped.where(employee_id: @employee.id, author_id: current_user.id).first_or_initialize do |record|
     # Build new record if it didn't already exist
  end

  # Add skills for evaluations based on the employee's position
  @skills.includes(:positions).where(positions: { id: @employee.position.id }).each do |skill|
    @report.evaluations << Evaluation.new(skill_id: skill.id) unless @report.evaluations.any? { |e| e.skill == skill}
  end

end

_form.html.erb

<%= simple_form_for([@employee, @report] do |f| %>
  <%= f.error_notification %>

  <!-- Drop Down list where user determines which position they wish to evaluate the employee for... -->
  <%= f.association :position, label: "Position Evaluated", selected: @employee.position.id %>


  <!-- Skills for the user to evaluate the employee, should change depending on the value selected from the drop down box. -->
  <%= f.nested_fields_for :evaluations do |fn| %>
    <%= fn.input :skill_id, as: :hidden, input_html: {value: fn.object.skill.id} %>
    <%= fn.object.skill.name %>
    <%= fn.association :grade %>
    <%= fn.input :explanation, input_html: { rows: 3 } %>
  <% end %>

  <% f.button :submit, "Update Report", class: "btn btn-primary" %>
<% end %>

Upvotes: 1

Views: 1926

Answers (3)

Rahul Sharma
Rahul Sharma

Reputation: 5995

1.View:

<%= f.association :position, label: "Position Evaluated", selected: @employee.position.id, id: "position-select" %>
<% if @position_eval == "Manager" %>
  <%= f.nested_fields_for :evaluations do |fn| %>
    <%= fn.input :skill_id, as: :hidden, input_html: {value: fn.object.skill.id} %>
    <%= fn.object.skill.name %>
    <%= fn.association :grade %>
    <%= fn.input :explanation, input_html: { rows: 3 } %>
  <% end %>
<% else if @position_eval == "Developer" %>
  .
  .
  .
<% end %>

2. ajax.js.coffee

$ ->
  $(document).on 'change', '#position-select', (evt) ->
    $.ajax 'update_position',
      type: 'GET'
      dataType: 'script'
      data: {
        position: $("#position-select option:selected").val()
      }
      error: (jqXHR, status, errorThrown) ->
        console.log("AJAX Error: #{status}")
      success: (data, status, jqXHR) ->
        console.log("Get Position OK!")

3. config/routes.rb

get 'report/update_position', as: 'update_position'

4. update_position action

def update_position
  @position_eval = params[:position]
  respond_to do |format|
    format.json {render nothing: true}
  end
end

Upvotes: 0

aarkerio
aarkerio

Reputation: 2354

1) Add the route to call get_skills(position_id) method in your controller, this method returns a JSON response with the skills.

2) In the form, add the option onChange in the position field.

3) onChange must call a jQuery Ajax function to call get_skills(position_id) in the background.

4) Update skills form field with the new values.

Upvotes: 0

user896237
user896237

Reputation:

Usually this would be handled with jQuery not Rails itself. You could hide and show some parts of the form based on what you want to display and hide. Setting the hidden ones input values to disabled in jQuery would prevent them sending any data to Rails.

You could read the values of the selected form object with

$('#selected-position :selected').change(function(){
    if // they selected position 1
        $('#position-1').show()
        $('#position-1').prop('disabled', true);
        $('#position-2').hide()
        $('#position-2').prop('disabled', false);
    elseif // and so on
});

Upvotes: 1

Related Questions