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).
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 ("label_sets"
), and when you select one, it populates the :name
text field ($('label_set_name')
) and disables it. If the drop-down displays the :include_blank
value, a new label set name can be entered. When the form is submitted, the :name
text field gets re-enabled so its value will actually get saved.
This form does perform the desired behaviour, but I think there must be a way to refactor the javascript in :onsubmit
and :onchange
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:
# app/views/label_sets/_form.html.erb
<%= form_for(@label_set,
:html => { :onsubmit => "$('label_set_name').enable();" }) do |f| %>
# ...
<div class="field">
<%= label "label_sets", t('.label_set') %><br />
<%= select_tag("label_sets",
options_for_select(LabelSet::NAMES),
{ :include_blank => t('.new'),
:onchange => "if (this.value.empty()) {
$('label_set_name').clear();
$('label_set_name').enable();
} else {
$('label_set_name').value = this.value;
$('label_set_name').disable();
}" }) %><br />
</div>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
# ...
<% end %>
Update: 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 application.js
(and wrote it up in jQuery just to try out something new).
The new form view looks like:
# app/views/label_sets/_form.html.erb
<%= form_for(@label_set) do |f| %>
# ...
<div class="field">
<%= label "label_sets", t('.label_set') %><br />
<%= select_tag("label_sets",
options_for_select(LabelSet::NAMES),
{ :include_blank => t('.new') }) %><br />
</div>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
# ...
<% end %>
The new application.js
looks like:
# 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);
}
});
});