require File.dirname(__FILE__) + '/tag_helper'
module ActionView
module Helpers
# You must call <%= define_javascript_functions %> in your application before using these helpers.
module JavascriptHelper
# Returns a link that'll trigger a javascript +function+ using the onclick handler and return false after the fact.
#
# Examples:
# link_to_function "Greeting", "alert('Hello world!')"
# link_to_function(image_tag("delete"), "if confirm('Really?'){ do_delete(); }")
def link_to_function(name, function, html_options = {})
content_tag(
"a", name,
html_options.symbolize_keys.merge(:href => "#", :onclick => "#{function}; return false;")
)
end
# Returns a link to a remote action defined by options[:url] (using the url_for format) that's called in the background
# using XMLHttpRequest. The result of that request can then be inserted into a DOM object who's id can be specified
# with options[:update]. Usually, the result would be a partial prepared by the controller with either render_partial
# or render_partial_collection.
#
# Examples:
# link_to_remote "Delete this post", :update => "posts", :url => { :action => "destroy", :id => post.id }
# link_to_remote(image_tag("refresh"), :update => "emails", :url => { :action => "list_emails" })
#
# By default, these remote requests are processed asynchronous during which various callbacks can be triggered (for progress indicators
# and the likes).
#
# Example:
# link_to_remote word,
# :url => { :action => "undo", :n => word_counter },
# :complete => "undoRequestCompleted(request)"
#
# The complete list of callbacks that may be specified are:
#
# * :uninitialized -- EXPLAIN ME!
# * :loading -- EXPLAIN ME!
# * :loaded -- EXPLAIN ME!
# * :interactive -- EXPLAIN ME!
# * :complete -- EXPLAIN ME!
#
# If you for some reason or another needs synchronous processing (that'll block the browser while the request is happening), you
# can specify options[:type] = :sync.
def link_to_remote(name, options = {}, html_options = {})
link_to_function(name, remote_function(options), html_options)
end
def form_remote_tag(options = {})
options[:form] = true
options[:html] ||= { }
options[:html][:onsubmit] = "#{remote_function(options)}; return false;"
tag("form", options[:html], true)
end
def remote_function(options)
callbacks = build_callbacks(options)
function = options[:update] ?
"update_with_response('#{options[:update]}', " :
"xml_request("
function << "'#{url_for(options[:url])}'"
function << ', Form.serialize(this)' if options[:form]
function << ', null' if !options[:form] && callbacks
function << ", true" if callbacks || options[:type] != :sync
function << ", #{callbacks}" if callbacks
function << ')'
function = "#{options[:before]}; #{function}" if options[:before]
function = "#{function}; #{options[:after]}" if options[:after]
function = "if (#{options[:condition]}) { #{function}; }" if options[:condition]
return function
end
def define_javascript_functions
<<-EOF
EOF
end
private
def build_callbacks(options)
callbacks = nil
%w{uninitialized loading loaded interactive complete}.each do |cb|
cb = cb.to_sym
if options[cb]
callbacks ? callbacks << "," : callbacks = "{"
callbacks <<
"#{cb}:function(request){#{options[cb].gsub(/"/){'\"'}}}"
end
end
callbacks << "}" if callbacks
callbacks
end
end
end
end