Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating unique HTML ids in Rails when using a repeated partial that has form_for

I have a view on my current project which does something like the following(in haml):

[email protected] do |horse|
  = render :partial => 'main/votingbox', :locals => {:horse => horse}

The in the _votingbox.html.haml file I have the following:

%div.votingbox
  %span.name= horse.name
  %div.genders
    - if horse.male
      %img{:src => 'images/male.png', :alt => 'Male'} 
    - if horse.female
      %img{:src => 'images/female.png', :alt => 'Female'}
  %div.voting_form
    = form_for(Vote.new, {:url => horse_vote_path(horse)}) do |f|
      = f.label :comment, "Your opinion"
      = f.text_field :comment
      ...
      a bunch of labels and input elements follow generated using the form helpers

This will generate working code but it does generate forms with the same ids for all the form elements which makes the HTML invalid once the votingbox partial is rendered a second time.

My first guess at fixing this was to specify a unique :id to form_for but that only applies to the form tag generated by form_for and not any of the tags inside the form_for block.

One definite solution to this problem is to go through and manually define my own unique ids on form_for and all the form elements I use. This is more work than I had hoped for.

Is there an easier or cleaner way to get unique ids in a similar format to the way Rails currently generates them on all my form elements?

like image 342
cyberkni Avatar asked Oct 31 '10 18:10

cyberkni


2 Answers

I have removed the original answer as it is totally irrelevant to the updated version of the question.

Update: So now we know that you have an unsaved ActiveRecord object passed to the form_for call, the answer becomes simple: You can override any parameter that form_for generates. That includes the element id. And fields_for sets the context for a specific record.

= form_for(Vote.new, :url => horse_vote_path(horse), :id => dom_id(horse, 'vote')) do |f|
  = f.fields_for horse, :index => horse do |fh|
    = fh.text_field :whatever
    …
like image 154
edgerunner Avatar answered Oct 24 '22 02:10

edgerunner


You can override the autogenerated ids and names of all form_for content with :as like the following:

= form_for(Vote.new, :as => horse.name, {:url => horse_vote_path(horse)}) do |f|
  = f.label :comment, "Your opinion"
  = f.text_field :comment

So if a given horse.name is foobar, it will generate a comment field whose id is foobar_comment and name is foobar[comment]

But remember to make sure that the dynamic parameter is acceptable as an html id, a horse.name like hor$e is not acceptable as an html id and therefore might break something.

P.S: Sorry for answering very late, but at the time the question was asked, I haven't had learnt anything at all about rails! hope that might help someone out there!

like image 21
Tamer Shlash Avatar answered Oct 24 '22 04:10

Tamer Shlash