Get updates

Scott Q&A: How to Set a Form’s ID in Rails?

HTML is not hard. Anyone who can program, in any language, should be able to write HTML with little or no training. Yet there are reasons why the HTML helper functions in Rails can be handy. Chief among them is the easy and fairly clean way you can incorporate variables and other constructs; after all, the idea here is to have an app generate some of the code rather than having to write every piece by hand.

I was happily marching to the tune of form_tag() when I decided that I wanted a little JavaScript function to interact with the form’s contents. Great, except the HTML form code being generated by that helper function wasn’t coming with its own id attribute.

I could probably have the JavaScript function refer to this particular form by indexing an array, but then it could break if I ever changed the layout of the page to include another form. Hardly ideal.

Question: How does one tell Rails what the form’s id should be when creating the form with the helper function (or the Ajax form_remote_tag)?

Answer: Unfortunately this is an area where my trusty rails book fell flat. Maybe they’ve answered this one in the second edition, I don’t have it yet. Google to the rescue, providing the answer on this archived list discussion.

Include an :html hash with the parameters and you’ll be able to set the form’s id, for example. I haven’t seen documentation on the attributes which work in that hash, but code like this:

<%= form_remote_tag(:url => { :action => :create }, :update => 'main_list', :position => :bottom, :html => {:id => 'main_input' }) %>

results in HTML output like this:

<form action="/list/create" id="main_input" method="post" onsubmit="new Ajax.Request('/list/create', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">

Update (20070127): I played with the :html hash a little more and it turns out that it will accept arbitrary attributes; for example this:

<%= form_tag({ :action => :create }, { :yummy => 'yumminess' }) %>

…sets a yummy attribute in the form tag. Of course certain attributes that are already in use (such as :onsubmit for the Ajax version) get overwritten, but otherwise any valid HTML attribute should be fine.

19 Responses to “Q&A: How to Set a Form’s ID in Rails?”

  1. jennifer Says:

    i am trying to do something similar, but perhaps really wrongheaded. i want to call a javascript function on a rails submit; before the form is submitted i want to dynamically add fields and then send their values. i’d love to use an ajax remote_form_tag to generate the form. i’ve been looking at the html options hash also but can’t find any way of doing something like :onsubmit => “call javascript function”.

    do you have any thoughts on this? any help would be much appreciated.

    thanks,
    jen

  2. Jen:

    With a standard form you can do this:

    <%= form_tag({ :action => :create }, { :onsubmit => 'function call' }) %>

    However you probably noticed that if you try using :onsubmit with form_remote_tag(), your event handler gets replaced with the Ajax handler set up by Rails.

    One option for Ajax may be to use the :before callback, which should allow you to call a function before the request is made. I haven’t tested it, but that may be what you’re looking for.

  3. Thanks! This really helped me. My book doesn’t mention the :html hash either.

  4. You’re welcome, glad you found it useful Jonathon!

  5. Thank You

  6. Jon Says:

    Thanks! Just the trick.

  7. You bet, and thanks for stopping by Jon!

  8. Cosmo Says:

    Note: your follow-up post was for the ‘form_tag’ helper, not the ‘form_remote_tag’ helper used in the original post.

    Here’s my question – once you’ve passed the value, say by { :yummy => ‘yumminess’ }, how do you then access the values in the controller?

    I’ve tried params[:yummy], but it doesn’t seem to be there. I know it’s hiding in there somewhere…Thanks

  9. Cosmo:

    The original post features both form_tag and form_remote_tag, as the :html hash applies to both.

    The :yummy => ‘yumminess’ example was only included in the post to point out that you can add any arbitrary attributes (you could potentially interact with some JavaScript frameworks in this way).

    To work with a form value in your Rails controller you could use params[:yummy], assuming your form has an input (like a textbox) named “yummy”.

  10. Cosmo Says:

    Scott:

    Hmmm, please forgive my newbie-ness, perhaps I’m misunderstanding or maybe making a beginner’s error…

    Here I’m passing the arbitrary value :element_id via the form as you describe, via the :html hash. I then try to access the value from the controller via params[:element_id]. But the value comes up blank for me when I write it out to the logger. The value for :element_id doesn’t appear in params[] at all..

    view:

    {:action => ‘remove_element’}, :html=> {:element_id => ‘STUFF’} ) do %>

    controller:

    def remove_element
    element_id = params[:element_id]
    logger.info “element_id is #{element_id}”
    logger.info( ‘params[]: ‘ + params.to_a.join(‘, ‘) )
    end

    log:

    element_id is
    params[]: commit, Submit, answer, Default Answer, authenticity_token, NMX9HWoXEFrz4qDXvx6SpRnM2Z73bapzn1NBRO2JPvc=, action, remove_element, controller, set

    Am I misunderstanding something here??

  11. Cosmo Says:

    Hmm, that view code got munged by the post -try again:

    {:action => ‘remove_element’}, :html=> {:element_id => ‘STUFF’} ) do %>

  12. Cosmo Says:

    Lemme try escaping the darts w/ backslash…

    \ {:action => ‘remove_element’}, :html=> {:element_id => ‘STUFF’} ) do %\>

    \
    \
    \

  13. Cosmo Says:

    Grrrrr….. How do I de-munge HTML tags in these posts? Here it is w/o the ERB tag darts:

    % form_remote_tag( :url=> {:action => ‘remove_element’}, :html=> {:element_id => ‘STUFF’} ) do %

    %= text_field_tag :answer, ‘Default Answer’ %
    %= submit_tag ‘Submit’ %
    % end %

  14. Yeah, I don’t have a good plugin for handling code in the comments on the blog yet – and I’m sorry the comment form doesn’t state such limitations.

    I’m probably not doing a good job explaining – in your controller action that’s receiving the form submission you can receive a value for each input in the form’s HTML.

    So from the controller, the action can assign:

    element_id = params[:element_id]

    To be able to do that, your HTML might look something like:

    <form action="...">
      <input name="element_id" type="...">
      ...
    </form>

    But with Rails your forms are usually built around creating or editing a model object. This means your form HTML is probably going to look more like this:

    <form action="...">
      <input name="element[id]" type="...">
      ...
    </form>

    In turn, to produce that HTML your view could contain code looking a little like:

    <% form_for(@element) do |f| %>
      <%= f.text_field :id ... %>
      ...
      <%= f.submit "Submit" %>

    And then in your controller you can just do:

    element_like = params[:element]

    If you just want the data as some bare object; instead you’ll probably want to instantiate a model object, and probably store it in an instance var too:

    @element = Element.new(params[:element])

    You might take a look at the Rails API docs for more examples with text_field.

    Hope this helps.

  15. Cosmo Says:

    Scott:

    Ah, I see that we’re talking about different directions of communication. In the case you are talking about, you’re addressing passing the id from Rails to the HTML code (via the :html option of the view code).

    In my case I want to communicate the form’s id upon submission to the rails controller. This is so that I can run some JS code to interact with the element (specifically to delete the form from the web page).

    I’ve been doing this in the view via the :url option like this:

    % form_remote_tag :url=> { :action => ‘remove_element’, :element_id => id } do %

    In the controller I then delete the form from the web page:

    def remove_element
    page.remove element_id
    end

    What I’m wondering is whether I’m doing unnecessary work? Do I need to manually pass the id of the form to the controller like this or is there some other Rails-magical way that automatically makes information (such as form and element ids) available to the controller?

    I don’t see any such data in the params[] hash, but perhaps I’m overlooking something?

    I’m not crazy about the way I’m doing it because the element id appears in the URL. Perhaps it should be in a hidden field so it’s passed in the POST data?

    What would be the “Rails way” of doing this?

    TIA

  16. Okay, I think I see where you’re trying to get to.

    In my opinion this is something that should be handled purely in JavaScript, you don’t need to get the server involved (beyond the usual form submission/Ajax request), and it’s simpler too.

    If you’re using Prototype you just do something like this in the onSuccess callback of your Ajax.request:

    $('form_id').remove();

    Of course, that assumes you’re comfortable writing a bit of JavaScript, including some unobtrusive code to, say, observe the form’s submit event and send the Ajax request yourself. It’s not the only option but that’s the route I’d recommend.

  17. Gregory House Says:

    This helped thanks. I was stuck with html5 validation interfering with my rails validation. So I added the no validate attribute to my form.

    :html => { :novalidate => ‘novalidate’ }

  18. ddf skin care benzoyl peroxide

    Q&A: How to Set a Form?s ID in Rails? – Development – 3DM Design

  19. visage Instant Lift reviews

    Q&A: How to Set a Form?s ID in Rails? – Development – 3DM Design

Leave a Reply


Fatal error: Call to undefined function show_subscription_checkbox() in /home/dmetro/3dmdesign.com/wp-content/themes/hex_columns/comments.php on line 90