ctilley79
ctilley79

Reputation: 2195

Rails Ajax Remote Javascript

I have three select boxes that dynamically change their options. The purpose is to find Employees that perform more than one Job. My issue is my CoffeeScript file only triggers once. when the partial is updated and rendered after the first option is selected, I can't get it to fire for the third.

After the javascript file assets/javascripts/employees.js.coffee is triggered and the second select is updated, I can only get the javascript file that renders the partial to execute javascript code for the third.

First select has a list of all Jobs:

After the first Job is selected, then the second select is filtered excluding Jobs that are performed by only one Employee

The third select filters Jobs excluding those that are only performed by two Employees, leaving jobs that are performed by three or more Employees

my partial:

<div class="available_jobs">
  <%= form_tag('employee', action: :index, method: :get) do%>
    <div class="ui stackable three column grid">
        <div class="five wide column"> <%= select_tag "job1", options_for_select(@jobs_available), id: 'job_option_1',prompt:"Select Job", class:"fluid ui dropdown"%></div>
        <div class="five wide column"> <%= select_tag "job2", options_for_select(@jobs_available), id:"job_option_2",prompt:"Select Job", class:"fluid ui dropdown"%></div>
        <div class="five wide column"> <%= select_tag "job3", options_for_select(@jobs_available), id:"job_option_1",prompt:"Select Job", class:"fluid ui dropdown"%></div>
    </div>
    <br/>
    <div class="four wide column"> <%=submit_tag "Get Employees", class: "ui primary button"%></div>
<%end%>
</div>

Heres the javascript in my assets/javascripts/employees folder:

$(document).on 'turbolinks:load', ->
  $('#employee_job').change ->
    $.ajax '/update_available',
      type:"GET",
      dataType: 'script'
      data: {
        available_jobs:
          job1: $("#job_option_1 option:selected").val()
          job2: $("#job_option_2 option:selected").val()
          job3: $("#job_option_3 option:selected").val()
      }
      error: (jqXHR, textStatus, errorThrown) ->
      success: (data, textStatus, jqXHR) -> 

My controller method

def update_available
  employee_params=[]
  employee_params = params[:available_jobs].values_at :job1, :job2, :job3
  employee_params.reject!(&:blank?)
  @employee_jobs=[]

  @employees = Employee.joins(:employee_jobs).where(employee_jobs: { job: employee_params }).where("employee_jobs.job_name").group("employee.id").having("count(*) = #{employee_params.count}")
  @employees.each do|e|
    e.employee_jobs.each do |j|
      @employee_jobs.push(j.job_name)
    end
  end

@employee_jobs = @employee_jobs.uniq

respond_to do |format|
  format.js
end

end

and finally update_available.js.coffee

$( "#job_option_2" ).replaceWith('<div class="five wide column"> <%= select_tag "job2", options_for_select(@employee_jobs), id:"job_option_2",prompt:"Select Job", class:"fluid ui dropdown"%></div>')
$( "#job_option_3" ).replaceWith('<div class="five wide column"> <%= select_tag "job3", options_for_select(@employee_jobs), id:"job_option_3",prompt:"Select Job", class:"fluid ui dropdown"%></div>')

Upvotes: 0

Views: 47

Answers (1)

John
John

Reputation: 10049

Based on your description, it sounds like the problem may be that you're updating the #employee_job element and removing the attached event handlers, or that the second and third #employee_job elements are not on the page when .on('turbolinks:load') fires.

For either problem, you you can fix it by updating your coffeescript file from this:

$(document).on 'turbolinks:load', ->
  $('#employee_job').change ->
    $.ajax '/update_available',
      ...

To this:

$(document).on 'turbolinks:load', ->
  $('body').on 'change', '#employee_job1', ->
    $.ajax '/update_available',
      ...
  $('body').on 'change', '#employee_job2', ->
    $.ajax '/update_available',
      ...
  $('body').on 'change', '#employee_job3', ->
    $.ajax '/update_available',
      ...

You can learn more about jQuery's .on() method here.

Upvotes: 1

Related Questions