Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I make the javascript in my Rails 3 form unobtrusive?
    primarykey
    data
    text
    <p>I'm a rails newbie attempting to make an app for managing translations of sets of labels using Rails 3. I haven't gotten too far past scaffolding so as far as I know I'm using Rails 3's default javascript libraries (ie prototype, not jQuery).</p> <p>I have a form for the names of the label sets, and the desired behaviour is for the names of all current label sets to be populated in a drop-down list (<code>"label_sets"</code>), and when you select one, it populates the <code>:name</code> text field (<code>$('label_set_name')</code>) and disables it. If the drop-down displays the <code>:include_blank</code> value, a new label set name can be entered. When the form is submitted, the <code>:name</code> text field gets re-enabled so its value will actually get saved.</p> <p>This form does perform the desired behaviour, but I think there must be a way to refactor the javascript in <code>:onsubmit</code> and <code>:onchange</code> into another file(s) and make it unobtrusive. I've scoured the web for material on making unobtrusive javascript in Rails 3, but have honestly been confused by a lot of it and don't know how to apply it to my case. Could anyone please offer any suggestions? The abbreviated source for my label set form is below:</p> <pre><code># app/views/label_sets/_form.html.erb &lt;%= form_for(@label_set, :html =&gt; { :onsubmit =&gt; "$('label_set_name').enable();" }) do |f| %&gt; # ... &lt;div class="field"&gt; &lt;%= label "label_sets", t('.label_set') %&gt;&lt;br /&gt; &lt;%= select_tag("label_sets", options_for_select(LabelSet::NAMES), { :include_blank =&gt; t('.new'), :onchange =&gt; "if (this.value.empty()) { $('label_set_name').clear(); $('label_set_name').enable(); } else { $('label_set_name').value = this.value; $('label_set_name').disable(); }" }) %&gt;&lt;br /&gt; &lt;/div&gt; &lt;div class="field"&gt; &lt;%= f.label :name %&gt;&lt;br /&gt; &lt;%= f.text_field :name %&gt; &lt;/div&gt; # ... &lt;% end %&gt; </code></pre> <p><strong>Update</strong>: So I think I solved my problem, or at least got my form view looking cleaner, by taking all the javascript out and stuffing it into <code>application.js</code> (and wrote it up in jQuery just to try out something new).</p> <p>The new form view looks like:</p> <pre><code># app/views/label_sets/_form.html.erb &lt;%= form_for(@label_set) do |f| %&gt; # ... &lt;div class="field"&gt; &lt;%= label "label_sets", t('.label_set') %&gt;&lt;br /&gt; &lt;%= select_tag("label_sets", options_for_select(LabelSet::NAMES), { :include_blank =&gt; t('.new') }) %&gt;&lt;br /&gt; &lt;/div&gt; &lt;div class="field"&gt; &lt;%= f.label :name %&gt;&lt;br /&gt; &lt;%= f.text_field :name %&gt; &lt;/div&gt; # ... &lt;% end %&gt; </code></pre> <p>The new <code>application.js</code> looks like: </p> <pre><code># public/javascripts/application.js $(function() { $('.new_label_set, .edit_label_set').submit(function() { if ($('#label_set_name').attr('disabled') == true) { $('#label_set_name').removeAttr('disabled'); } }); $('#label_sets').change(function() { if ($(this).val() == '') { $('#label_set_name').val(''); $('#label_set_name').removeAttr('disabled'); } else { $('#label_set_name').val($(this).val()); $('#label_set_name').attr('disabled', true); } }); }); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload