Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

will_paginate ajax with fade

I'm trying to ajaxify my will_pagniate pagination in rails. I want to have the old page fade out and the new one fade in.

Here's the relevant part of my controller:

respond_to do |format|
  format.html # new.html.erb
  format.js {
    render :update do |page|
      page.replace 'page', :partial => 'cur_page'
    end
  }
  format.xml  { render :xml => @branch }
end

The aforementioned partial:

<div id="page">
  <%= will_paginate %>
  <div id="posts">
    <%= render @posts %>
  </div>
  <%= will_paginate %>
</div>

And the relevant part of application.js:

document.observe("dom:loaded", function() {
  // the element in which we will observe all clicks and capture
  // ones originating from pagination links
  var container = $(document.body)

  if (container) {
    var img = new Image
    img.src = '/images/spinner.gif'

    function createSpinner() {
      return new Element('img', { src: img.src, 'class': 'spinner' })
    }

    container.observe('click', function(e) {
      var el = e.element()
      if (el.match('.pagination a')) {
        el.up('.pagination').insert(createSpinner())
        target = $('posts')
        new Effect.fade(target, { duration: 0.3, afterFinish: function()
          {
            new Ajax.Request(el.href,
            {
              method: 'get',
              onSuccess: function(){ new Effect.Appear(target, {duration:0.3})}
            })
        }})
        e.stop()
      }
    })
  }
})

The script seems to get killed on this line,

        new Effect.fade(target, { duration: 0.3, afterFinish: function()

because I see the spinner.gif start, then no fading and the page is refreshed normally. I have got the ajax working before I tried to add Effect.Fade and Effect.Appear.

Is this the right way to go about this? Should I put the effects in the controller instead?

like image 800
freedrull Avatar asked Jan 31 '11 23:01

freedrull


3 Answers

Here is what I did using jQuery and working well too :)

Put your will_paginate helper view call in a div

#tickets_pagination
  = will_paginate @tickets

In application.js

$("#tickets_pagination .pagination a").live("click", function() {
  $.get("/users/?"+this.href.split("?")[1], null, null, "script");
  return false
});

The javascript above will convert the pagination links in #tickets_pagination to ajax links

In your controller as usual

def index
  @tickets = Ticket.all.paginate({:page => params[:page], :per_page => 10 })
  respond_to do |format|
    format.js
    format.html
  end
end

Now finally in index.js.erb

$("#tickets_list_table").fadeOut('slow');
$("#tickets_list_table").html("<%= escape_javascript(render :partial =>'tickets/tickets_table', :locals => {:tickets => @tickets}) %>");
$("#tickets_list_table").fadeIn('slow');

Here tickets/ticket_table has a table that lists all tickets. The partial is rendered in a div #ticket_list_table

Hope this will work for you as well.

like image 146
Pravin Avatar answered Nov 08 '22 02:11

Pravin


I tried putting more of the work into the javascript helpers:

respond_to do |format|
  format.html # new.html.erb
  format.js {
    render :update do |page|
      page.visual_effect :fade, 'posts', :afterFinsh => "function(){" +
      page.replace 'page', :partial => 'cur_page' +
      page.visual_effect(:appear, 'branches') + "}"
    end
  }
  format.xml  { render :xml => @branch }
end

Then removed this part of the javascript:

new Effect.fade(target, { duration: 0.3, afterFinish: function()

I get the effect I want, but all out of order. The request completes and the html is replaced, then the div fades out and then reappears!

like image 43
freedrull Avatar answered Nov 08 '22 03:11

freedrull


Not very familiar with RoR, does it generate its own client-side JS that may possibly be battling your code?

If not, I would say the problem is somewhere in your own client-side code. For testing, get rid of the HREF attribute from the anchor tag and place the URL as a string literal in the Ajax request. If nothing happens, there is a problem with the Ajax request itself. If the page loads as expected, then the event in the original scenario is not being completely stopped.

Also, clean up your JS a bit just to be sure, line-ending semi-colons where needed.

like image 28
Matt Molnar Avatar answered Nov 08 '22 03:11

Matt Molnar