views:

313

answers:

3

I am converting some of my link_to_remote generators with link_to as the AJAX calls were creating issues with my browser back button. (Silly noob mistakes!)

My application has many pages that have a long wait cycle (for various reasons out of my control). I have been relying on the link_to_remote's ability to use :before and :after calls to display a spinner while the user is waiting. Does link_to have something similar? I was assuming to just toss the calls in like I was with link_to_remote ... but that really only makes sense for the :before call (and it doesn't seem to be working). What are my other options at this point?

+1  A: 

Since link_to generates a simple anchor for users to click on, probably your best option would be to add javascript handlers for document.onunload to replace your :before handlers. You're SOL for the :after handlers;-) Check out Prototype's Event.observe() for this, or use RJS for the same thing with better Rails integration.

Dave Duchene
+2  A: 

link_to "Click me", your_url, :onclick => "javascript"

ABCoder
Of course! I feel like an idiot. Thanks.
salt.racer
A: 

If you're willing to learn a little Javascript, I find doing the same stuff in jQuery to be fast and easy. It sounds like you're still doing AJAX calls, just the link_to_remote behavior was having unfortunate side effects.

If your Rails view code looks like this:

<%= link_to "Show me", slow_page_url, :class => 'remote', :'data-update' => 'display' %>

I like to add a jQuery block like so:

<% content_for :dom_ready do %>
  // register a callback for the click event on links with class 'remote'

  $('a.remote').click( function() {

    // this is the clicked_link, which you may want to 
    // persist thru several levels of callbacks
    // so assign it to a local variable

    var clicked_link = this;

    // assuming you already have a start_spinner function, 
    // and you might pass it the object where the click occured

    start_spinner(clicked_link);

    // here's the ajax call, which will automatically update 
    // the div you identified using the data-update attribute 
    // with the returned html

    $('#'+$(this).attr('data-update')).load( $(this).attr('href'), {}, function() {

       //this callback only runs when the AJAX request has completed

      stop_spinner( clicked_link );

    } );

    // prevents the click event from propagating to the window object 
    //and moving the user away from the current page

    return false;
  } );
<% end %>

Then I have all my javascript load at the bottom of my layout like so

<%= javascript_include_tag 'jquery-1.3.2.js' %>
<script type="text/javascript">
$( function() {
  <%= yield :dom_ready %>
);
</script>
austinfromboston