require File.dirname(__FILE__) + '/tag_helper'
module ActionView
module Helpers
# Provides a set of helpers for calling Javascript functions and, most importantly, to call remote methods using what has
# been labelled Ajax[http://www.adaptivepath.com/publications/essays/archives/000385.php]. This means that you can call
# actions in your controllers without reloading the page, but still update certain parts of it using injections into the
# DOM. The common use case is having a form that adds a new element to a list without reloading the page.
#
# To be able to use the Javascript helpers, you must either call <%= define_javascript_functions %> (which returns all
# the Javascript support functions in a '
end
# Observes the field with the DOM ID specified by +field_id+ and makes
# an Ajax when its contents have changed.
#
# Required +options+ are:
# :frequency:: The frequency (in seconds) at which changes to
# this field will be detected.
# :url:: +url_for+-style options for the action to call
# when the field has changed.
#
# Additional options are:
# :update:: Specifies the DOM ID of the element whose
# innerHTML should be updated with the
# XMLHttpRequest response text.
# :with:: A Javascript expression specifying the
# parameters for the XMLHttpRequest. This defaults
# to 'value', which in the evaluated context
# refers to the new field value.
#
# Additionally, you may specify any of the options documented in
# +link_to_remote.
def observe_field(field_id, options = {})
build_observer('Form.Element.Observer', field_id, options)
end
# Like +observe_field+, but operates on an entire form identified by the
# DOM ID +form_id+. +options+ are the same as +observe_field+, except
# the default value of the :with option evaluates to the
# serialized (request string) value of the form.
def observe_form(form_id, options = {})
build_observer('Form.Observer', form_id, options)
end
# Escape carrier returns and single and double quotes for Javascript segments.
def escape_javascript(javascript)
(javascript || '').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
end
private
def options_for_ajax(options)
js_options = build_callbacks(options)
js_options['asynchronous'] = options[:type] != :synchronous
js_options['method'] = options[:method] if options[:method]
js_options['insertion'] = "Insertion.#{options[:position].to_s.camelize}" if options[:position]
if options[:form]
js_options['parameters'] = 'Form.serialize(this)'
elsif options[:with]
js_options['parameters'] = options[:with]
end
'{' + js_options.map {|k, v| "#{k}:#{v}"}.join(', ') + '}'
end
def build_observer(klass, name, options = {})
options[:with] ||= 'value' if options[:update]
callback = remote_function(options)
javascript = '"
end
def build_callbacks(options)
CALLBACKS.inject({}) do |callbacks, callback|
if options[callback]
name = 'on' + callback.to_s.capitalize
code = options[callback]
callbacks[name] = "function(request){#{code}}"
end
callbacks
end
end
end
end
end