How to observe more fields with AJAX helper
The observe_field AJAX helper allows to observe one field; if there is a change, it calls the specified method on the server side. It is possible to attach one value for the call.
This is enough if we have one text box search for searching over multiple columns or for a full-text search.
For a more complicated filtering functionality with more fields there are two main problems with the observe_field helper:
- how to specify more parameter values in the observe_field helper.
- it is necessary to write a observe_field call for each field.
Added: Thanks to Ryan Bate and Benjamin, I found out there is a helper for the whole form: the observe_form helper. Basically my post is useless, except a few situations: if a form contains a lot of items and you would not like to send them all, or, and I am not 100% sure about this, if a form contains a file field (the file_field helper).
Let’s create a special observe_fields helper that will handle all this problems :)
More Parameter Values for observe_field Helper
Imagine a simplified case where we would like to observe two fields: first_name and last_name.
The standard usage of the observe_field helper is not sufficient:
-
<%= observe_field ‘first_name’, :frequency => 2,
-
:update => :result,
-
:before => "Element.show(’spinner’)",
-
:success => "Element.hide(’spinner’)",
-
:url => {:action => :list},
-
:with => first_name %>
-
<%= observe_field ‘last_name’, :frequency => 2,
-
:update => :result,
-
:before => "Element.show(’spinner’)",
-
:success => "Element.hide(’spinner’)",
-
:url => {:action => :list},
-
:with => last_name %>
This code will observe both fields, but it reckons without a fact, that a call to the server side has to provide both values — the filter functionality does not work correctly.
Well, I found several articles with instructions how to send more parameter values, but they did not work for me. Here is my code (yeah, it works fine):
-
:with => "’first_name=’+escape($(’first_name’).value) + ‘&last_name=’ + escape($(’last_name’).value)"
A new code that works fine:
-
<%= observe_field ‘first_name’, :frequency => 2,
-
:update => :result,
-
:before => "Element.show(’spinner’)",
-
:success => "Element.hide(’spinner’)",
-
:url => {:action => :list},
-
:with => "’first_name=’+escape($(’first_name’).value) + ‘&last_name=’ + escape($(’last_name’).value)" %>
-
<%= observe_field ‘last_name’, :frequency => 2,
-
:update => :result,
-
:before => "Element.show(’spinner’)",
-
:success => "Element.hide(’spinner’)",
-
:url => {:action => :list},
-
:with => "’first_name=’+escape($(’first_name’).value) + ‘&last_name=’ + escape($(’last_name’).value)" %>
but it is cumbersome. Well, all options can be defined separately, even so you have to write an observe_field call for each field. And to write a value of the :with option for more fields.. phew :)
observe_fields Helper
The observe_fields helper simplifies an observing of more fields. The example with two fields can be written with the new helper as follows:
-
<%= observe_fields [‘first_name’, ‘last_name’],
-
:frequency => 2,
-
:update => :customers,
-
:before => "Element.show(’spinner’)",
-
:success => "Element.hide(’spinner’)",
-
:url => {:action => :list} %>
The first parameter is an array of fields that will be observed, the second parameter is a list of options. A value of the :with option is set by the helper (if it is specified, it will be ignored) — it contains values of all observed fields.
All parameters are accessible normally in the list method, that is: @params[:first_name] or @params[:last_name].
The source code of the observe_fields helper:
-
def observe_fields(fields, options)
-
#prepare a value of the :with parameter
-
with = ""
-
for field in fields
-
with += "’"
-
with += "&" if field != fields.first
-
with += field + "=’+escape($(’" + field + "’).value)"
-
with += " + " if field != fields.last
-
end
-
-
#generate a call of the observer_field helper for each field
-
ret = "";
-
for field in fields
-
ret += observe_field(field,
-
options.merge( { :with => with }))
-
end
-
ret
-
end
Lines 3-9 contain a code that generates a value of the :with option, because it is the same for all fields. Lines 12-16 contain a code that generates calls of the observe_field helper for each field with the pre-generated value of the :with option.
Added: If you need to handle Unicode characters, you should read how to get a parameter value in a controller from my newer post Observing more fields with AJAX helper and Unicode.
Conclusion
We created a observe_fields helper that extends the existing observe_field helper with a support to observe more fields. The specified method on the server side is called with values of all fields.










