On Jun 24, 2007, at 2:57 PM, Fernando P. wrote:
Ajax.Updater(‘ajaxWrapper’, ‘/pruebas/test’, {asynchronous:true,
evalScripts:true, parameters:‘text1=’ + value})}, ‘blur’)
//]]>
–
This code is from Rails 1.2.2, but you should be able to track this
down in your version if different.
The problem is that the documentation is simply wrong. Let’s look at
the code:
vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb:287:
def observe_field(field_id, options = {})
if options[:frequency] && options[:frequency] > 0
build_observer(‘Form.Element.Observer’, field_id, options)
else
build_observer(‘Form.Element.EventObserver’, field_id,
options)
end
end
line 662:
def build_observer(klass, name, options = {})
if options[:with] && !options[:with].include?(“=”)
options[:with] = “‘#{options[:with]}=’ + value”
else
options[:with] ||= ‘value’ if options[:update]
end
callback = options[:function] || remote_function(options)
javascript = "new #{klass}('#{name}', "
javascript << "#{options[:frequency]}, " if options[:frequency]
javascript << "function(element, value) {"
javascript << "#{callback}}"
javascript << ", '#{options[:on]}'" if options[:on]
javascript << ")"
javascript_tag(javascript)
end
public/javascripts/prototype.js:2124:
Abstract.EventObserver = function() {}
Abstract.EventObserver.prototype = {
initialize: function(element, callback) {
this.element = $(element);
this.callback = callback;
this.lastValue = this.getValue();
if (this.element.tagName.toLowerCase() == 'form')
this.registerFormCallbacks();
else
this.registerCallback(this.element);
},
onElementEvent: function() {
var value = this.getValue();
if (this.lastValue != value) {
this.callback(this.element, value);
this.lastValue = value;
}
},
registerFormCallbacks: function() {
Form.getElements(this.element).each(this.registerCallback.bind
(this));
},
registerCallback: function(element) {
if (element.type) {
switch (element.type.toLowerCase()) {
case ‘checkbox’:
case ‘radio’:
Event.observe(element, ‘click’, this.onElementEvent.bind
(this));
break;
default:
Event.observe(element, ‘change’, this.onElementEvent.bind
(this));
break;
}
}
}
}
Form.Element.EventObserver = Class.create();
Form.Element.EventObserver.prototype = Object.extend(new
Abstract.EventObserver(), {
getValue: function() {
return Form.Element.getValue(this.element);
}
});
So a Form.Element.EventObserver has an initialization function from
Abstract.EventObserver which looks like this (seen above also):
Abstract.EventObserver.prototype = {
initialize: function(element, callback) {
this.element = $(element);
this.callback = callback;
Notice that it only has two arguments. The third argument added by
the build_observer helper is not passed along to the prototype.js
function. The actual event is made wholly dependent on:
switch (element.type.toLowerCase()) {
which is just a fancy way of saying ‘change’ when that’s ‘click’ for
checkboxes and radio buttons.
Now, could the initialize function be changed in
Abstract.EventObserver to use the third argument as the event to
observe if provided and still fall back to using the element type?
Sure. But the moral of this story is that the code itself is the
most reliable place to find out how something works – don’t assume
that the documentation is always correct.
Of course, these very changes may have already been made in the most
recent versions of prototype and Rails, but I’ll leave that
investigation to the diligent reader.
-Rob
Rob B. http://agileconsultingllc.com
[email protected]