On the front page of my rap lyrics explanation site, there's a place where users can try explaining a challenging line:
alt text http://dl.dropbox.com/u/2792776/screenshots/2010-02-06_1620.png
Here's the partial I use to generate this:
<div class="stand_alone annotation" data-id="<%= annotation.id %>">
<%= song_link(annotation.song, :class => :title) %>
<span class="needs_exegesis"><%= annotation.referent.strip.gsub(/\n/, "\n <br />") %></span>
<% form_for Feedback.new(:annotation_id => annotation.id, :created_by_id => current_user.try(:id), :email_address => current_user.try(:email)), :url => feedback_index_path, :live_validations => true do |f| %>
<%= f.hidden_field :annotation_id %>
<%= f.hidden_field :created_by_id %>
<p style="margin-top: 1em">
<%= f.text_area :body, :rows => 4, :style => 'width:96%', :example_text => "Enter your explanation" %>
</p>
<p>
<% if current_user %>
<%= f.hidden_field :email_address %>
<% else %>
<%= f.text_field :email_address, :example_text => "Your email address" %>
<% end %>
<%= f.submit "Submit", :class => :button, :style => 'margin-left: .1em;' %>
</p>
<% end %>
</div>
However, putting more than one of these on a single page is problematic because Rails automatically gives each form an ID of new_feedback
, and each field an ID like feedback_body
(leading to name collisions)
Obviously I could add something like :id => ''
to the form and all its fields, but this seems a tad repetitive. What's the best way to do this?
If you don't want to change your input names or your model structure, you can use the id
option to make your form ID unique and the namespace
option to make your input IDs unique:
<%= form_for Feedback.new(...),
id: "annotation_#{annotation.id}_feedback"
namespace: "annotation_#{annotation.id}" do |f| %>
That way our form ID is unique, i.e. annotation_2_feedback
and this will also add a prefix, e.g. annotation_2_
, to every input created through f
.
Did you consider nested_attributes for rails models? Instead of having multiple new
feedback forms where each is tied to an annotation, you could have multiple edit
annotation forms where each annotation includes fields for a new feedback. The id's of the generated forms would include the annotations id such as edit_annotation_16
.
The annotation model would have a relationship to its feedbacks and will also accept nested attributes for them.
class Annotation < ActiveRecord::Base
has_many :feedbacks
accepts_nested_attributes_for :feedbacks
end
class Feedback < ActiveRecord::Base
belongs_to :annotation
end
You could then add as many forms as you want, one for each annotation. For example, this is what I tried:
<% form_for @a do |form| %>
Lyrics: <br />
<%= form.text_field :lyrics %><br />
<% form.fields_for :feedbacks do |feedback| %>
Feedback: <br/>
<%= feedback.text_field :response %><br />
<% end %>
<%= form.submit "Submit" %>
<% end %>
<% form_for @b do |form| %>
Lyrics: <br />
<%= form.text_field :lyrics %><br />
<% form.fields_for :feedbacks do |feedback| %>
Feedback: <br/>
<%= feedback.text_field :response %><br />
<% end %>
<%= form.submit "Submit" %>
<% end %>
And the quick and dirty controller for the above edit view:
class AnnotationsController < ApplicationController
def edit
@a = Annotation.find(1)
@a.feedbacks.build
@b = Annotation.find(2)
@b.feedbacks.build
end
def update
@annotation = Annotation.find(params[:id])
@annotation.update_attributes(params[:annotation])
@annotation.save!
render :index
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With