Upgraded Rails and RSpec
[monkeycharger.git] / vendor / rails / actionpack / lib / action_view / helpers / scriptaculous_helper.rb
blob83f4d168a880741491d3101510786d3f6d8089cc
1 require 'action_view/helpers/javascript_helper'
3 module ActionView
4   module Helpers
5     # Provides a set of helpers for calling Scriptaculous JavaScript 
6     # functions, including those which create Ajax controls and visual effects.
7     #
8     # To be able to use these helpers, you must include the Prototype 
9     # JavaScript framework and the Scriptaculous JavaScript library in your 
10     # pages. See the documentation for ActionView::Helpers::JavaScriptHelper
11     # for more information on including the necessary JavaScript.
12     #
13     # The Scriptaculous helpers' behavior can be tweaked with various options.
14     # See the documentation at http://script.aculo.us for more information on
15     # using these helpers in your application.
16     module ScriptaculousHelper
17       unless const_defined? :TOGGLE_EFFECTS
18         TOGGLE_EFFECTS = [:toggle_appear, :toggle_slide, :toggle_blind]
19       end
20       
21       # Returns a JavaScript snippet to be used on the Ajax callbacks for
22       # starting visual effects.
23       #
24       # Example:
25       #   <%= link_to_remote "Reload", :update => "posts", 
26       #         :url => { :action => "reload" }, 
27       #         :complete => visual_effect(:highlight, "posts", :duration => 0.5)
28       #
29       # If no element_id is given, it assumes "element" which should be a local
30       # variable in the generated JavaScript execution context. This can be 
31       # used for example with drop_receiving_element:
32       #
33       #   <%= drop_receiving_element (...), :loading => visual_effect(:fade) %>
34       #
35       # This would fade the element that was dropped on the drop receiving 
36       # element.
37       #
38       # For toggling visual effects, you can use :toggle_appear, :toggle_slide, and
39       # :toggle_blind which will alternate between appear/fade, slidedown/slideup, and
40       # blinddown/blindup respectively.
41       #
42       # You can change the behaviour with various options, see
43       # http://script.aculo.us for more documentation.
44       def visual_effect(name, element_id = false, js_options = {})
45         element = element_id ? element_id.to_json : "element"
46         
47         js_options[:queue] = if js_options[:queue].is_a?(Hash)
48           '{' + js_options[:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'" }.join(',') + '}'
49         elsif js_options[:queue]
50           "'#{js_options[:queue]}'"
51         end if js_options[:queue]
52         
53         [:endcolor, :direction, :startcolor, :scaleMode, :restorecolor].each do |option|
54           js_options[option] = "'#{js_options[option]}'" if js_options[option]
55         end
57         if TOGGLE_EFFECTS.include? name.to_sym
58           "Effect.toggle(#{element},'#{name.to_s.gsub(/^toggle_/,'')}',#{options_for_javascript(js_options)});"
59         else
60           "new Effect.#{name.to_s.camelize}(#{element},#{options_for_javascript(js_options)});"
61         end
62       end
63       
64       # Makes the element with the DOM ID specified by +element_id+ sortable
65       # by drag-and-drop and make an Ajax call whenever the sort order has
66       # changed. By default, the action called gets the serialized sortable
67       # element as parameters.
68       #
69       # Example:
70       #   <%= sortable_element("my_list", :url => { :action => "order" }) %>
71       #
72       # In the example, the action gets a "my_list" array parameter 
73       # containing the values of the ids of elements the sortable consists 
74       # of, in the current order.
75       #
76       # Important: For this to work, the sortable elements must have id
77       # attributes in the form "string_identifier". For example, "item_1". Only
78       # the identifier part of the id attribute will be serialized.
79       #
80       #
81       # You can change the behaviour with various options, see
82       # http://script.aculo.us for more documentation.
83       def sortable_element(element_id, options = {})
84         javascript_tag(sortable_element_js(element_id, options).chop!)
85       end
86       
87       def sortable_element_js(element_id, options = {}) #:nodoc:
88         options[:with]     ||= "Sortable.serialize(#{element_id.to_json})"
89         options[:onUpdate] ||= "function(){" + remote_function(options) + "}"
90         options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
91   
92         [:tag, :overlap, :constraint, :handle].each do |option|
93           options[option] = "'#{options[option]}'" if options[option]
94         end
95   
96         options[:containment] = array_or_string_for_javascript(options[:containment]) if options[:containment]
97         options[:only] = array_or_string_for_javascript(options[:only]) if options[:only]
98   
99         %(Sortable.create(#{element_id.to_json}, #{options_for_javascript(options)});)
100       end
102       # Makes the element with the DOM ID specified by +element_id+ draggable.
103       #
104       # Example:
105       #   <%= draggable_element("my_image", :revert => true)
106       # 
107       # You can change the behaviour with various options, see
108       # http://script.aculo.us for more documentation.
109       def draggable_element(element_id, options = {})
110         javascript_tag(draggable_element_js(element_id, options).chop!)
111       end
112       
113       def draggable_element_js(element_id, options = {}) #:nodoc:
114         %(new Draggable(#{element_id.to_json}, #{options_for_javascript(options)});)
115       end
117       # Makes the element with the DOM ID specified by +element_id+ receive
118       # dropped draggable elements (created by draggable_element).
119       # and make an AJAX call  By default, the action called gets the DOM ID 
120       # of the element as parameter.
121       #
122       # Example:
123       #   <%= drop_receiving_element("my_cart", :url => 
124       #     { :controller => "cart", :action => "add" }) %>
125       #
126       # You can change the behaviour with various options, see
127       # http://script.aculo.us for more documentation.
128       def drop_receiving_element(element_id, options = {})
129         javascript_tag(drop_receiving_element_js(element_id, options).chop!)
130       end
131       
132       def drop_receiving_element_js(element_id, options = {}) #:nodoc:
133         options[:with]     ||= "'id=' + encodeURIComponent(element.id)"
134         options[:onDrop]   ||= "function(element){" + remote_function(options) + "}"
135         options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
137         options[:accept] = array_or_string_for_javascript(options[:accept]) if options[:accept]    
138         options[:hoverclass] = "'#{options[:hoverclass]}'" if options[:hoverclass]
139         
140         %(Droppables.add(#{element_id.to_json}, #{options_for_javascript(options)});)
141       end
142     end
143   end