Rails Helpers (and a little bit of javascript)
Posted by admin, Mon Mar 12 10:56:00 UTC 2007
On a website I have the following simple Rails/Scriptaculous list -
Click on the first item and then on the link referring to the next item.
The first problem I had with this was that the standard scriptaculous routines don't support a blind-if-not-visible-already option - so when you clicked on the referring link, if the section it referred to was already visible it would hide and be displayed.
I needed to check the display property of the DIV and only do the blind/appear if the DOM was currently hidden. I chose to do this using a combination of some javascript and a helper.
Javascript
1 2 3 4 5 6 7 8 9 10 11 12 |
function slideshow(dom, options) { Effect.toggle(dom,'blind',options); Effect.toggle(dom,'appear',options); } function highlight(dom, slideoptions, options) { if ($(dom).getStyle('display') == 'none') { Effect.toggle(dom,'blind',slideoptions); Effect.toggle(dom,'appear',slideoptions); } new Effect.Highlight(dom,options); } |
The javascript is pretty simple but it helps to reduce the code clutter in both the helper and the generated HTML.
Helper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
module ApplicationHelper def slideshow(element_id = false, js_options = {}) element = element_id ? element_id.to_json : "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] "slideshow(#{element},#{options_for_javascript(js_options)});" end def highlight(element_id = false, sl_options={}, js_options={}) element = element_id ? element_id.to_json : "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] sl_options[:queue] = if sl_options[:queue].is_a?(Hash) '{' + sl_options[:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'" }.join(',') + '}' elsif sl_options[:queue] "'#{sl_options[:queue]}'" end if sl_options[:queue] "highlight(#{element}, #{options_for_javascript(sl_options)}, #{options_for_javascript(js_options)});" end end |
I stole most of the code in the helper from the existing scriptaculous helper. As you can see it is just a simple wrapper to generate the javascript function call. I could have simplified the use of my new helpers still by having the helper itself generate the links also but this would have also required supportting any additional attributes etc.. - as link_to_function already does this I decided using it was a no brainer.
View
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<ul> <li><%= link_to_function 'A List Item', slideshow(:list1, { :duration => 0.5, :queue => 'parallel' }) %> <div id="list1" style="display: none"> The text in this list item refers to the list item below, and when you click on <%= link_to_function 'this link', highlight(:list2, { :duration => 0.5, :queue => 'parallel' }, { :duration => 0.5, :queue => 'end' } ) %> the item below should open also </div> </li> <li><%= link_to_function 'Another List Item', slideshow( :list1, { :duration => 0.5, :queue => 'parallel' } ) %> <div id="list2" style="display: none"> This is the text explaining the second item in this list. </div> </li> </ul> |