Form builders in Rails: field names and ids for Javascript

I came up with a few convenience methods today which will help you discover what Rail’s generated NAME and ID attributes will be for a specific field on a given form builder object. Actually, I didn’t come up with them so much as extract them from the built in form builder. It was useful enough to me that I thought I might share my discovery. I can’t tell you how many times I’ve lazily hardcoded an ID onto a form element just to bypass the defaults.

Throw these 2 methods in your ApplicationHelper module:

def field_id_for_js(builder, attribute)
  "#{builder.object_name}[#{attribute.to_s.sub(/\?$/,"")}]".gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
end

def field_name_for_js(builder, attribute)
  "#{builder.object_name}[#{attribute.to_s.sub(/\?$/,"")}]"
end

Here is an example using Rails nested attribute forms:

<%= form_for(@submission) do |f| %>
  <%= f.fields_for :project, @submission.project do |builder| %>

    <div class="field">
      <%= builder.label :classified, "Classified?" %><br/>
      <%= builder.radio_button :classified, false %> <%= builder.label :classified_false, "No" %>
      <%= builder.radio_button :classified, true %>  <%= builder.label :classified_true, "Yes" %>
    </div>

    <%= content_for(:head) do %>
      <script>
        $(function() {
          // get our value by name
          $("input[name='<%= field_name_for_js(builder, :classified) %>']").val();
          // set our value by ID
          $("#<%= field_id_for_js(builder, :classified_true) %>").attr('checked', true);
        });
      </script>
    <% end %>

  <% end %>
<% end %>

Would output:

<script>
  $(function() {
    // get our value by name
    $("input[name='submission[project_attributes][classified]']").val();
    // set our value by ID
    $("#submission_project_attributes_classified_true").attr('checked', true);
  });
</script>

In case you missed it …

<%= field_name_for_js(builder, :classified) %>
<%= field_id_for_js(builder, :classified_true) %>

… produced …

submission[project_attributes][classified]
submission_project_attributes_classified_true

Pretty handy stuff

comments powered by Disqus