scriptaculous_helper主要是对scriptaculous的controls和effects相关方法调用的封装
require File.dirname(__FILE__) + '/javascript_helper'
module ActionView
module Helpers
module ScriptaculousHelper
unless const_defined? :TOOGLE_EFFECTS
TOGGLE_EFFECTS = [:toggle_appear, :toggle_slide, :toggle_blind]
end
def visual_effect(name, element_id = false, js_options = {})
element = element_id ? element_id.to_json : "element"
js_options[:queque] = if js_options[:queue].is_a?(Hash)
'{' + js_options[:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'"}.join(',') + '}'
elseif js_options[:queue]
"'#{js_options[:queue]}'"
end if js_options[:queue]
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
def sortable_element(element_id, options = {})
javascript_tag(sortable_element_js(element_id, options).chop!)
end
def sortable_element_js(element_id, options = {})
options[:with] ||= "Sortable.serialize(#{element_id.to_json})"
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(#{element_id.to_json}, #{options_for_javascript(options)});)
end
def draggable_element(element_id, options = {})
javascript_tag(draggable_element_js(element_id, options).chop!)
end
def draggable_element_js(element_id, options = {})
%(new Draggable(#{element_id.to_json}, #{options_for_javascript(options)});)
end
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 = {})
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]
%(Droppables.add(#{element_id.to_json}, #{options_for_javascript(options)});)
end
end
end
end
和前面看到的javascript_helper,prototype_helper一样,也是封装并返回JavaScript语句
这些方法用到了scriptaculous的Effect,Sortable,Draggable和Draggables类,具体方法参数参考
http://script.aculo.us
还是看看例子吧:
1,visual_effect
<%= link_to_remote "Reload", :update => "posts",
:url => { :action => "reload" },
:complete => visual_effect(:highlight, "posts", :duration => 0.5)
其中visual_effect可以使用:toggle_appear,:toggle_slide和:toggle_blind参数来在appear/fade,slidedown/slideup和blinddown/blindup间切换
2,sortable_element
# view
<ul id="list">
<% 6.times do |i| -%>
<li id="item_<%= i+1 %>">I'm number <%= i+1 %></li>
<% end -%>
</ul>
<p id="list-info"></p>
<%= sortable_element 'list',
:update => 'list-info',
:complete => visual_effect(:highlight, 'list'),
:url => { :action => "order" } %>
# controller
def order
params[:list].each_with_index { |id,idx| Model.update(id, :position => idx) }
render :text => 'Updated sort order'
end
3,draggable_element
<%= draggable_element("my_image", :revert => true)
revert为true时,拖动的元素会回到初始位置
4,drop_receiving_element
<div id="to_drop">
<%= render :partial => 'item', :collection => @to_drop_items %>
</div>
<div id="to_receive">
<%= render :partial => 'item', :collection => @to_receive_items %>
</div>
<%= drop_receiving_element('to_drop', :url => remove_item_url(@item), :accept => 'to_receive') %>