module ActionView module Helpers module MootoolsHelper CALLBACKS = Set.new([:complete, :start, :cancel] + (100..599).to_a) # 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 requestx can then be inserted into a # DOM object whose id can be specified with options[:update]. # Usually, the result would be a partial prepared by the controller with # render :partial. # # 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" }) # # You can override the generated HTML options by specifying a hash in # options[:html]. # # link_to_remote "Delete this post", :update => "posts", # :url => post_url(@post), :method => :delete, # :html => { :class => "destructive" } # # You can also specify a hash for options[:update] to allow for # easy redirection of output to an other DOM element if a server-side # error occurs: # # Example: # link_to_remote "Delete this post", # :url => { :action => "destroy", :id => post.id }, # :update => { :success => "posts", :failure => "error" } # # Optionally, you can use the options[:position] parameter to # influence how the target DOM element is updated. It must be one of # :before, :top, :bottom, or :after. # # The method used is by default POST. You can also specify GET or you # can simulate PUT or DELETE over POST. All specified with options[:method] # # Example: # link_to_remote "Destroy", :url => person_url(:id => person), :method => :delete # # By default, these remote requests are processed asynchronous during # which various JavaScript callbacks can be triggered (for progress # indicators and the likes). All callbacks get access to the # request object, which holds the underlying XMLHttpRequest. # # To access the server response, use request.responseText, to # find out the HTTP status, use request.status. # # Example: # link_to_remote word, # :url => { :action => "undo", :n => word_counter }, # :complete => "undoRequestCompleted(request)" # # The callbacks that may be specified are (in order): # # :loading:: Called when the remote document is being # loaded with data by the browser. # :loaded:: Called when the browser has finished loading # the remote document. # :interactive:: Called when the user can interact with the # remote document, even though it has not # finished loading. # :success:: Called when the XMLHttpRequest is completed, # and the HTTP status code is in the 2XX range. # :failure:: Called when the XMLHttpRequest is completed, # and the HTTP status code is not in the 2XX # range. # :complete:: Called when the XMLHttpRequest is complete # (fires after success/failure if they are # present). # # You can further refine :success and :failure by # adding additional callbacks for specific status codes. # # Example: # link_to_remote word, # :url => { :action => "action" }, # 404 => "alert('Not found...? Wrong URL...?')", # :failure => "alert('HTTP Error ' + request.status + '!')" # # A status code callback overrides the success/failure handlers if # present. # # If you for some reason or another need synchronous processing (that'll # block the browser while the request is happening), you can specify # options[:type] = :synchronous. # # You can customize further browser side call logic by passing in # JavaScript code snippets via some optional parameters. In their order # of use these are: # # :confirm:: Adds confirmation dialog. # :condition:: Perform remote request conditionally # by this expression. Use this to # describe browser-side conditions when # request should not be initiated. # :before:: Called before request is initiated. # :after:: Called immediately after request was # initiated and before :loading. # :submit:: Specifies the DOM element ID that's used # as the parent of the form elements. By # default this is the current form, but # it could just as well be the ID of a # table row or any other DOM element. # :with:: A JavaScript expression specifying # the parameters for the XMLHttpRequest. # Any expressions should return a valid # URL query string. # # Example: # # :with => "'name=' + $('name').value" # # You can generate a link that uses AJAX in the general case, while # degrading gracefully to plain link behavior in the absence of # JavaScript by setting html_options[:href] to an alternate URL. # Note the extra curly braces around the options hash separate # it as the second parameter from html_options, the third. # # Example: # link_to_remote "Delete this post", # { :update => "posts", :url => { :action => "destroy", :id => post.id } }, # :href => url_for(:action => "destroy", :id => post.id) def link_to_remote(name, options = {}, html_options = nil) link_to_function(name, remote_function(options), html_options || options.delete(:html)) end # Creates a form that will submit using XMLHttpRequest in the background # instead of the regular reloading POST arrangement and a scope around a # specific resource that is used as a base for questioning about # values for the fields. # # === Resource # # Example: # <% remote_form_for(@post) do |f| %> # ... # <% end %> # # This will expand to be the same as: # # <% remote_form_for :post, @post, :url => post_path(@post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %> # ... # <% end %> # # === Nested Resource # # Example: # <% remote_form_for([@post, @comment]) do |f| %> # ... # <% end %> # # This will expand to be the same as: # # <% remote_form_for :comment, @comment, :url => post_comment_path(@post, @comment), :html => { :method => :put, :class => "edit_comment", :id => "edit_comment_45" } do |f| %> # ... # <% end %> # # If you don't need to attach a form to a resource, then check out form_remote_tag. # # See FormHelper#form_for for additional semantics. def remote_form_for(record_or_name_or_array, *args, &proc) options = args.extract_options! case record_or_name_or_array when String, Symbol object_name = record_or_name_or_array when Array object = record_or_name_or_array.last object_name = ActionController::RecordIdentifier.singular_class_name(object) apply_form_for_options!(record_or_name_or_array, options) args.unshift object else object = record_or_name_or_array object_name = ActionController::RecordIdentifier.singular_class_name(record_or_name_or_array) apply_form_for_options!(object, options) args.unshift object end concat(form_remote_tag(options)) fields_for(object_name, *(args << options), &proc) concat('') end alias_method :form_remote_for, :remote_form_for class JavaScriptGenerator def initialize(context, &block) #:nodoc: @context, @lines = context, [] include_helpers_from_context @context.instance_exec(self, &block) end private def include_helpers_from_context extend @context.helpers if @context.respond_to?(:helpers) extend GeneratorMethods end # JavaScriptGenerator generates blocks of JavaScript code that allow you # to change the content and presentation of multiple DOM elements. Use # this in your Ajax response bodies, either in a