论坛首页 编程语言技术论坛

Rails源码研究之ActionView:六,scriptaculous_helper

浏览 2803 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-07-03  
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') %>
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics