module ActionView::Helpers::ScriptaculousHelper
def array_or_string_for_javascript(option)
def array_or_string_for_javascript(option) if option.kind_of?(Array) "['#{option.join('\',\'')}']" elsif !option.nil? "'#{option}'" end end
def draggable_element(element_id, options = {})
You can change the behaviour with various options, see
<%= draggable_element("my_image", :revert => true)
Example:
Makes the element with the DOM ID specified by +element_id+ draggable.
def draggable_element(element_id, options = {}) javascript_tag(draggable_element_js(element_id, options).chop!) end
def draggable_element_js(element_id, options = {}) #:nodoc:
def draggable_element_js(element_id, options = {}) #:nodoc: %(new Draggable(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});) end
def drop_receiving_element(element_id, options = {})
* :with - A JavaScript expression specifying the parameters for
the drop - like if the Ctrl or Shift keys were pressed - from the Event object.
element and the Event object. You can extract additional information about
This callback gets three parameters: The Draggable element, the Droppable
:onDrop => "function(draggable_element, droppable_element, event) { alert('I like bananas') }"
change the default drop behaviour. Example:
this element. Override this callback with a JavaScript expression to
* :onDrop - Called when a +draggable_element+ is dropped onto
hovered over it.
this additional CSS class when an accepted +draggable_element+ is
* :hoverclass - If set, the +drop_receiving_element+ will have
:confirm => "Are you sure you want to do this?"
* :confirm - Adds a confirmation dialog. Example:
to be accepted by this +drop_receiving_element+.
allowable CSS classes that the +draggable_element+ must have in order
* :accept - Set this to a string or an array of strings describing the
Some of these +options+ include:
http://script.aculo.us for more documentation.
You can change the behaviour with various options, see
{ :controller => "cart", :action => "add" }) %>
<%= drop_receiving_element("my_cart", :url =>
Example:
of the element as parameter.
and make an AJAX call. By default, the action called gets the DOM ID
dropped draggable elements (created by +draggable_element+).
Makes the element with the DOM ID specified by +element_id+ receive
def drop_receiving_element(element_id, options = {}) javascript_tag(drop_receiving_element_js(element_id, options).chop!) end
def drop_receiving_element_js(element_id, options = {}) #:nodoc:
def drop_receiving_element_js(element_id, options = {}) #:nodoc: options[:with] ||= "'id=' + encodeURIComponent(element.id)" options[:onDrop] ||= "function(element){" + remote_function(options) + "}" options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) } options[:accept] = array_or_string_for_javascript(options[:accept]) if options[:accept] options[:hoverclass] = "'#{options[:hoverclass]}'" if options[:hoverclass] # Confirmation happens during the onDrop callback, so it can be removed from the options options.delete(:confirm) if options[:confirm] %(Droppables.add(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});) end
def sortable_element(element_id, options = {})
is called once on each Sortable. Gets the container as its parameter.
changed in any way. When dragging from one Sortable to another, the callback
* :onUpdate - Called when the drag ends and the Sortable's order is
Sortable. Gets the affected element as its parameter.
dragging from one Sortable to another, the callback is called once on each
* :onChange - Called whenever the sort order changes while dragging. When
is false).
rules) as a child element when there are no more elements inside (default
a Droppable, that can receive a Draggable (as according to the containment
* :dropOnEmpty - If true the Sortable container will be made into
the original in place until the clone is dropped (default is false).
* :ghosting - Clones the element and drags the clone, leaving
the handle.
found within the element that has this CSS class value will be used as
(as of script.aculo.us V1.5). The first child/grandchild/etc. element
embedded handle. The value may be a string referencing a CSS class value
* :handle - Sets whether the element should only be draggable by an
when an accepted Draggable is hovered over it.
* :hoverclass - If set, the Droppable will have this additional CSS class
between levels.
and not only sort items at the same level, but drag and sort items
main sortable list. This means that you can create multi-layer lists,
* :tree - Determines whether to treat nested lists as part of the
operations if the list runs past the visual border.
* :scroll - Determines whether to scroll the list during drag
out child elements as candidates.
* :only - A CSS class name or array of class names used to filter
potential drop targets (defaults to the original target element).
* :containment - Takes an element or array of elements to treat as
sortable (default is li).
* :tag - Which children of the container element to treat as
or :vertical direction.
* :overlap - Calculate the item overlap in the :horizontal
:horizontal or :vertical (or false to make it unconstrained).
* :constraint - Whether to constrain the dragging to either
serialized id to the server (the default is /^[^_]*_(.*)$/).
* :format - A regular expression to determine what to send as the
Additional +options+ are:
the identifier part of the id attribute will be serialized.
attributes in the form "string_identifier". For example, "item_1". Only
Important: For this to work, the sortable elements must have id
of, in the current order.
containing the values of the ids of elements the sortable consists
In the example, the action gets a "my_list" array parameter
<%= sortable_element("my_list", :url => { :action => "order" }) %>
Example:
element as parameters.
changed. By default, the action called gets the serialized sortable
by drag-and-drop and make an Ajax call whenever the sort order has
Makes the element with the DOM ID specified by +element_id+ sortable
def sortable_element(element_id, options = {}) javascript_tag(sortable_element_js(element_id, options).chop!) end
def sortable_element_js(element_id, options = {}) #:nodoc:
def sortable_element_js(element_id, options = {}) #:nodoc: options[:with] ||= "Sortable.serialize(#{ActiveSupport::JSON.encode(element_id)})" options[:onUpdate] ||= "function(){" + remote_function(options) + "}" options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) } [:tag, :overlap, :constraint, :handle].each do |option| options[option] = "'#{options[option]}'" if options[option] end options[:containment] = array_or_string_for_javascript(options[:containment]) if options[:containment] options[:only] = array_or_string_for_javascript(options[:only]) if options[:only] %(Sortable.create(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});) end
def visual_effect(name, element_id = false, js_options = {})
You can change the behaviour with various options, see
blinddown/blindup respectively.
:toggle_blind which will alternate between appear/fade, slidedown/slideup, and
For toggling visual effects, you can use :toggle_appear, :toggle_slide, and
element.
This would fade the element that was dropped on the drop receiving
<%= drop_receiving_element (...), :loading => visual_effect(:fade) %>
used for example with +drop_receiving_element+:
variable in the generated JavaScript execution context. This can be
If no +element_id+ is given, it assumes "element" which should be a local
starting visual effects.
Returns a JavaScript snippet to be used on the Ajax callbacks for
def visual_effect(name, element_id = false, js_options = {}) element = element_id ? ActiveSupport::JSON.encode(element_id) : "element" js_options[:queue] = if js_options[:queue].is_a?(Hash) '{' + js_options[:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'" }.join(',') + '}' elsif js_options[:queue] "'#{js_options[:queue]}'" end if js_options[:queue] [:endcolor, :direction, :startcolor, :scaleMode, :restorecolor].each do |option| js_options[option] = "'#{js_options[option]}'" if js_options[option] end if TOGGLE_EFFECTS.include? name.to_sym "Effect.toggle(#{element},'#{name.to_s.gsub(/^toggle_/,'')}',#{options_for_javascript(js_options)});" else "new Effect.#{name.to_s.camelize}(#{element},#{options_for_javascript(js_options)});" end end