daily pastebin goal
10%
SHARE
TWEET

Untitled

a guest May 23rd, 2018 63 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. require 'action_view'
  2. require 'custom_helpers.rb'
  3. require 'action_view/helpers/tag_helper'
  4. require 'action_view/helpers/form_helper'
  5. require 'action_view/helpers/javascript_helper'
  6. # InPlaceControls - Do in-place-style editors with other form controls
  7. module Flvorful
  8.   module SuperInplaceControls
  9.    
  10.     include  CustomHelpers
  11.         # =MAIN
  12.         # These controls were designed to be used with habtm & hm associations.  Just use the object and the foreign key as the attribute (see examples).  You can specify a chain of methods to use for the final display text (so you dont see the foreign key id)
  13.         #
  14.         # Controller methods. Call just like the prototype helper method in_place_edit_for
  15.         #
  16.         # =OPTIONS
  17.         # <code>final_text</code> - this is an array of methods calls or a special symbol to be executed after the update<br>
  18.         # <b>example</b>:<br>
  19.         # <code>in_place_edit_for( :prospect, "status_id", { :final_text => ["status", "title"] })</code>
  20.         # This will chain the methods together to display the final text for  the update.  
  21.         # The method call will look like: <code>object.status.title</code>
  22.         #
  23.         # <b>special symbols</b>
  24.         # <code>collection</code> - Use this as your final text if you want to use a checkbox collection on a HABTM or HM association.  This will call a method stack similar to: <code>object.collections.map { |e| e.title || e.name }.join(", ")</code><br>
  25.         # <b>example</b>: <code>in_place_edit_for :product, :category_ids, {:final_text => :collection }</code>
  26.         #
  27.         # <code>highlight_endcolor</code> - the end color for the "highlight" visual effect.<br>
  28.         # example: <code>in_place_edit_for( :prospect, "status_id", { :final_text => ["status", "title"], highlight_endcolor => "'#ffffff'" })</code>
  29.         #
  30.         # <code>highlight_startcolor</code> - the start color for the "highlight" visual effect.<br>
  31.         # example: <code>in_place_edit_for( :prospect, "status_id", { :final_text => ["status", "title"], :highlight_startcolor => "'#ffffff'" })</code>
  32.         #
  33.         # <code>error_messages</code> - the error messages div that errors will be put into.  defaults to error_messages<br>
  34.         # <b>example:</b> <code>in_place_edit_for( :prospect, "status_id", { :error_messages => "my_error_div", :highlight_startcolor => "'#ffffff'" })</code>
  35.         #
  36.         # <code>error_visual_effect</code> - The visual effect to use for displaying your error_message div. Defaults to :slide_down. <br>
  37.         # example: <code>in_place_edit_for( :prospect, "status_id", { :error_visual_effect => :appear })</code>
  38.         #
  39.         # =TODO
  40.         # <code>final_text_operation</code> - this is a helper method that you want to call once the final_text is generated<br>
  41.         # example: <code>in_place_edit_for( :prospect, "status_id", { :final_text => ["status", "title"] }, { :final_text_operation => ["truncate", 30] })</code>
  42.         # This will call truncate on the final_text and pass in 30 as the argument.
  43.         # Everything after the first argument (the method to call) is sent as an argument to the method. The method call is similar to: truncate(, 30)
  44.         #
  45.         #
  46.      
  47.    
  48.     module ControllerMethods
  49.  
  50.       def in_place_edit_for(object, attribute, options = {})
  51.         define_method("set_#{object}_#{attribute}") do
  52.           @item = object.to_s.camelize.constantize.find(params[:id])
  53.           id_string = "#{object}_#{attribute}_#{@item.id}"
  54.           field_id = "#{object}_#{attribute}"
  55.           error_messages = options[:error_messages] || "error_messages"
  56.           highlight_endcolor = options[:highlight_endcolor] || "#ffffff"
  57.           highlight_startcolor = options[:highlight_startcolor] || "#ffff99"
  58.           error_visual_effect = options[:error_visual_effect] || :slide_down
  59.          
  60.           if @item.update_attributes(attribute => params[object][attribute])
  61.             unless options[:final_text].nil?
  62.               if options[:final_text] == :collection
  63.                 final_text = @item.send(attribute.to_s.gsub("_ids", "").pluralize).map { |e| e.title || e.name }.join(", ")
  64.               else
  65.                 methods = options[:final_text]
  66.                 sum_of_methods = @item
  67.                 methods.each do |meth|
  68.                   sum_of_methods = sum_of_methods.send(meth)
  69.                 end
  70.                 final_text = sum_of_methods
  71.               end
  72.             else
  73.               final_text = @item.send(attribute).to_s
  74.             end
  75.  
  76.  
  77.             final_text = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" if final_text.blank?
  78.  
  79.             render :update do |page|
  80.               page.replace_html "#{id_string}", final_text
  81.               page.hide "#{id_string}_form"
  82.  
  83.               unless error_messages.nil? || !@error_div_on
  84.                 page.hide error_messages
  85.                 page.select("##{id_string}_form ##{field_id}").map { |e| e.remove_class_name "fieldWithError" }
  86.               end
  87.               page.show "#{id_string}"
  88.               page.visual_effect :highlight, "#{id_string}", :duration => 0.5, :endcolor => "#{highlight_endcolor}", :startcolor => "#{highlight_startcolor}"
  89.             end
  90.           else
  91.             unless error_messages.nil? || !@error_div_on
  92.               errors_html = "<h2>Errors</h2>"  + "<ul>" + @item.errors.full_messages.map { |e| "<li>#{e}</li>" }.join("\n  ") + "</ul>"
  93.               render :update do |page|
  94.                 page.select("##{id_string}_form ##{field_id}").map { |e| e.add_class_name "fieldWithError" }
  95.                 page.show "#{id_string}_form"
  96.                 #page[:error_messages].add_class_name "full_errors"
  97.                 page.replace_html error_messages, errors_html
  98.                 page.visual_effect error_visual_effect, error_messages
  99.               end
  100.             else
  101.               raise @item.inspect
  102.             end
  103.           end
  104.         end
  105.       end
  106.  
  107.  
  108.  
  109.     end
  110.  
  111.  
  112.  
  113.  
  114.     # These methods are mixed into the view as helpers.
  115.     # Common options for the helpers:
  116.     #   :action - the action to submit the change to
  117.     #   :saving_text - text to show while the request is processing.  Default is "Saving..."
  118.     #   :object - the object to create the control for, if other than an instance variable. (Useful for iterations.)
  119.     #   :display_text - the text to be display before the update.  Used when you want to use an
  120.     #                                   in_place control for an association field.  Defaults to method
  121.     #   :br           - add a <br /> tag after the field and before the submit tag.  Defaults to
  122.     #                   false/nil
  123.     module HelperMethods
  124.       # Creates an "active" date select control that submits any changes to the server
  125.       # using an in_place_edit-style action.
  126.       # Extra Options:
  127.       #   :time     - Allows users to select the Time as well as the date.  Defaults to false.
  128.       # By default the value of the object's attribute will be selected, or blank.
  129.       # Example:
  130.       #   <%= in_place_date_select :product, :display_begin_date %>
  131.      
  132.       def in_place_date_select(object, method, options = {})
  133.         options[:time] ||= false
  134.         in_place_field(:date_select, object, method, options)
  135.       end
  136.      
  137.       # Creates an "active" select box control that submits any changes to the server
  138.       # using an in_place_edit-style action.
  139.       # Extra Options:
  140.       #   :choices          - (required) An array of choices (see method "select")
  141.       # By default the value of the object's attribute will be selected, or blank.
  142.       # Example:
  143.       #   <%= in_place_select :employee, :manager_id, :choices => Manager.find_all.map { |e| [e.name, e.id] } %>
  144.       def in_place_select(object, method, options = {})
  145.         check_for_choices(options)
  146.         in_place_field(:select, object, method, options)
  147.       end
  148.      
  149.       # Creates an "active" text field control that submits any changes to the server
  150.       # using an in_place_edit-style action.
  151.       # By default the value of the object's attribute will be filled in or blank.
  152.       # Example:
  153.       #   <%= in_place_text_field :product, :title %>
  154.       def in_place_text_field(object, method, options = {})
  155.         in_place_field(:text_field, object, method, options)
  156.       end
  157.      
  158.       # Creates an "active" text area control that submits any changes to the server
  159.       # using an in_place_edit-style action.
  160.       # By default the value of the object's attribute will be filled in or blank.
  161.       # Example:
  162.       #   <%= in_place_text_area :product, :description %>
  163.       def in_place_text_area(object, method, options = {})
  164.         in_place_field(:text_area, object, method, options)
  165.       end
  166.      
  167.       # Creates an "active" collection of checkbox controls that submits any changes to the server
  168.       # using an in_place_edit-style action.
  169.       # Extra Options:
  170.       #   :choices          - (required) An array of choices (see method "select")
  171.       # By default the value of the object's attribute will be selected, or blank.
  172.       # Example:
  173.       #   <%= in_place_check_box_collection :product, :category_ids, :choices => Category.find(:all).map { |e| [e.id, e.title] } %>
  174.       def in_place_check_box_collection(object, method, options = {})
  175.         check_for_choices(options)
  176.         options[:display_text] = :collection
  177.         in_place_field(:check_box, object, method, options)
  178.       end
  179.      
  180.       # Creates an "active" collection of radio controls that submits any changes to the server
  181.       # using an in_place_edit-style action.
  182.       # Extra Options:
  183.       #   :choices          - (required) An array of choices (see method "select")
  184.       #   :columns          - breaks up the collection into :columns number of columns
  185.       # By default the value of the object's attribute will be selected, or blank.
  186.       # Example:
  187.       #   <%= in_place_radio_collection :product, :price, :choices => %w(199 299 399 499 599 699 799 899 999).map { |e| [e, e] } %>
  188.       def in_place_radio_collection(object, method, options = {})
  189.         check_for_choices(options)
  190.         in_place_field(:radio, object, method, options)
  191.       end
  192.  
  193.       # Creates an div container for error_messages
  194.       def inplace_error_div(div_id = "error_messages", div_class = "error_messages")
  195.                 @error_div_on = true                                                        
  196.                 content_tag(:div, "", :id => div_id, :class => div_class, :style => "display:none")
  197.       end
  198.  
  199.  
  200.       protected      
  201.       def check_for_choices(options)
  202.         raise ArgumentError, "Missing choices for select! Specify options[:choices] for in_place_select" if options[:choices].nil?
  203.       end
  204.      
  205.       def in_place_field(field_type, object, method, options)
  206.         object_name = object.to_s
  207.         method_name = method.to_s
  208.         @object = self.instance_variable_get("@#{object}") || options[:object]
  209.         display_text = set_display_text(@object, method_name, options)
  210.         ret =  html_for_inplace_display(object_name, method_name, @object, display_text)
  211.         ret << form_for_inplace_display(object_name, method_name, field_type, @object, options)
  212.       end
  213.      
  214.       def set_blank_text(text, number_of_spaces = 7)
  215.         blank = ""
  216.         number_of_spaces.times { |e| blank += "&nbsp;"  }
  217.         text = blank if text.blank?
  218.         text
  219.       end
  220.      
  221.       def set_display_text(object, attribute, options)
  222.         display_text = ""
  223.         #raise options.inspect + "|" + object.to_s + "|" + attribute.to_s
  224.         if options[:display_text] == :collection
  225.           display_text = object.send(attribute.to_s.gsub("_ids", "").pluralize).map { |e| e.title || e.name }.join(", ")
  226.         else
  227.           display_text = options[:display_text] || object.send(attribute)
  228.         end
  229.         #display_text = set_blank_text(display_text)
  230.         h display_text
  231.       end
  232.      
  233.       def id_string_for(object_name, method_name, object)
  234.         "#{object_name}_#{method_name}_#{object.id}"
  235.       end
  236.  
  237.       def html_for_inplace_display(object_name, method_name, object, display_text)
  238.         id_string = id_string_for(object_name, method_name, object)
  239.         content_tag(:span,  display_text,
  240.         :onclick => update_page do |page|
  241.                     page.hide "#{id_string}"
  242.                         page.show "#{id_string }_form"
  243.                   end,
  244.         :onmouseover => visual_effect(:highlight, id_string),
  245.         :title => "Click to Edit",
  246.         :id => id_string ,
  247.         :class => "inplace_span #{"empty_inplace" if display_text.blank?}"
  248.         )
  249.  
  250.  
  251.       end
  252.  
  253.       def form_for_inplace_display(object_name, method_name, input_type, object, opts)
  254.         retval = ""
  255.         id_string = id_string_for(object_name, method_name, object)
  256.         set_method = opts[:action] || "set_#{object_name}_#{method_name}"
  257.                 save_button_text = opts[:save_button_text] || "OK"
  258.         loader_message = opts[:saving_text] || "Saving..."
  259.         retval << form_remote_tag(:url => { :action => set_method, :id => object.id },
  260.                 :method => opts[:http_method] || :post,
  261.                 :loading => update_page do |page|
  262.                     page.show "loader_#{id_string}"
  263.                     page.hide "#{id_string}_form"
  264.                 end,
  265.                 :complete => update_page do |page|
  266.                     page.hide "loader_#{id_string}"
  267.                 end,
  268.         :html => {:class => "in_place_editor_form", :id => "#{id_string}_form", :style => "display:none" } )
  269.  
  270.         retval << field_for_inplace_editing(object_name, method_name, object, opts, input_type )
  271.         retval << content_tag(:br) if opts[:br]
  272.         retval << submit_tag( save_button_text, :class => "inplace_submit")
  273.         retval << link_to_function( "Cancel", update_page do |page|
  274.                     page.show "#{id_string}"
  275.                     page.hide "#{id_string}_form"
  276.                 end, {:class => "inplace_cancel" })
  277.         retval << "</form>"
  278.         retval << invisible_loader( loader_message, "loader_#{id_string}", "inplace_loader")
  279.         retval << content_tag(:br)
  280.       end
  281.  
  282.       def field_for_inplace_editing(object_name, method_name,  object, options , input_type)
  283.         options[:class] = "inplace_#{input_type}"
  284.         htm_opts = {:class => options[:class] }
  285.         case input_type
  286.         when :text_field
  287.           text_field(object_name, method_name, options )
  288.         when :text_area
  289.           text_area(object_name, method_name, options )
  290.         when :select
  291.           select(object_name, method_name,  options[:choices], options, htm_opts )
  292.         when :check_box
  293.           options[:label_class] = "inplace_#{input_type}_label"
  294.           checkbox_collection(object_name, method_name, object,  options[:choices], options )
  295.         when :radio
  296.           options[:label_class] = "inplace_#{input_type}_label"
  297.           radio_collection(object_name, method_name, object,  options[:choices], options )
  298.         when :date_select
  299.           calendar_date_select( object_name, method_name, options)
  300.         end
  301.       end
  302.  
  303.  
  304.     end
  305.   end
  306. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top