# Using observe\_field on an field inside a fields\_for

**URL:** <https://www.ruby-forum.com/t/using-observe-field-on-an-field-inside-a-fields-for/173898>\
**Category:** Rails\
**Created:** [August 17, 2009, 11:25pm UTC](https://www.ruby-forum.com/t/using-observe-field-on-an-field-inside-a-fields-for/173898 "2009-08-17T23:25:27Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ed8c4c/32.png) [@jay](https://www.ruby-forum.com/u/jay)\
**Post date:** [August 17, 2009, 11:25pm UTC](https://www.ruby-forum.com/t/using-observe-field-on-an-field-inside-a-fields-for/173898/1 "2009-08-17T23:25:27Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![jay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ed8c4c/32.png) [@jay](https://www.ruby-forum.com/u/jay)\
**Post date:** [August 18, 2009, 3:34am UTC](https://www.ruby-forum.com/t/using-observe-field-on-an-field-inside-a-fields-for/173898/2 "2009-08-18T03:34:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![jay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ed8c4c/32.png) [@jay](https://www.ruby-forum.com/u/jay)\
**Post date:** [August 18, 2009, 4:33pm UTC](https://www.ruby-forum.com/t/using-observe-field-on-an-field-inside-a-fields-for/173898/3 "2009-08-18T16:33:22Z")

</div>

OK, here’s an example of what I’m trying to do.

\_form.html.erb

\<%= form.error\_messages %\>

\<%= form.label :title %\>  
 \<%= form.text\_field :title %\>

\<%= form.label :due\_date %\>  
 \<%= form.datetime\_select :due\_date %\>

### Tasks
 \<% form.fields\_for :tasks do |task\_form| -%\> \<%= render :partial =\> 'task', :locals =\> { :form =\> task\_form } %\> \<% end -%\>
\<%= add\_task\_link(form) %\>

\<%= form.submit 'Save' %\>

And here’s the partial that gets called above (\_task.html.erb)

\<%= form.label :name %\> \<%= form.text\_field :name, :size =\> 15 %\> \<%= remove\_task\_link( form ) %\>

 \<%= observe\_field :project\_tasks\_attributes\_0\_name, :function =\> 'alert("field changed")' %\>

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

---

<div class="post-metadata">

**Author:** ![jay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ed8c4c/32.png) [@jay](https://www.ruby-forum.com/u/jay)\
**Post date:** [October 7, 2009, 11:27am UTC](https://www.ruby-forum.com/t/using-observe-field-on-an-field-inside-a-fields-for/173898/4 "2009-10-07T11:27:10Z")

</div>

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/](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 B.’ latest nested form code for Rails 2.3 -  
[GitHub - ryanb/complex-form-examples: Various ways to handle multi-model forms in Rails.](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://www.chrisblunt.com)  
[http://twitter.com/cblunt](http://twitter.com/cblunt)

---

<div class="post-metadata">

**Author:** ![jay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ed8c4c/32.png) [@jay](https://www.ruby-forum.com/u/jay)\
**Post date:** [August 18, 2009, 7:49pm UTC](https://www.ruby-forum.com/t/using-observe-field-on-an-field-inside-a-fields-for/173898/5 "2009-08-18T19:49:34Z")

</div>

Hi Jay,

On Tue, 2009-08-18 at 07:32 -0700, jheaslip wrote:

> \<%= form.label :due\_date %\>
> 
> :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
