Refactor Coffee Script to fire on page load instead of change I have a Rails app where I'm trying to select a list of facilities based on what region is selected in a form.  So far, I've implemented group_collection_select to do this as well as a bit of CoffeeScript.

It works when creating a new record and selecting a region.  The behavior being to only show facilities listed for the selected region.  What does not work is when editing a record, selecting the facilities shows all of the facilities grouped by region instead of constraining the facilities to the selected region.

If I select another region and then select the original reason, the proper list of facilities show up.

I'd like to learn how to refactor the CoffeeScript to where when editing the record the function is fired both on load and on change.

Here's what my code looks like:

calls.js.coffee

jQuery -&gt;
  facilities = $('#call_transfer_from_id').html()

  $('#call_region_id').change -&gt;
    region = $('#call_region_id :selected').text()
    options = $(facilities).filter("optgroup[label=#{region}]").html()

    if options
      $('#call_transfer_from_id').html(options)   
    else
      $('#call_transfer_from_id').empty()


region.rb

has_many :facilities


facility.rb

attr_accessible :region_id
belongs_to :region


_form.html.erb excerpt

 &lt;%= f.label :region %&gt;
  &lt;%= f.collection_select(:region_id, Region.all, :id, :area, {:include_blank =&gt; true}, {:class =&gt; 'select', required: true}) %&gt;
  &lt;%= f.label :Transfer_From %&gt;
  &lt;%= f.grouped_collection_select :transfer_from_id, Region.order(:area), :active_facilities, :area, :id, :facility_name, {include_blank: true}, class: 'select' %&gt;


If my question and examples are not clear, please let me know and I'll be happy to edit.
This is borderline Code Review material, since the code doesn't work as intended. It's not the same thing as "broken", because it does run, but what you're asking for is more or less a new feature.

(I'm also a little unsure of what you're asking, though I think I got it right. This isn't prose review, but you've got some run-on sentences in your question that are nigh impossible to read. Edit: That's been improved now)

Still, I'll give it shot regardless. 

First, when you use jQuery, remember to store things you'll use more than once - don't call $(...) again and again for the same selectors.

Second, store a clone of the facilities list element. Not the HTML string. You can just have an element in memory without having to to display it on the page. No need to reduce it a string, and parsing it every time you need something.

Third, I'd use a more precise identifier for the optgroups than the region name. It works, but I'd prefer using an integer ID or something. Unfortunately, grouped_collection_select doesn't have an option to do that (you'd have to write your own version), so I'll skip that here.

I'd extract a function to do the options-setting

$ -&gt; # on DOM ready

  # Grab the elements we'll need
  facilitySelect = $ "#call_transfer_from_id"
  regionSelect = $ "#call_region_id"

  # Make an in-memory clone of the facilities.
  # We'll use this as out "master list"
  facilitiesCopy = facilitySelect.clone()

  # A simple helper function to set the facility select's option
  # to match those in a named optgroup (again, we're cloing elments)
  setFacilityOptionsForSelectedRegion = -&gt;
    region = regionSelect.val()
    options = facilitiesCopy.find("optgroup[label='#{region}'] option").clone()
    facilitySelect.empty().append options

  # Call the function on region change
  regionSelect.on "change", setFacilityOptionsForSelectedRegion

  # and also just call it now that the page has loaded
  setFacilityOptionsForSelectedRegion()


I think that should work.

Edit: Here's a demo