Guest User

Untitled

a guest
May 23rd, 2018
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.60 KB | None | 0 0
  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
Add Comment
Please, Sign In to add comment