0

I know this question gets asked a lot, but none of the solutions have helped. I have a select menu that works the first time no problem, but won't execute again until the page has reloaded.

<div class="dynamic">
<%= render 'status_selector' %>
</div>

This is what is inside the partial:

<%= form_for @report, :remote => true, :html => {:id => 'report-edit-status'} do |f| %>
    <%= f.hidden_field :report_id, :value => @report.id  %>
    <%= f.select(:status, STATUS, {},:class => "status-change-selector", :style => "font-size:1.1em;") %>
<% end %>

And here is the Application.js:

$('.status-change-selector').unbind('change');
$('.status-change-selector').change(function(event) {
    event.preventDefault();
    $(this).closest('form').submit();
});

Update.js.erb

$('.dynamic').html("<%= escape_javascript(render(:partial => 'reports/status_selector')).html_safe %>");

EDIT:

Based on Peter Goldstein's suggestion, I added a listener to a Parent element, so I don't need to add the Jquery code to my Update.js.erb. This is what I have in my Application.js now:

$('.dynamic').on('change', '.status-change-selector', function(event) {
    event.preventDefault();
    $(this).closest('form').submit();
});
fatfrog
  • 2,118
  • 1
  • 23
  • 46

1 Answers1

2

So your update is creating a new element to which your change event does not apply. The JS change binds to elements that exist at the time of execution. One easy way to fix the issue is to add:

$('.status-change-selector').unbind('change');
$('.status-change-selector').change(function(event) {
  event.preventDefault();
  $(this).closest('form').submit();
});

to the end of your Update.js.erb. That will bind the newly created DOM element. Other solutions which are more DRY are a little more complex, but basically involve attaching a listener to a parent element of the DOM you're inserting rather than to the element itself.

Peter Goldstein
  • 4,479
  • 2
  • 19
  • 17
  • Bam! That did it! 1 question - is this still considered "unobtrusive javascript"? – fatfrog Nov 20 '13 at 17:49
  • I'd probably say yes, because the JS isn't embedded in the HTML. Though as I mention, there are ways to DRY this up by adding the listener in the application.js to a parent DOM element. Then you don't need to duplicate the code. But the necessary listener is a little more complex. – Peter Goldstein Nov 20 '13 at 17:54