Assume I have a vanilla form containing a selection list and a submit button:
<%= form_for(@report :url => report_path) do |f| %>
<%= f.select(:sort_by, options_for_select(Report.SORT_OPTIONS, @report.sort_by)) %>
<%= f.submit 'sort' %>
<% end %>
Works fine, except that the user has to first make a selection and then click ‘sort’. What I’d really like is to have the action triggered when the user makes a selection and to ditch the ‘sort’ button altogether. This feels like a perfect use case for unobtrusive jQuery.
So [based on responses from @Dennis and @ethan below], before this form_for I added:
<%= javascript_include_tag(:defaults) %>
<script type="text/javascript">
$(document).ready(function() {
var $select = $('#report_sort_by'),
$form = $select.closest('form');
// $('[type="submit"]', $form).attr('type', 'hidden'); // gives error
$('[type="submit"]', $form).hide(); // works
$select.change(function() { $form.submit(); });
});
</script>
So is it considered right to plunk javascript right into the .html.erb file? Or is it better to put this in a separate .js file, and if so, what are the conventions for paramaterizing and naming the .js file?
For a few reputation points, can someone show me and all the other tyros how to do this?
Rails will stringify the object & property you’re using, so the select menu would have
id="report_sort_by". Which means you could use:If you want to include this code in a robust, unobtrusive way, you could make a file called maybe MyProject.Report.js and put this code in it:
Then in your .erb file (at the bottom, after the form) you could add
<script type="text/javascript">MyProject.Report.init();</script>and then, of course, add thejavascript_include_tagto include the JS file itself.There’s a bunch of different ways you could do your namespacing & encapsulation. The
MyProject.Reportobject that I describe above has the chief advantage of being incredibly straightforward. As your code grows, you just add new functionality inside theMyProject.Reportobject like:And then you basically hack away at that until you’re knowledgeable enough to decide whether you need a framework like backbone.js for a given project 🙂