PJAX allows you to quickly update a section of a page using AJAX with automatic pushState support. Here I show how to use both pjax_rails and rack-pjax gems.
Looks good, but: this always renders the full layout? That does seem very wasteful to me. But I guess its a tradeoff between code complexity and performance.
Right, without PJAX I would normally add remote: true option to a link and respond with some JavaScript that renders out only exactly what I need, but that is quite a bit more work. So it is a tradeoff of performance for convenience.
That's how I was doing it prior to this episode, but it seems like window.pushstate isn't quite agreed upon between browsers on when the first time it should be fired (some browsers fire on page load, while others don't.)
Any tips with how you've dealt with this in order to make the back and forward buttons function properly (if we opt out of using pjax)?
Is there any examples you can give of this working, I've integrated PJAX into my app and would really like fading transitions, I'm not that versed in js so examples of how to integrate this code would be awesome. Any help would be massively appreciated.
Hi Ryan...Are you using this on railscasts.com? I noticed there is a bug...when you are on an episode page, click on one of the tabs like comments (I'm assuming this is using pjax). Then type in google.com and press the back button. It shows the pjax request code instead of reloading the full page.
Nice... however when I run bundle it complains about a gemfile conflict
Bundle
Bundler could not find compatible versions for gem "nokogiri":
In Gemfile:
rack-pjax (>= 0) x86-mingw32 depends on
nokogiri (~> 1.4.4) x86-mingw32
cucumber-rails (>= 1.1.1) x86-mingw32 depends on
nokogiri (1.5.0)
We're trying to use this plugin but it's not working and I have a feeling it's because we aren't converting that tag to HAML correctly. Anyone using HAML with this?
When u say 'maybe i can do something with rack'
what u mean? what means a rack app?
its something inside rails? its is a modeling pattern? where i can found material about?
It degrades gracefully for those browsers: jquery-pjax won't intercept clicks when the browser doesn't support pushstate, making the link just a normal link.
Anyone seeing the pjax links make the "page request" twice? Tried various configurations, but every pjax link makes 2 requests; the first with _pjax=true and the second without _pjax. I've changed the jquery-pjax plugin timeout to 30000 (in ms) and still no luck. I've tried various browsers, and they all are doing the something. Any suggestions?
I'm seeing that too. In the browser I get a pjax response and the page paints, then immediately I get a full page refresh. Watching the development.log in my app, I see (for example) a GET "/projects/28?_pjax=true" which runs the controller and renders the views. Then immediately there is another request "GET /projects/28" which again runs the controller, renders thew view and sends it back to the browsers. On the second request all the assets (images, javascript, etc...) are sent also.
Maybe the request is just meeting a timeout, in which case it falls back to a normal request. You can configure the timeout delay, which is by default 650ms.
I finally had a chance to get back to this and discovered that tonight. After getting it working I came back here to let David know how I solved it. You are correct, the timeout is very low and at least for me running nginx/passenger/rails in dev mode is just too slow to respond. I changed the JS/CoffeeScript to:
I had the same issue however raising the timeout delay did not work for me. What I found though was the initial PJAX request was rendering the application layout, so I found this fix. In other words I added this:
ruby
defindex# your code here
render layout:falseif request.headers['X-PJAX']
end
I haven't figured out why the initial PJAX request was rendering my application layout, which is weird especially given that when I make PJAX requests to all my other pages the same behaviour does not occur.
I'm trying to use rack-pjax on the top div container and I can see the performance difference even the pushState reload whole body (header still loaded)
If the response comes back faster than 500ms, won't this look a little funny? Testing in this in my local environment, I've had PJAX load in the response before the div was finished fading.
My workaround for the moment is to hide immediately and then fade in, which still looks better than a simple replacement.
I added rack-pjax and it works but there is always an extra "&" at the end of the URL shown in browser bar even if my link doesn't have it. This breaks my link_to_unless ...
If I remove
$('.navbar a').pjax('[data-pjax-container]')
from my .js.coffee file, the & goes away.
Example link I use in my application navbar
<%= link_to_unless(params[:category].to_s == "Application", "Application", {:controller => "top10", :action => "index", :category => "Application"}) %>
In Chrome 17, when I hover this link, it shows
http://localhost:3000/top10?category=Application
but when I click it, the current URL in the top Chrome bar is
http://localhost:3000/top10?category=Application&
pjax_rails gem has changed significantly since this railscast was released and hence if you are trying to use it as per screencast, you may face errors.
First thing is, pjax_rails plugin does not add that pjax handler by default to all the links anymore. You will have to specify the elements for which you want pjax to work via, $('a').pjax('#data-pjax-container')
Seond thing, pjax_rails will automatically disable layout rendering if it it detects request is of type pjax.
Looks good, but: this always renders the full layout? That does seem very wasteful to me. But I guess its a tradeoff between code complexity and performance.
Right, without PJAX I would normally add
remote: true
option to a link and respond with some JavaScript that renders out only exactly what I need, but that is quite a bit more work. So it is a tradeoff of performance for convenience.That's how I was doing it prior to this episode, but it seems like window.pushstate isn't quite agreed upon between browsers on when the first time it should be fired (some browsers fire on page load, while others don't.)
Any tips with how you've dealt with this in order to make the back and forward buttons function properly (if we opt out of using pjax)?
you can use
Alike, you can use request.headers['X-PJAX'] + parameters to determine what to render in templates too, if you feel like it
pjax is cool and all, but what about adding transition effects?
So after perusing the github pages for pjax, it seems like you could do this:
thanks for this, this is awesome, do you have any examples with it working? Not ready to play around w/ PJAX yet but i'd love to see what you did
Is there any examples you can give of this working, I've integrated PJAX into my app and would really like fading transitions, I'm not that versed in js so examples of how to integrate this code would be awesome. Any help would be massively appreciated.
Totally blown away by this. It makes AJAX so much easier, the way it should be, thank you
Hi Ryan...Are you using this on railscasts.com? I noticed there is a bug...when you are on an episode page, click on one of the tabs like comments (I'm assuming this is using pjax). Then type in google.com and press the back button. It shows the pjax request code instead of reloading the full page.
I confirm this bug. Steps to reproduce:
Edit: It has already been reported on Github
Wael
Added a comment with solution on GitHub page https://github.com/ryanb/railscasts/issues/12
There is an error in the notes for pjax_rails. The manifest file should just be
//= require pjax
Nice... however when I run bundle it complains about a gemfile conflict
I just released a new version of rack-pjax, it includes specs and fixes this issues as well.
How do you create the following div in HAML?
We're trying to use this plugin but it's not working and I have a feeling it's because we aren't converting that tag to HAML correctly. Anyone using HAML with this?
%div(data-pjax-container="true")
Works the same and still looks semantic.
Thanks. This plugin still isn't working for me so I guess that wasn't the issue.
I have the same problem, somebody can help me ?
You can use it this way:
It is especially handy when you have several "data-" attributes, this way you don't have to repeat the "data-" part.
Hello Ryan
Great screencast.
I was wondering, is it possible to use the pjax functionality with a search button instead of a link?
Whem I try I get this
No route matches [GET] "/undefined"
When u say 'maybe i can do something with rack'
what u mean? what means a rack app?
its something inside rails? its is a modeling pattern? where i can found material about?
jquery-pjax isn't compatible with browsers not supporting pushstate, like all released IEs. A trade-off between convenience and compatibility.
It degrades gracefully for those browsers: jquery-pjax won't intercept clicks when the browser doesn't support pushstate, making the link just a normal link.
Anyone seeing the pjax links make the "page request" twice? Tried various configurations, but every pjax link makes 2 requests; the first with _pjax=true and the second without _pjax. I've changed the jquery-pjax plugin timeout to 30000 (in ms) and still no luck. I've tried various browsers, and they all are doing the something. Any suggestions?
I'm seeing that too. In the browser I get a pjax response and the page paints, then immediately I get a full page refresh. Watching the development.log in my app, I see (for example) a GET "/projects/28?_pjax=true" which runs the controller and renders the views. Then immediately there is another request "GET /projects/28" which again runs the controller, renders thew view and sends it back to the browsers. On the second request all the assets (images, javascript, etc...) are sent also.
I haven't found a solution yet.
Maybe the request is just meeting a timeout, in which case it falls back to a normal request. You can configure the timeout delay, which is by default 650ms.
Thanks VonD,
I finally had a chance to get back to this and discovered that tonight. After getting it working I came back here to let David know how I solved it. You are correct, the timeout is very low and at least for me running nginx/passenger/rails in dev mode is just too slow to respond. I changed the JS/CoffeeScript to:
Now it's working find :)
Thanks, bitencode. This works great!
And thank you all, too!!
Bitencode, I am SO glad I stopped by the comments section here after debugging for 3 hours :D thank you!
I had the same issue however raising the timeout delay did not work for me. What I found though was the initial PJAX request was rendering the application layout, so I found this fix. In other words I added this:
I haven't figured out why the initial PJAX request was rendering my application layout, which is weird especially given that when I make PJAX requests to all my other pages the same behaviour does not occur.
Hope that helps someone though. :)
any idea if this works with mouseovers?
I'm trying to use rack-pjax on the top div container and I can see the performance difference even the pushState reload whole body (header still loaded)
I'm using pjax_rails. How do I call a particular link in a non-pjax mode?
Got it - 'data-skip-pjax' => true
Thanks 。
Here's a useful jquery snippet for anyone looking to do jquery powered transitions on their PJAX calls:
Simple slide down
could also be used for Fades, etc.
Should go without saying to use it in $(document).ready function, or similar.
If the response comes back faster than 500ms, won't this look a little funny? Testing in this in my local environment, I've had PJAX load in the response before the div was finished fading.
My workaround for the moment is to hide immediately and then fade in, which still looks better than a simple replacement.
I added rack-pjax and it works but there is always an extra "&" at the end of the URL shown in browser bar even if my link doesn't have it. This breaks my link_to_unless ...
If I remove
$('.navbar a').pjax('[data-pjax-container]')
from my .js.coffee file, the & goes away.
Example link I use in my application navbar
<%= link_to_unless(params[:category].to_s == "Application", "Application", {:controller => "top10", :action => "index", :category => "Application"}) %>
In Chrome 17, when I hover this link, it shows
http://localhost:3000/top10?category=Application
but when I click it, the current URL in the top Chrome bar is
http://localhost:3000/top10?category=Application&
Any idea ?
Thanks
Thanks. This was a really nice and useful screencast for me. I also wrote a related blog post covering Pjaxifying search form, pagination, etc. http://blog.assimov.net/post/19250353925/rails-search-form-with-pjax
pjax_rails gem has changed significantly since this railscast was released and hence if you are trying to use it as per screencast, you may face errors.
First thing is, pjax_rails plugin does not add that pjax handler by default to all the links anymore. You will have to specify the elements for which you want pjax to work via, $('a').pjax('#data-pjax-container')
Seond thing, pjax_rails will automatically disable layout rendering if it it detects request is of type pjax.
Thanks for the note.
I wonder if we could use multiple containers for pjax. so when a link in div 'one' has clicked, the content in the div 'two' loaded.
FYI - Excellent talk by DHH on PJAX.
Also http://www.youtube.com/watch?v=3ml88L39cng by Adrian Holovaty (django).
An episode on Turbo links? https://github.com/rails/turbolinks
@rayn ,,I think now both gems has problems ,,,I found a jquery plugin which is more easy ,,just need to be used in rails
https://github.com/vdemedes/joconut
If you're using this now, note that the example in the github repo is incorrect
https://github.com/rails/pjax_rails
should be:
not:
see issue:
https://github.com/rails/pjax_rails/issues/51
@hayksaakian You save my day!
help,i have a trouble with the pjax ..
btw,my english is pool,maybe there's some mistakes ~
ok,i download the lastest pjax at https://github.com/defunkt/jquery-pjax
then code as the demo,but it doesn't work,also there's no errors.
when i click on the link,it refresh whole page.
could any one help me ?thanks a lot!
email:miles.luffy@gmail.com
All my request seem to get canceled after 650 ms.
the console starts and then the status is cancelled? seems the timeout isn't working, as I read the default timeout is 650ms. any ideas?
I'd like to recommend Wiselinks:
https://github.com/igor-alexandrov/wiselinks
I like it better than both PJAX and Turbolinks
Pjax library has changed
First you have to call the new pjax function like this in the coffeescript file:
$(document).pjax('a[data-pjax]', '#pjax-container')
Notice that the div container is now a normal div with an id "pjax-container"
I've seen this everywhere.
This was coming, I know.