Enhancement to drop_receiving_element_js in ActionView::Helpers::ScriptaculousHelper

Today I submitted an enhancement ticket for the Rails ActionView::Helpers::ScriptaculousHelper module. This version of drop_receiving_element_js adds two additional options, beforeAjax and afterAjax, that provide a means for javascript code to be executed before and after the creation of the Ajax.Request object. This would allow greater flexibility than just having to create an onDrop function from scratch when needing to do more than making a remote request from within the function. The Rails API doesn’t actually include this method, instead, it’s called from the drop_receiving_element method. You can track the ticket on Lighthouse.

If you’d like to use this enhanced version immediately, create a file named scriptaculous_helper.rb to be placed in config/initializers (for Rails 2.x) or lib (for older versions of Rails). Save the code below into the file, restart your app, and you should be good to go.

  1. require 'action_view/helpers/javascript_helper'
  2.  
  3. module ActionView
  4. module Helpers
  5. module ScriptaculousHelper
  6. def drop_receiving_element_js(element_id, options = {}) #:nodoc:
  7. options[:with] ||= "'id=' + encodeURIComponent(element.id)"
  8. beforeAjax = options[:beforeAjax] ? options[:beforeAjax] + ';' : ''
  9. afterAjax = options[:afterAjax] ? options[:afterAjax] + ';' : ''
  10. options.delete(:beforeAjax)
  11. options.delete(:afterAjax)
  12. options[:onDrop] ||= "function(draggable,droppable,event){" + beforeAjax + remote_function(options) + ';' + afterAjax + "}"
  13. options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
  14.  
  15. options[:accept] = array_or_string_for_javascript(options[:accept]) if options[:accept]
  16. options[:hoverclass] = "'#{options[:hoverclass]}'" if options[:hoverclass]
  17.  
  18. # Confirmation happens during the onDrop callback, so it can be removed from the options
  19. options.delete(:confirm) if options[:confirm]
  20.  
  21. %(Droppables.add(#{element_id.to_json}, #{options_for_javascript(options)});)
  22. end
  23. end
  24. end
  25. end

Here’s an example call from one of my apps that I used to swap the order of an HTML element and make a remote call to change the affected objects’ attributes on the back end:

  1. drop_receiving_element("field#{@field.id}", :url => field_path(@field),
  2. :method => :put, :accept => 'fields', :hoverclass => 'droppable_field',
  3. :beforeAjax => 'droppable.parentNode.insertBefore(draggable,droppable);')

Posted on Sep 03, 2008 | filed under Ruby on Rails | 0 comments