880cbab435f00197613c9cc2065b4f5a

We use this utility internally. I had a use case today where I don't want to $('#{container_id}').hide(); rather I'd like to grey it out and stop it from receiving events. Is there a more generic way to do all this?

# Behave like +link_to_remote+, but shows a spinner while the request is processing.
#   link_to_remote_with_spinner 'Hi', :url => hi_path
# You can specify the spinner and the container to hide
#   link_to_remote_with_spinner 'Hi', :url => hi_path, :container_id => 'container', :spinner => 'spinner'
def link_to_remote_with_spinner(title, options)
  element_id = options.delete(:id) || ('link_to_' + title.underscore.tr(' ', '_'))
  container_id = options.delete(:container_id) || element_id
  
  returning '' do |out|
    unless spinner = options.delete(:spinner)
      spinner = "#{element_id}_spinner"
      out << image_tag('spinner.gif', :id => spinner, :style => 'display:none')
    end
    options[:complete] = "$('#{spinner}').hide(); " + (options[:complete] || "$('#{container_id}').show()")
    
    out << link_to_remote(title, { :loading => "$('#{container_id}').hide(); $('#{spinner}').show()" }.merge(options),
                                 { :id => element_id })
  end
end

Refactorings

No refactoring yet !

Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

September 21, 2007, September 21, 2007 07:42, permalink

No rating. Login to rate!

With the above code you could already specify the onComplete callback overriding the container hiding thing, I just added the same thing for the loading callback and now you got more freedom then a jobless freelancer on crack.

def link_to_remote_with_spinner(title, options)
  element_id = options.delete(:id) || ('link_to_' + title.underscore.tr(' ', '_'))
  container_id = options.delete(:container_id) || element_id
  
  returning '' do |out|
    unless spinner = options.delete(:spinner)
      spinner = "#{element_id}_spinner"
      out << image_tag('spinner.gif', :id => spinner, :style => 'display:none')
    end
    options[:complete] = "$('#{spinner}').hide(); " + (options[:complete] || "$('#{container_id}').show()")
    options[:loading] = "$('#{spinner}').show(); " + (options[:loading] || "$('#{container_id}').hide()")
    
    out << link_to_remote(title, options, { :id => element_id })
  end
end

# Now if you specify complete and loading you can do wathever you want:
link_to_remote_with_spinner 'Grey out text', :url => ouch_path, :id => 'my_link',
                            :loading => toggle = "$('my_link').toggleClassName('disabled')",
                            :complete => toggle
                            
link_to_remote_with_spinner 'Dont click!', :url => ouch_path,
                            :loading => "$('notice').update('I told you not to click')",
                            :complete => "$('notice').update('Ok now! Look what you did, stupid!')"
898bf26eb61308fe717a243441cc615d

Andrew Kaspick

September 27, 2007, September 27, 2007 23:51, permalink

No rating. Login to rate!

Use my plugin at http://agilewebdevelopment.com/plugins/remote_helpers

See the readme for info on more advanced usage... or email me.

<%= link_to_remote ... %> <%= indicator %>
898bf26eb61308fe717a243441cc615d

Andrew Kaspick

September 28, 2007, September 28, 2007 01:33, permalink

2 ratings. Login to rate!

Using my plugin remote_helpers from http://agilewebdevelopment.com/plugins/remote_helpers, all of the spinner functionality is taken care of. It also works with any method that makes a remote function call.

See the plugin README in the plugin for more detailed usage.

The code below is the most basic usage. The 'indicator' method contains the spinner image and that's all there is to it... the spinner automatically gets displayed and hidden.

<%= link_to_remote 'Text', :url => your_url %> <%= indicator %>
E635ccff7389d9070f5e7e9fe8b36beb

Ryan

October 8, 2007, October 08, 2007 23:04, permalink

No rating. Login to rate!

Anymore, I always use EventSelectors.js to handle all toggling of the "loading" image. I usually keep the loading image in a nice place in the layout (often absolutely positioned) and show activity that way.

References:

1) <a href="http://rpheath.com/posts/2007/03/17/add_a_loading_image_for_all_ajax_requests">loading image for all ajax requests</a>
2) <a href="http://rpheath.com/posts/2007/06/01/rails-plugin-for-handling-ajax-spinners">Rails plugin to show loading image</a>

# include the eventselectors.js library in your layout
# put this at the very bottom:

Ajax.Responders.register({
  onComplete: function() { Element.hide('loading'); EventSelectors.assign(Rules);},
  onLoading: function() { Element.show('loading');}
})
Ae84538a417a8ebd51414b8c6ef579d5

clonecd478

May 9, 2011, May 09, 2011 00:30, permalink

No rating. Login to rate!

Well begun is half done.

Your refactoring





Format Copy from initial code

or Cancel