will_paginate + ajax deletion
I've got a list of resources that I show on a paginated list using will_paginate.
I haven't customized anything, here's my view:
<ul>
<%= render :partial => "item_li", :collection => @items%>
</ul>
<%= will_paginate @items %>
Items is calculated like this on the controller:
@items = Item.find(:all)
The generated code is a simple html list with the pagination navigation links at the bottom:
<ul>
<li>Item 1</li>
<li>Item 2</li>
...
<li>Item 10</li>
</ul>
<div class="pagination">
<span class="disabled prev_page">Previous</span>
<span class="current">1</span>
...
</div>
I have included a "delete" button on my items. When that link is pressed, there's an ajax call to the server and the item disappears from the list (the <li>
will is replaced by ""
)
My problem comes with the navigation links.
- Say that I had items 1 to 10 on the first page, items 11 to 20 on the second, etc.
- Say that I delete items 1, 2 and 3 on the first page.
- And then I press "next".
The server will "recalculate" the list of items; since I removed 3 of t开发者_JAVA百科he previous list, it will return items 13 to 22. In other words, items 10, 11 and 12 don't appear on the first page nor the second.
How can I solve this in a simple, elegant way?
So far the only solution I could find was reloading the whole page after each deletion, but then using ajax becomes pointless.
Thanks a lot.
Depending on your AJAX library, you need to implement a callback method that gets called whenever the AJAX call has completed successfully.
First, put the <%= will_paginate @items %>
into a div or some sort of container. Then, in your "success" callback, remove that div and replace it with a new one containing a new call to will_paginate @items.
This works assuming that your AJAX call to your delete method reloads the @items variable.
If you're using jQuery, it'd look something like this (assuming you give the div holding the pagination a class called "my_pagination":
$.ajaxSuccess(function(){
$(".my_pagination").text("");//Cleans out the div
$(".my_pagination").append(<%=will_paginate @items%>);//Refill the div with a new pagination
});
You may have to wrap the <%=will_paginate @items%> in quotation marks, I'm not 100% sure.
I decided to do something a bit simpler; whenever I deleted an item from the list, I loaded the item that came right after the last item on the page, and inserted it at the bottom. This way, I can delete to my heart's content, and the whole page feels snappy.
I just have to be careful with the "no more items" situations.
Thanks a lot for your answer, Zachary, but this one feels more correct.
精彩评论