aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-03-14 12:47:38 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-03-14 12:47:38 +0000
commit8d646006db8cd3f2e5074deab4618120089020c6 (patch)
tree7046f871864d62bc859dd30ae6867f49bd722ee0 /actionpack
parent193edfbfdbaffff177c44f70f15450390741b7d2 (diff)
downloadrails-8d646006db8cd3f2e5074deab4618120089020c6.tar.gz
rails-8d646006db8cd3f2e5074deab4618120089020c6.tar.bz2
rails-8d646006db8cd3f2e5074deab4618120089020c6.zip
Added asynchronous processing model
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@902 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb77
1 files changed, 71 insertions, 6 deletions
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index 023d67fd48..5d87c85647 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -24,6 +24,23 @@ module ActionView
# 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" })
+ #
+ # Asynchronous requests may be made by specifying a callback function
+ # to invoke when the request finishes.
+ #
+ # Example:
+ # link_to_remote word,
+ # :url => { :action => "undo", :n => word_counter },
+ # :before => "if(!prepareForUndo()) return false",
+ # :complete => "undoRequestCompleted(request)"
+ #
+ # The complete list of callbacks that may be specified are:
+ #
+ # * uninitialized
+ # * loading
+ # * loaded
+ # * interactive
+ # * complete
def link_to_remote(name, options = {}, html_options = {})
link_to_function(name, remote_function(options), html_options)
end
@@ -64,21 +81,47 @@ module ActionView
var container = o(arguments[0]);
var url = arguments[1];
var parameters = arguments[2];
-
- container.innerHTML = xml_request(url, parameters);
+ var async = arguments[3];
+
+ if (async) {
+ xml_request(url, parameters, true,
+ { complete: function(request) {
+ container.innerHTML = request.responseText }
+ })
+ } else {
+ container.innerHTML = xml_request(url, parameters);
+ }
}
function xml_request() {
var url = arguments[0];
var parameters = arguments[1];
var async = arguments[2];
+ var callbacks = arguments[3];
var type = parameters ? "POST" : "GET";
req = xml_http_request_object();
req.open(type, url, async);
+
+ if (async) {
+ invoke_callback = function(which) {
+ if(callbacks && callbacks[which]) callbacks[which](req)
+ }
+
+ req.onreadystatechange = function() {
+ switch(req.readyState) {
+ case 0: invoke_callback('uninitialized'); break
+ case 1: invoke_callback('loading'); break
+ case 2: invoke_callback('loaded'); break
+ case 3: invoke_callback('interactive'); break
+ case 4: invoke_callback('complete'); break
+ }
+ }
+ }
+
req.send(parameters ? parameters + "&_=" : parameters);
- return req.responseText;
+ if(!async) return req.responseText;
}
function xml_http_request_object() {
@@ -182,10 +225,32 @@ module ActionView
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
+
def remote_function(options)
+ callbacks = build_callbacks(options)
+
function = options[:update] ?
- "update_with_response('#{options[:update]}', '#{url_for(options[:url])}'#{', Form.serialize(this)' if options[:form]})" :
- "xml_request('#{url_for(options[:url])}'#{', Form.serialize(this)' if options[:form]})"
+ "update_with_response('#{options[:update]}', " :
+ "xml_request("
+
+ function << "'#{url_for(options[:url])}'"
+ function << ', Form.serialize(this)' if options[:form]
+ function << ', nil' if !options[:form] && callbacks
+ function << ", true, " << callbacks if callbacks
+ function << ')'
function = "#{options[:before]}; #{function}" if options[:before]
function = "#{function}; #{options[:after]}" if options[:after]
@@ -195,4 +260,4 @@ module ActionView
end
end
end
-end \ No newline at end of file
+end