Skip to content
This repository
Browse code

Added asynchronous processing model

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@902 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 8d646006db8cd3f2e5074deab4618120089020c6 1 parent 193edfb
David Heinemeier Hansson dhh authored

Showing 1 changed file with 71 additions and 6 deletions. Show diff stats Hide diff stats

  1. +71 6 actionpack/lib/action_view/helpers/javascript_helper.rb
77 actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -24,6 +24,23 @@ def link_to_function(name, function, html_options = {})
24 24 # Examples:
25 25 # link_to_remote "Delete this post", :update => "posts", :url => { :action => "destroy", :id => post.id }
26 26 # link_to_remote(image_tag("refresh"), :update => "emails", :url => { :action => "list_emails" })
  27 + #
  28 + # Asynchronous requests may be made by specifying a callback function
  29 + # to invoke when the request finishes.
  30 + #
  31 + # Example:
  32 + # link_to_remote word,
  33 + # :url => { :action => "undo", :n => word_counter },
  34 + # :before => "if(!prepareForUndo()) return false",
  35 + # :complete => "undoRequestCompleted(request)"
  36 + #
  37 + # The complete list of callbacks that may be specified are:
  38 + #
  39 + # * uninitialized
  40 + # * loading
  41 + # * loaded
  42 + # * interactive
  43 + # * complete
27 44 def link_to_remote(name, options = {}, html_options = {})
28 45 link_to_function(name, remote_function(options), html_options)
29 46 end
@@ -64,21 +81,47 @@ def define_javascript_functions
64 81 var container = o(arguments[0]);
65 82 var url = arguments[1];
66 83 var parameters = arguments[2];
67   -
68   - container.innerHTML = xml_request(url, parameters);
  84 + var async = arguments[3];
  85 +
  86 + if (async) {
  87 + xml_request(url, parameters, true,
  88 + { complete: function(request) {
  89 + container.innerHTML = request.responseText }
  90 + })
  91 + } else {
  92 + container.innerHTML = xml_request(url, parameters);
  93 + }
69 94 }
70 95
71 96 function xml_request() {
72 97 var url = arguments[0];
73 98 var parameters = arguments[1];
74 99 var async = arguments[2];
  100 + var callbacks = arguments[3];
75 101 var type = parameters ? "POST" : "GET";
76 102
77 103 req = xml_http_request_object();
78 104 req.open(type, url, async);
  105 +
  106 + if (async) {
  107 + invoke_callback = function(which) {
  108 + if(callbacks && callbacks[which]) callbacks[which](req)
  109 + }
  110 +
  111 + req.onreadystatechange = function() {
  112 + switch(req.readyState) {
  113 + case 0: invoke_callback('uninitialized'); break
  114 + case 1: invoke_callback('loading'); break
  115 + case 2: invoke_callback('loaded'); break
  116 + case 3: invoke_callback('interactive'); break
  117 + case 4: invoke_callback('complete'); break
  118 + }
  119 + }
  120 + }
  121 +
79 122 req.send(parameters ? parameters + "&_=" : parameters);
80 123
81   - return req.responseText;
  124 + if(!async) return req.responseText;
82 125 }
83 126
84 127 function xml_http_request_object() {
@@ -182,10 +225,32 @@ def define_javascript_functions
182 225 end
183 226
184 227 private
  228 + def build_callbacks(options)
  229 + callbacks = nil
  230 + %w{uninitialized loading loaded interactive complete}.each do |cb|
  231 + cb = cb.to_sym
  232 + if options[cb]
  233 + callbacks ? callbacks << "," : callbacks = "{"
  234 + callbacks <<
  235 + "#{cb}:function(request){#{options[cb].gsub(/"/){'\"'}}}"
  236 + end
  237 + end
  238 + callbacks << "}" if callbacks
  239 + callbacks
  240 + end
  241 +
185 242 def remote_function(options)
  243 + callbacks = build_callbacks(options)
  244 +
186 245 function = options[:update] ?
187   - "update_with_response('#{options[:update]}', '#{url_for(options[:url])}'#{', Form.serialize(this)' if options[:form]})" :
188   - "xml_request('#{url_for(options[:url])}'#{', Form.serialize(this)' if options[:form]})"
  246 + "update_with_response('#{options[:update]}', " :
  247 + "xml_request("
  248 +
  249 + function << "'#{url_for(options[:url])}'"
  250 + function << ', Form.serialize(this)' if options[:form]
  251 + function << ', nil' if !options[:form] && callbacks
  252 + function << ", true, " << callbacks if callbacks
  253 + function << ')'
189 254
190 255 function = "#{options[:before]}; #{function}" if options[:before]
191 256 function = "#{function}; #{options[:after]}" if options[:after]
@@ -195,4 +260,4 @@ def remote_function(options)
195 260 end
196 261 end
197 262 end
198   -end
  263 +end

0 comments on commit 8d64600

Please sign in to comment.
Something went wrong with that request. Please try again.