kaminari ajax pagination not updating the paginate - ruby-on-rails

I'm implementing pagination in rails3 using the kaminari gem.
I've been following this code from github
https://github.com/amatsuda/kaminari_example/commits/ajax
unfortunately, the following code
jQuery('#paginator').html('<%= escape_javascript(paginate(#recipes,:remote=>true).to_s) %>');
does not seem to be working.
my javascript for what to do what a user selects a page is
jQuery('a','nav.pagination').click(function(){
// get the page value from href
var page = jQuery(this).attr('href').replace('/home/index?page=','');
jQuery.getJSON('?page='+page, function(data){
for (var r in data){
results.push(data[r]);
});
showResults(results,(page-1)*10);
jQuery('#paginator').html('<%= escape_javascript(paginate(#recipes,:remote=>true).to_s) %>');
});
the showResults function runs through the JSON and creates a bunch of html elements.
Everything is working great, except that the pagination isn't updating to show the current page when the results are reloaded.
I don't get any errors in firebug, i'm using Rails 3 with ruby 192.

Are you sure you have '#paginator' element for the paginator in you HTML?
I mean, does the following code return the element on Firebug?
jQuery('#paginator')

In order to update result and paginate you need to update both at a time.
Paginate AJAX sends a request as JS so to handle them you should have action.js.erb file inside view folder. Perform two things here.
1) Update result
$("#issues").html("<%= j render(:partial => 'recipes') %>");
2) Update Paginate
$('.pagination').html('<%= escape_javascript(paginate(#recipes, :remote => true).to_s) %>');
Find respective page attribute to update paginate. This will update result and paginate run time.

Related

will_paginate with ajax is working in one page but not in other

I am using will_paginate with ajax.
I do it like that:
#requests = Model.paginate(per_page: 20, page: params[:page])
<%= will_paginate #requests %>
and in js:
$(document).on("click","#requests th a, #requests .pagination a", function() {
$.getScript(this.href);
return false;
});
This one works fine.
BUT when i use the same method for other page:
#requests = SomeOtherModel.paginate(per_page:2, page: params[:page])
and put will_paginate inside view.
But pagination is not working.
POSSIBLE PROBLEM:
In first case I use pagination for request model, inside requests_controller. (and i have request resource defined).
But in the second case I am in closed_requests view page, whose action is inside the request_controller.
1st case hrefs on paginated links:
/?page=2
(before click)
after clicking on pagination links hrefs loook like that
/?_=1433158161065&page=2
In the 2nd case:
/requests/closed_requests?page=2
I suspect that link is builded wrongly. It is not consistent with the first.

Does will pagination work with forms which have method="POST"?

I switched my advanced order form to POST from GET as the URI request became too large for browsers to handle. Everything works fine, with the exception of will pagaination. It keeps adding the page to the url itself http://localhost:3000/orders/advanced_search like http://localhost:3000/orders/advanced_search?page=2 which fails as this is a post call, and not a get call.
Any way that it can just update the params[:page] but not do anything to the link?
I used to just call <%= will_paginate #orders["order_items"] %> which worked great when it was a GET call where
#orders["order_items"] = #orders["order_items"].paginate(:page => params[:page],
:per_page => limit, :total_entries=>#orders["total"])
What I want is simple, add it to params, but do not add it to the link.
The other answer posted is wrong. will_paginate was NOT built to work with post requests.
Your choices to 'make' will_paginate work with post request include:
writing some javascript to:
preventDefault on click of the will_paginate-generated link
$(".pagination li a").click(function(e){
e.preventDefault(); ....
find the target page via the clicked link.
(below code is assuming all will_paginate links have a query string...which they do. But note that this particular line of code won't work if you are passing in more params in the controller via the params option for will_paginate..which you shouldn't be in the first place because we are trying to achieve a post request.)
var tp_id = $(this).attr("href").split('?page=')[1]
generate a hidden input with the correct name attribute depending on the clicked will_paginate link.
$('form').append("< input type='hidden' name='page' value='" + tp_id +"' >")
finally post to the controller action of the search form.
$('form').submit()
.done. I hope this puts you on the right path.
You can add a param to will_paginate
https://github.com/mislav/will_paginate/wiki/API-documentation
<%= will_paginate #orders['order_items'], :params => { :method => :post } %>
If it doesn't work, set te complete controller and action to params.

Kaminari with AJAX, unable to paginate

I've followed the AJAX Kaminari example here: https://github.com/amatsuda/kaminari_example/tree/ajax
I've successfully generated the partial and table. However, pressing the pages in the pagination does not update my table. In fact, upon pressing, the queries are the exact same data.
I found a similar problem, however the solution remains unanswered:
kaminari ajax pagination not updating the paginate
I can verify that I am using the #paginator element.
Some things I did do differently were instead of creating a separate js.erb file, I added
<script>
$('#paginator').html('<%= escape_javascript(paginate(#pending_requests, :remote => true).to_s) %>');
$('#requests').html('<%= escape_javascript render (#pending_requests) %>');
</script>
at the end of the of my html.erb file.
Also, in a view, I use an ajax request to select different data within the table. For example, I have a select_tag which upon selecting a user, the appropriate table is rendered using AJAX in the view. The table isn't a partial, it has its own view and method in the controller. At first I suspected that because of this, the table wasn't being updated. However, if I go to the table url, I am still unable to use pagination!
Edit: I am able to right-click the pagination links and open them to another tab. Clicking on them still doesn't do anything.
EDIT:
I wanted to add that I'm using Twitter Bootstrap. I noticed that if I set in my controller
format.html { render :layout => false }
Then I open one of the pagination links to another page, I can successfully paginate. I am using the Kaminari bootstrap theme however...
I didn't see a place to add a comment, so this is not a real answer.
Do only render the table with AJAX? Is the partial part of another page? Or is a stand alone view?
I had a similar problem (last post before your on the Kaminari tag page link where I had the option to render the table as a partial in a show view or as a separate page. that messed things up. I ended up, like you adding a script tag, but yours in not wrapped in a document ready function, so the page might not be fully loaded. Try.
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$('#paginator').html('<%= escape_javascript(paginate(#pending_requests, :remote => true).to_s) %>');
$('#requests').html('<%= escape_javascript render (#pending_requests) %>');
})
</script>

rails 3,Kaminari pagination for an simple Array

For paginating a common array I got this solution,
#arr_name =
Kaminari.paginate_array(#arr_name).page(params[:page]).per(PER_PAGE_RECORDS)
PER_PAGE_RECORDS is a variable with value as per needed for pagination.
Any better Ideas??
Also to have an ajax call for using pagination one can use this,
In your view,
give id to your div tab
div id="paginate"
and inside it
<%= paginate #arr_name, :remote => true %>
And in js response file put,
$('#paginate').html('<%= escape_javascript(paginate(#arr_name, :remote
=> true).to_s) %>');
So your requests will be AJAX.
Thanks.
This is the only available helper method to paginate an array object using Kaminari. Another alternative is, as suggested solution in kaminari wiki page, add the instance methods to the array object.
If you are trying a common solution based on the ActiveModel return type ( .all returns array and .where returns ARL) then following is an workaround.
unless #arr_name.kind_of?(Array)
#arr_name = #arr_name.page(params[:page]).per(PER_PAGE_RECORDS)
else
#arr_name = Kaminari.paginate_array(#arr_name).page(params[:page]).per(PER_PAGE_RECORDS)
end

Best way to get will_paginate working with Ajax

If you google "will_paginate" and "ajax", the top result is this blog post: But the original author of will_paginate says to not use this method (bad for SEO/spiders) ...
But I cant get the original authors method to work (his javascript kills all my links). An other gentleman suggests a similar method to mislav's (the original will_paginate author) concept. But I cant get that to work either.
so .... what is the best way to paginate using AJAX, and stay SEO friendly? (for RAILS >2.1)
Tomh's answer is correct. Just for shiggles, I prototyped a quick implementation. Here's a screencast that shows it using Ajax when Javascript is enabled (your users) and still having pretty URLs when Javascript is disabled (Google). And here are a few code snippets to get you rolling on it.
config/routes.rb:
map.connect 'items/:page', :controller => "items", :action => "index", :page => 1
app/controllers/items_controller.rb:
class ItemsController < ApplicationController
def index
#items = Item.paginate(:all, :page => params[:page])
respond_to do |format|
format.html
format.js do
render :update do |page|
page.replace_html :items, :partial => "items"
page << "ajaxifyPagination();"
end
end
end
end
end
app/views/items/index.html.erb:
<h1>Listing items</h1>
<div id="items">
<%= render :partial => "items" %>
</div>
app/views/items/_items.html.erb:
<%= will_paginate #items %>
<table>
<% for item in #items %>
<tr>
<td><%= item.id %></td>
</tr>
<% end %>
</table>
layout:
<%= javascript_include_tag :defaults %>
public/javascripts/application.js:
$(document).ready(function() {
ajaxifyPagination();
});
function ajaxifyPagination() {
$(".pagination a").click(function() {
$.ajax({
type: "GET",
url: $(this).attr("href"),
dataType: "script"
});
return false;
});
}
My example uses jQuery (with jRails), but it's straightforward to do with Prototype as well.
Seo friendly and unobtrusive javascript goes hand in hand. What you can do is the following.
Code the entire site as if only html is enabled (incl your pagination thing)
Use respond_to and serve only the list of items if the request comes in from js
Using onDomReady from whatever library you pick you attempt to catch all pagination links and add an onclick event which triggers an ajax call to that new view and returns the result. You put that result into the container containing the data you are paginating. The onclick then returns false.
To give your users a better user experience you can add some features like active links etc to the same javascript method.
Using this approach the pagination will work for JS and non-js as the non-js users (including Googlebot) will traverse your pagination as normal. Only in the event that the user has javascript enabled, the container with data will be updated with new results.
Unfortunately, I don't think you can use Ajax in the way you want and still stay SEO friendly as far as the paginated content. The problem is that the robots of Google and friends, as far as I know, won't go through your content using XHR requests so they simply won't see that content.
That said, if the paginated items each have their own static, SEO-friendly pages (or are otherwise statically available on your site), the content will still find its way into their engines. This is the way you'll probably want to go.
There is a railscasts on this topic which helped me out http://railscasts.com/episodes/174-pagination-with-ajax
I'm running rails 3.2, so I added the pagination.js there mentioned to app/assets/javascripts folder
pagination.js
$(function() {
$(".pagination a").live("click", function() {
$(".pagination").html("Loading...");
$.getScript(this.href);
return false;
});
});
And then created
home.js.erb
$('#div_tags_list').html('<%= escape_javascript(render partial: '/customersb2b/user_customer_numbers_list').html_safe %>')
$('#receipts_list').html('<%= escape_javascript(render partial: '/customersb2b/feed').html_safe %>')
Since I have two distinct listings on my homepage.
This is all I had to do to put will_paginate working with Ajax.
As for the SEO concerns, well, I don't know much about it, but the URL http://localhost:3000/customers?_=1366372168315&feed_page=1&tags_page=2 still works
There is a great way to do this easily if not worried about spiders. Took me 5 minutes. Check out:
https://github.com/ronalchn/ajax_pagination/wiki/Adding-AJAX-to-will_paginate
If you get an error about a missing 'history' file, install:
https://github.com/wweidendorf/jquery-historyjs
but also be aware of:
rails ajax_pagination couldn't find file 'history'

Resources