#174
Aug 10, 2009

Pagination with AJAX

Learn an easy, unobtrusive way to add AJAX functionality to an existing set of pagination links using jQuery.
Tags: ajax views
Download (24.5 MB, 13:18)
alternative download for iPod & Apple TV (15.9 MB, 13:18)

Resources

# config/environment.rb
config.gem "mislav-will_paginate", :lib => "will_paginate", :source => "http://gems.github.com"

# products_controller.rb
def index
  @products = Product.paginate(:per_page => 10, :page => params[:page])
end
<!-- layouts/application.html.erb -->
<%= javascript_include_tag 'jquery' %>

<!-- products/index.js.erb -->
$("#products").html("<%= escape_javascript(render("products")) %>");
// public/javascripts/pagination.js
$(function() {
  $(".pagination a").live("click", function() {
    $(".pagination").html("Page is loading...");
    $.get(this.href, null, null, "script");
    return false;
  });
});

// For older jQuery versions...
// jQuery.ajaxSetup({ 
//   'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
// });

RSS Feed for Episode Comments 67 comments

1. Mephux Aug 10, 2009 at 00:54

I am moving snorby.org to jQuery and this was a huge help - very clean. Thank you.


2. Vojto Aug 10, 2009 at 00:55

I did just the same thing last week!

Except that I used also history plugin for jQuery - which makes also back/forward buttons work :)

http://www.balupton/projects/jquery_history/


3. Adam Hill Aug 10, 2009 at 02:00

Very nice Ryan, I'm especially looking forward to the follow-up episode with the changing URL and history maintenance etc.


4. Radoslav Stankov Aug 10, 2009 at 03:32

Great cast as always.
I use the same technique for my projects. I will be great in some of the future screen casts you show sprockets for managing js dependencies.


5. hjuskewycz Aug 10, 2009 at 03:56

Thank you Ryan, like Adam I am really looking forward to the next episode because I think AJAX pagination like in this episode breaks the UI. Losing URL/history is always a high price for AJAX.


6. Dave Shenk Aug 10, 2009 at 03:59

Here's another slightly different solution to get you a similar result.

http://weblog.redlinesoftware.com/2008/1/30/willpaginate-and-remote-links


7. Brian Armstrong Aug 10, 2009 at 05:36

Yep I think the solution posted by Dave Shenk is simpler:
http://weblog.redlinesoftware.com/2008/1/30/willpaginate-and-remote-links

This is what I used in the past. Perhaps the downside to it (and why you didn't include it) is that it doesn't fall back for people who have javascript turned off?

Probably 90% of the stuff on my site doesn't work without JS. Actually that would be a good railscast...how to display a generic message to people who have JS turned off, like basecamp. Thanks!


8. Chris Gunther Aug 10, 2009 at 08:22

Great screencast Ryan. I did something similar to this on one of my own sites recently. Looks like it may be easier to use the live method as opposed to my own event bubbling solution. Anybody know if there is any kind of a performance hit in using live versus defining a normal click handler on a parent element and detecting the target?

Ryan, for future screencasts, could you consider doing them from a TDD/BDD approach? I know you've done some screencasts on testing, but I think tackling them from a TDD/BDD approach on a regular basis would help people (myself atleast) get into the same habits themselves.

Thanks,
Chris


9. Millisami Aug 10, 2009 at 09:05

Great screencast!! and thanx as always.

I'm concerned about the ?_263635377 parameter that is appended in those page links?

I've too seen this in my own project and haven't figured out what that is coz it doesn't break the funcationality. just curious!!


10. Luciano Aug 10, 2009 at 10:01

@Millisami, I saw that extra parameter also... you can work it out by moving the pagnation links from the products partial into the index view...

Thanks


11. lobo_tuerto Aug 10, 2009 at 10:04

Excellent screencast!

Lots of info packed on this one, thank you!


12. clee Aug 10, 2009 at 10:52

Monday's just wouldn't be the same without your excellent screencasts.
Also, I agree that maybe a series of BDD/TDD approaches to creating a solution would be helpful ... it would be nice to compare techniques.
Gotta go watch this screencast :-)


13. iGEL Aug 10, 2009 at 11:09

Hi!

Thank you for introducing the unintrusive JavaScript topic. I learned only a few months about this by a talk from DHH, who said Rails 3.0 will use unintrusive JavaScript, which seems a very good idea (especially for Prototype deserters like me).

But actually I don't think that pagination is a good example for the usage of ajax. Pagination will usually change large potions of the visible text (more than 90%), so I think it's better to traditionally load the page.

Also you have to remember lot's of things the user expects from a paginated list, like you said, giving the user a proper loading feedback or the usability of the back and next button. Also, the user expect the page to return to the top, if the page was scrolled down. There are probably other usability expectations as well.

Don't break an expected and learned behavior without a good reason.


14. iGEL Aug 10, 2009 at 11:11

unintrusive => unobtrusive


15. Scott Motte Aug 10, 2009 at 11:24

Thanks Ryan. Great video. For anyone interested, here is how to do similar in merb, but with a 'more' pagination similar to twitter's instead.

http://scottmotte.com/archives/217.html


16. Jim Gay Aug 10, 2009 at 13:51

Simplify that code! Use $.getScript(url)


17. Michael Aug 10, 2009 at 16:45

Nice Screencast. Was wondering what a good approach would be to accomplish this.

Looking forward to next weeks screencast to see your take on handling the history-variant of this.

Makes it easy enough to just implement in a few minutes as a progressive enhancement element. Great!


18. Geoff Evans Aug 10, 2009 at 17:29

@brian

Just add to any HTML page

<noscript>Your Browser Has Javascript disabled. Enable It</noscript>


19. Richard McIntyre Aug 10, 2009 at 21:58

Geoff you don't need to add the noscript ugliness as it will work as a regular link without javascript turned on.


20. defsdoor Aug 11, 2009 at 02:22

You use a nice little helper called javascript to add to the list of javascript loaded on each page. Is this a plugin ?


21. eqbal Aug 11, 2009 at 03:10

Amazing , unquestionably fabulous ... is there anything like jQuery "live" for prototype ?? thanks alot .


22. Geoff Evans Aug 11, 2009 at 04:14

@richard

Quite agree in this case it is not needed to add noscript however brian wanted to know how to detect if Javascript is enabled


23. artemave Aug 11, 2009 at 07:08

What if next version of will_paginate changes class name of a pagination container div? Your code will simply stop working. Suddenly.

This solution relies on external library internals (external internals; I like that), which makes it a bit of a hack.

Still, a great demonstration of technique. Thanks!


24. Mislav Aug 11, 2009 at 08:22

Prototype.js users: the will_paginate wiki had sample code similar to this railscast for a long time now: http://wiki.github.com/mislav/will_paginate/ajax-pagination

Take a look even if you're not using Prototype.

@Ryan: something you should know about jQuery "live" method: it doesn't re-apply the event handlers to new elements inserted in the DOM. That's what the (now obsolete) plugin called "livequery" was doing. The current jQuery "live" method uses a modern and correct approach: event delegation.

Prototype.js doesn't yet have event delegation support (that's coming in a future release), but event delegation is fairly easy to use manually. I'm using it in the example code on the wiki page linked above.


25. Lucas Aug 11, 2009 at 17:40

It didn't works for me, the result of the request returns, but it's like the javascript didn't interpreted and the returns didn't been showing.
Can you help me, please?


26. Joseph Silvashy Aug 11, 2009 at 19:34

Excellent, I've had all this before, but you did show me how amazing the live() function is, and in fact, I'm incorporating this in my site. At some point there was a jQuery plugin called jQuery Live, and it did this and more, like combining both adding things to the dom and binding the events.

Anyhow thanks Ryan, also like to mention that your site is the best screencast site ever and the best deals on um... designer bags and shoes.


27. Jeff Aug 12, 2009 at 11:17

Brilliant!


28. Lee Aug 12, 2009 at 20:20

I got to the part where you illustrate an ajax request from index.js.erb by sending the alert "this is an ajax request" and I get a javascript "syntax error" in my firebug console. I never see the alert so of course the ajax doesn't work for me.

What could that be? I'm using jQuery 1.3.2. Thanks for any help!


29. Sean McCleary Aug 12, 2009 at 20:22

Thank you for choosing to make this demonstration with jQuery. Most people I know using Rails these days wants to or is using jQuery.


30. lardawge Aug 13, 2009 at 06:16

Great and timely article and thanks to Mislav for posting his prototype solution (which works great btw).

@Joseph Silvashy
LMAO!!!


31. Carl Aug 13, 2009 at 20:37

Isn't this line missing a right parenthesis:

$(".pagination a").live("click", function() {


32. squil Aug 14, 2009 at 01:47

Hi guys,
just wanted to let you know that I did a write up of how to go about adding Javascript to paginated content. It's all on my blog: http://thinksimple.pl/entries/83-AJAX-pagination-with-Javascript


33. Iceblink Aug 14, 2009 at 23:35

You are the most awesome person in the world! Looking forward to the next episode! Thanks a lot as always!


34. Amy Aug 15, 2009 at 21:56

Another great Railscast, and oddly exactly at the time I needed to know this!


35. Andrés Aug 16, 2009 at 19:11

This is my favorite cast so far.


36. Marcin Stecki Aug 16, 2009 at 23:27

Hi Ryan, great episode! However i think there is one, much more elegent solution for handling ajax request, called Taconite. My friend described it here: http://codetunes.com/2008/12/08/rails-ajax-and-jquery/
Cheers, hope you like it.


37. Lee Aug 17, 2009 at 08:02

To answer my own question (comment #33) you have to add the javascript respond_to type in your controller.

The products controller from this episode does not have any respond_to blocks. Is this common practice now to remove the respond_to blocks from controllers?

Thanks again to Ryan for such great screencasts.


38. jack Aug 30, 2009 at 08:39

I was using a custom action instead of index.

To make Rails execute the code in custom_action.js.erb (as opposed to index.js.erb), I had to use a respond_to block with format.js, like this:

respond_to do |format|
      format.html
      format.js
end

I'm not sure why Rails doesn't respond to js requests by default?


39. Arcath Aug 30, 2009 at 12:45

Would it be possible to get use flash[:notice] to display the loading message?


40. Homar Sep 01, 2009 at 01:14

Instead of printing a loading messages every time you make an AJAX call, you can use something like this:

http://docs.jquery.com/Ajax_Events


41. Rafał Filipek Sep 04, 2009 at 16:18

1) Big thanks for Your screencasts.
2)Why dont just use $("#products").load(this.href) and in view just render list of products ? You dont have to use jqeury to put generated html into proucts div.
Or maybe You have to. I was playing with this episode on CakePHP not on Rails.


42. aqar aqar Sep 08, 2009 at 17:56

Thanks man these informations are very helpful


43. Dustin Oct 22, 2009 at 08:44

For anyone who has yet to refactor their AJAX and run into Javascript conflicts,
you can use:

jQuery.noConflict();

At the head of your file and then use

jQuery instead of $ for your commands and it won't conflict with other AJAX libraries.


44. wxianfeng Dec 09, 2009 at 01:27

chinese guy can see this posts : http://www.blogjava.net/fl1429/archive/2009/08/25/292522.html


45. Michael Jan 26, 2010 at 16:03

I kept getting an error in Rails 2.3.5: undefined method 'javascript' when trying to use the command:

<% javascript "prototype" %>

So instead I used:
http://gist.github.com/287391


46. Steve Feb 09, 2010 at 16:15

Michael Thanks! I was able to get the pagination.js into the page header using the call
<script src="/javascripts/pagination.js" type="text/javascript">
</script>. Does anyone now why <% javascript "pagination" %> defined in the rails cast didn't work for me? It didn't fail, but it didn't list the jscript library in my header either. I wasn't using index.html.erb as my file name. Could this be why?


47. Clay Heaton Feb 17, 2010 at 07:38

Steve, I have the same problem. <% javascript "pagination" %> does not call the script.


48. Clay Heaton Feb 17, 2010 at 09:41

Ok, so if you have <%= javascript_include_tag :defaults %> in your header along with the call to jquery, it will not work, FYI.


49. gregor Mar 30, 2010 at 04:07

Very nice post, good work.
Very helpeful.

Gregor S.
<a href="http://www.sms-puls.de">Free SMS</a>
<a href="http://www.songdb.de">Songtexte</a>


50. gregor Mar 30, 2010 at 04:08

visit everbody


51. Resca Apr 15, 2010 at 05:17

Hi,
Maybe is better to modify js file with something like this:

-----file.js.erb
('#paginate').html("<%=escape_javascript(will_paginate(@pets))-%>")

---view
<div id='paginate'>
 <div id='pagination'>

where paginate is a div o span thath include pagination:

Because the page update with Jquery produce a nested side effect:
  <div id='paginate'>
    <div id='paginate'>
      <div id='paginate'>

Regards


52. Ruben Apr 22, 2010 at 15:42

Hello, Thanks for the post.
Im using a different action from Index, and when I click on the pages it doesnt go to my "custom_action.js.erb"

@39 - I tried with the format.js, but i have to take out format.html and format.xml to force it to get the script, but it doesnt work either...

Why is so hard to code when the action is not Index?

Thanks!


53. Brett D May 01, 2010 at 17:48

re custom_action.js.erb

I find it really easy, just match add it in your routes

all you need to do is add ".:format" on the end, so that rails can then use that in the respond_to/with e.g.

match '/contact_auto_search.:format' => 'contacts#contact_auto_search'

so I can now goto www.mysite.com/contact_auto_search.js and it responds to the js.erb file....


54. Ocean May 18, 2010 at 04:56

Man this is awesome! I love your screencasts :)


55. Deutschland Trikot May 30, 2010 at 08:28

Very useful man, thanks for sharing.


56. Sebastian Jun 27, 2010 at 03:56

very niche worke.

<a href="http://www.sms96.de/" title="Free SMS">Free SMS</a>


57. free card sharing Jun 28, 2010 at 13:44

Thank you,I think its very usefuls.


58. mail Jun 28, 2010 at 13:45

Hey everyone. I know this is an old screencast, but I wanted to add a little something to it.


59. card sharing Jun 28, 2010 at 13:45

Worth sharing this information. Good Work


60. spam Jul 06, 2010 at 01:39

This is all very new to me and this article really opened my eyes.Thanks for sharing with us your wisdom.


61. webtasarim Jul 15, 2010 at 09:05

web tasarımı, kurumsal site tasarımı, profesyonel web sitesi tasarımı, profesyonel web tasarımı

<a href="http://www.webtasarimturk.net" title="web tasarımı">web tasarımı</a>


62. Link Building Jul 22, 2010 at 11:09

another slightly different solution to get you a similar result.


63. saç ekimi Jul 25, 2010 at 19:12

thanks so much


64. tiffany Earrings Aug 04, 2010 at 20:09

@Millisami, I saw that extra parameter also... you can work it out by moving the pagnation links from the products partial into the index view...

Thanks


66. Rumana Akter Aug 05, 2010 at 04:35

A few years back, because of the lack of technology, search engines bypass sites that use an Ajax dashboard. Search engines were not programmed to detect java scripts and thus SEO bots do not list them in the search results, instead they only show crawl-able static websites.

Ajax
http://ajaxdashboard.com/


67. Ramya Aug 09, 2010 at 14:07

Hi there,

when I added the first line in the config/environment.rb I got an error message saying

/config/environment.rb:6: undefined local variable or method `config' for main:Object (NameError)

not sure why????


68. free directory list Aug 11, 2010 at 22:37

Very useful information!


69. wariror Aug 18, 2010 at 21:53

thanks admin


70. Card Sharing Aug 20, 2010 at 01:22

Thank you,I think its very usefuls.


71. Bakugan Games Aug 20, 2010 at 01:23

Great :) Thanks a lot.


72. Hurda Aug 20, 2010 at 08:08

I think type of site that is useful in sharing information and it is important to shar.Web proliferation of new developments in the field of design and entrepreneurial spirit of people who have very beautiful and pleasing to be professional.Site concept and sharing are quality thank you.


73. Wholesale baseball hats Aug 20, 2010 at 20:27

That is an awfully astounding column you've posted.Thanks a lot for that a fantastically amazing post!


74. jordan shoes on sale Aug 20, 2010 at 22:42

Many thanks for all the great screencasts. I really enjoy watching the RailsCasts. I think type of site that is useful in sharing information and it is important to share.


75. Haliyikama Aug 21, 2010 at 06:07

I think type of site that is useful in sharing information and it is important to shar.Web proliferation of new developments in the field of design and entrepreneurial spirit of people who have very beautiful and pleasing to be professional


76. medyum Aug 22, 2010 at 05:30

The information you provided was very useful. Because of your help, thank you


77. medyum Aug 22, 2010 at 05:31

Thanks for such a great post and the review, I am totally impressed! Keep stuff like this coming.


78. Buz Aug 23, 2010 at 05:58

possibility of sharing and social solidarity at a level just fine thank you


79. logar Aug 24, 2010 at 02:30

Thank you for sharing you do.


80. Wholesale Electronics Aug 25, 2010 at 01:44

Discount Wholesale Electronics, Wholesale Cell Phones, Electronic Gadgets and More from the Best Dropship Wholesaler


81. perde Aug 25, 2010 at 01:48

Your site very useful in terms of cultural exchange is one of the sites thanks.


82. konteyner Aug 26, 2010 at 01:29

a significant share of your site as people think.Thanks you


83. louis vuitton shoes Aug 26, 2010 at 21:11

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


84. palet Aug 27, 2010 at 05:27

possibility of sharing and social solidarity at a level just fine


85. palet Aug 27, 2010 at 05:28

possibility of sharing and social solidarity at a level just fine


86. вишивка хрестиком Aug 29, 2010 at 01:03

great stuff. ill share it with my twitter followers


87. USB Gadgets Aug 30, 2010 at 20:26

thanks for your sharing, it is a nice post, like it.


88. snow boots Aug 30, 2010 at 20:51

I use the same technique for my projects. I will be great in some of the future screen casts you show sprockets for managing js dependencies.


89. Web Tasarim Aug 31, 2010 at 05:36

thanks for sharing web design


90. louis vuitton sunglasses Sep 01, 2010 at 21:30

I agree with your Blog and I will be back to check it more in the future so please keep up your work. I love your content & the way that you write. It looks like you’ve been doing this for a while now, how long have you been blogging for?

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source