I''m trying to observe a field that get generated inside a fields_for loop (I''m trying to create the form dynamically depending on a selection value). Is there a way to access the index in the field_for loop? Thanks, Jay
Hi Jay, On Mon, 2009-08-17 at 14:24 -0700, Jay wrote:> I''m trying to observe a field that get generated inside a fields_for > loop (I''m trying to create the form dynamically depending on a > selection value). Is there a way to access the index in the field_for > loop?What do you mean by ''index''? The observe_field method takes a DOM id. If you''re having trouble, post the view and the page source that results. It''s very difficult to help with such sparse information. Best regards, Bill
OK, here''s an example of what I''m trying to do. _form.html.erb <%= form.error_messages %> <p> <%= form.label :title %><br /> <%= form.text_field :title %> </p> <p> <%= form.label :due_date %><br /> <%= form.datetime_select :due_date %> </p> <div id="tasks"> <h3>Tasks</h3> <% form.fields_for :tasks do |task_form| -%> <%= render :partial => ''task'', :locals => { :form => task_form } %> <% end -%> </div> <%= add_task_link(form) %> <p> <%= form.submit ''Save'' %> </p> And here''s the partial that gets called above (_task.html.erb) <div class="task"> <p> <%= form.label :name %> <%= form.text_field :name, :size => 15 %> <%= remove_task_link( form ) %> </p> <%= observe_field :project_tasks_attributes_0_name, :function => ''alert("field changed")'' %> </div> This doesn''t work because I need to change the observe_field name (:project_tasks_attributes_0_name) for each task. If I had 3 tasks, the then the observe_field names would be: :project_tasks_attributes_0_name :project_tasks_attributes_1_name :project_tasks_attributes_2_name I was wondering if there is a way to access the index of the task form loop to generate field names like the above. Thanks, Jay On Aug 17, 9:35 pm, bill walton <bwalton...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi Jay, > > On Mon, 2009-08-17 at 14:24 -0700, Jay wrote: > > I''m trying to observe a field that get generated inside a fields_for > > loop (I''m trying to create the form dynamically depending on a > > selection value). Is there a way to access the index in the field_for > > loop? > > What do you mean by ''index''? The observe_field method takes a DOM id. > If you''re having trouble, post the view and the page source that > results. It''s very difficult to help with such sparse information. > > Best regards, > Bill
Hi Jay, On Tue, 2009-08-18 at 07:32 -0700, jheaslip wrote:> OK, here''s an example of what I''m trying to do. > > _form.html.erb > > <%= form.error_messages %> > <p> > <%= form.label :title %><br /> > <%= form.text_field :title %> > </p> > <p> > <%= form.label :due_date %><br /> > <%= form.datetime_select :due_date %> > </p> > <div id="tasks"> > <h3>Tasks</h3> > <% form.fields_for :tasks do |task_form| -%> > <%= render :partial => ''task'', :locals => { :form => task_form } > %> > <% end -%> > </div> > <%= add_task_link(form) %> > <p> > <%= form.submit ''Save'' %> > </p> > > And here''s the partial that gets called above (_task.html.erb) > > <div class="task"> > <p> > <%= form.label :name %> > <%= form.text_field :name, :size => 15 %> > <%= remove_task_link( form ) %> > </p> > <%= observe_field :project_tasks_attributes_0_name, :function => > ''alert("field changed")'' %> > </div> > > This doesn''t work because I need to change the observe_field name > (:project_tasks_attributes_0_name) for each task. If I had 3 tasks, > the > then the observe_field names would be: > :project_tasks_attributes_0_name > :project_tasks_attributes_1_name > :project_tasks_attributes_2_name > > I was wondering if there is a way to access the index of the task form > loop to generate field names like the above.Good explanation. Thanks. A couple of suggestions re: approach. The first probably won''t work but it would be interesting to know. I wonder if do |task_form| could be replaced with each_with_index |task_form, i| both do and each take blocks. Probably won''t work, but... If you''re sure of the naming / order, then the easiest way would be something like (not tested)... <% index = 0 %> <% form.fields_for :tasks do |task_form| -%> <%= render :partial => ''task'', :locals => { :form => task_form, :index => index } %> <% index += 1 %> <% end -%> And then in the partial, using a string instead of a symbol... <%= observe_field "project_tasks_attributes_#{index}_name" ... Not terribly rubyish, I know, but something on that order should be workable ;-) HTH, Bill> Thanks, > Jay > > On Aug 17, 9:35 pm, bill walton <bwalton...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Hi Jay, > > > > On Mon, 2009-08-17 at 14:24 -0700, Jay wrote: > > > I''m trying to observe a field that get generated inside a fields_for > > > loop (I''m trying to create the form dynamically depending on a > > > selection value). Is there a way to access the index in the field_for > > > loop? > > > > What do you mean by ''index''? The observe_field method takes a DOM id. > > If you''re having trouble, post the view and the page source that > > results. It''s very difficult to help with such sparse information. > > > > Best regards, > > Bill > >
Hi Jay, I''ve just run into exactly the same problem, as I''m using jQuery to build autocompleters and need the generated field id for my observe_field call. I''ve looked all over for a way to access the index, but couldn''t find it anywhere. I decided to delve into the Rails code and found a couple of helper methods in the InstanceTagMethods moduke (http://github.com/rails/rails/blob/master/ actionpack/lib/action_view/helpers/form_helper.rb). The methods of interest are santized_object_name and sanitized_method_name. They take the FormHelper''s object_name (which is publically accessible) and return the generated form element id (e.g. person[attributes][0][name] becomes person_attributes_0_name). However, these methods are private to InstanceTagMethods, so you can''t get at them from within your fields_for block. The solution I''ve used is to duplicate these methods in my application_helper.rb, and call them from within my fields_for block: # app/helpers/application_helper.rb def sanitized_object_name(object_name) object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/,"_").sub(/_$/,"") end def sanitized_method_nam(method_name) method_name.sub(/\?$/, "") end def form_tag_id(object_name, method_name) "#{sanitized_object_name(object_name.to_s)}_#{sanitized_method_name (method_name.to_s)}" end Then in my fields_for partial: # app/views/people/_person_attributes.rb # wrapped in person_form,fields_for :attributes do |attributes_form| <%= f.text_field :name %> <%= observe_field form_tag_id(f.object_name, :name), ... %> This code works for index partials (i.e. those with absolute indexes) and those generated with timestamp indexes (I''m using a customised version of Ryan Bates'' latest nested form code for Rails 2.3 - http://github.com/ryanb/complex-form-examples). I''ll post this code on my site aswell. Hope this helps! If anyone knows a better way to access the form builder''s index, please follow up this post! Regards, Chris -- http://www.chrisblunt.com http://twitter.com/cblunt On Aug 17, 10:24 pm, Jay <jheas...-Wuw85uim5zDR7s880joybQ@public.gmane.org> wrote:> I''m trying to observe a field that get generated inside a fields_for > loop (I''m trying to create the form dynamically depending on a > selection value). Is there a way to access the index in the field_for > loop? > > Thanks, > Jay