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.
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.
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!
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.
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 :-)
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.
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.
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?
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.
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!
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
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.
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?
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.
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?
I have the same problem.
I don't know why "<% javascript "pagination" %>" is not work.
But
I fixed by: Add pagination javascript lib:
<%= javascript_include_tag 'pagination' %>
into EITHER header OR view
Reason: Without this javascript lib or this one was added before.
I followed your video, and got everything working. But now when i run my search through thinking_sphinx the pagination stops working... Any thoughts on that?
If you use Kaminari for pagination, there's no need for adding "click" event thru Javascript. Just adding :remote => true in the view works. Check https://github.com/amatsuda/kaminari
I am moving snorby.org to jQuery and this was a huge help - very clean. Thank you.
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/
Very nice Ryan, I'm especially looking forward to the follow-up episode with the changing URL and history maintenance etc.
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.
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.
Here's another slightly different solution to get you a similar result.
http://weblog.redlinesoftware.com/2008/1/30/willpaginate-and-remote-links
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!
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
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!!
@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
Excellent screencast!
Lots of info packed on this one, thank you!
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 :-)
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.
unintrusive => unobtrusive
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
Simplify that code! Use $.getScript(url)
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!
@brian
Just add to any HTML page
<noscript>Your Browser Has Javascript disabled. Enable It</noscript>
Geoff you don't need to add the noscript ugliness as it will work as a regular link without javascript turned on.
You use a nice little helper called javascript to add to the list of javascript loaded on each page. Is this a plugin ?
Amazing , unquestionably fabulous ... is there anything like jQuery "live" for prototype ?? thanks alot .
@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
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!
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.
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?
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.
Brilliant!
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!
Thank you for choosing to make this demonstration with jQuery. Most people I know using Rails these days wants to or is using jQuery.
Great and timely article and thanks to Mislav for posting his prototype solution (which works great btw).
@Joseph Silvashy
LMAO!!!
Isn't this line missing a right parenthesis:
$(".pagination a").live("click", function() {
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
You are the most awesome person in the world! Looking forward to the next episode! Thanks a lot as always!
Another great Railscast, and oddly exactly at the time I needed to know this!
This is my favorite cast so far.
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.
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.
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?
Would it be possible to get use flash[:notice] to display the loading message?
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
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.
Thanks man these informations are very helpful
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.
chinese guy can see this posts : http://www.blogjava.net/fl1429/archive/2009/08/25/292522.html
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
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?
I have the same problem.
I don't know why "<% javascript "pagination" %>" is not work.
But
I fixed by: Add pagination javascript lib:
<%= javascript_include_tag 'pagination' %>
into EITHER header OR view
Reason: Without this javascript lib or this one was added before.
Steve, I have the same problem. <% javascript "pagination" %> does not call the script.
Ok, so if you have <%= javascript_include_tag :defaults %> in your header along with the call to jquery, it will not work, FYI.
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
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!
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....
Man this is awesome! I love your screencasts :)
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????
Good suggestion from iGEL (comment 13).
To have the page scroll to the top when the navigation link is clicked, simply append this line to pagination.js script:
$("html, body").animate({ scrollTop: 0 }, "slow");
To: Abdul Shajin,
It worked for my rails 3 app.
Hello.
I followed your video, and got everything working. But now when i run my search through thinking_sphinx the pagination stops working... Any thoughts on that?
Cheers
@Lee Your post got me unstuck, thank you!
Instead of
$(".pagination").html("Page is loading...");
use
$(this).parent().html("Page is loading...");
so it works when doing more than one pagination per page.
Is there a carousel with similar functionality as will_paginate using AJAX?
If you use Kaminari for pagination, there's no need for adding "click" event thru Javascript. Just adding :remote => true in the view works. Check https://github.com/amatsuda/kaminari
If anyone is stuck on this:
$().live is not a function - JavaScript/jQuery
I solved it by switching 'live' to 'on'. Seems like the live-function is a little bit outdated.
Also, you need to bind to the parent. Mine (coffee script):
Hello very nice screencast but i'm stuck with a small issue hope u help me out.
In my case when i click on the links, it gets stuck on 'page loading' message forever. It does NOT refresh or render anything.
Just for your info i'm using haml not erb. So i named the file index.js.haml
I'm using latest jquery(3.0.4) through jquery-rails gem