0

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>')

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Another issue i encountered after this worked. If you notice, my coffeescript file that renders the partial, both select boxes are replaced. I need to restrict only the select box that needs to be updated. how do I test for this? This could almost be a new question. Hope you don't mind helping
If I understand you correctly, you're saying that when the second select box is changed you only want the third one to be updated. And when the third one is changed, you don't want any of them to be updated. Is this correct? It's inelegant, but you could simply create three separate event handles that fire three different functions. One event handler that responds to change events on the first and triggers updates on the second and third. One event handler on the second that triggers updates on the third. etc. Does this solve your problem?
Reading over your original posting again: are you re-rendering the partial containing all three select boxes after each change? If this is the case, you'll need to instead create a partial that just generates the proper select <option> tag elements and use those <option> tags to replace the insides of the next <select> tag in line. If this makes sense.
It possibly could. What I'm trying to do now is count the number of select boxes that have been selected. Then use a nasty if statement in _update_available.js.coffee. If 1 parameter value is sent, only update box 2. if 2 parameters are sent, then only updated select box 3. nasty. if yours is more elegant than this then we'll try it lol.
Ah. in your second comment you're saying each select box should be in its own partial? Because currently i am rerendering the whole thing every time an event fires
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.