Disclaimer: This might be the worst way ever to solve this requirement, but I wrote this in 10 minutes and I've never looked back! 

My plan here was to have a list of 'items' in my admin interface that the user can paginate through and select to edit.. using the joys of rails 0.11.x, pagination, ajax, and liberal helpings of vaseline.

h3. The Controller

The only 2 things of note here are the use of @render_partial@ in this action, and the @paginate@ call to set up my list of 'items' for the user to browse through. Read the Rails API docs on these two to get savvy, you savvy?

<pre>
  model :item

  ...

  # in the 'catalogue', when you click on a section, you list all the items for it. 
  # this is the paginated ajax snippet
  def item_list_with_ajax
    unless @params['id'].nil?
      @item_pages, @items = paginate :items, :conditions => "section_id = #{@params['id']}", :order_by => "name DESC", :per_page => 20
    end
    render_partial 'admin/blocks/item_nav' 
  end
</pre>

h2. The View

For fun, I've included my entire partial, showing you the love. The only thing unusual is this @pagination_links_with_ajax@ method. Where did that come from, I wonder? Life's full of mystery, I love it. I love gravy, too.

<pre>
Item Browser
<div id="item-sidebar">
<% unless @items.nil? or @items.empty? %>
  <% for item in @items %>
  <div class="little-black-text">· 
  <%= link_to_remote item.name, :update => 'content-body', :url => { :action => 'item_edit_with_ajax', :id => item.id } %>
  </div>
  <% end %>
  <hr/>
  <div class="tipster"><%= link_to_remote 'Refresh', :update => 'item-sidebar', :url => { :action => 'item_list_with_ajax', :page => @params['page'] } %> 
  · <%= pagination_links_with_ajax @item_pages, { :element_name => 'item-sidebar', :action =>  'item_list_with_ajax' } %></div>
<% else %>
   <div class="little-grey-text">no items</div>
<% end %>
</div>
</pre>

h2. The Helper

Aha! The final piece of the puzzle - it's like finding the holy grail to aid your dying father (who was shot in the stomach and perhaps the spine by a villainous antiquarian with dreams of glory and everlasting life):

<pre>
module AdminHelper

  # ripped straight out of docs, modified for ajax
  def pagination_links_with_ajax(paginator, options={})
   options.merge!(ActionView::Helpers::PaginationHelper::DEFAULT_OPTIONS) {|key, old, new| old}
 
   window_pages = paginator.current.window(options[:window_size]).pages

   return if window_pages.length <= 1 unless
     options[:link_to_current_page]
 
   first, last = paginator.first, paginator.last
 
   returning html = '' do
     if options[:always_show_anchors] and not window_pages[0].first?
       #html << link_to(first.number, options[:name] => first)
       html << link_to_remote(first.number, :update => options[:element_name], :url => { :action => options[:action], :page => first })
       html << ' ... ' if window_pages[0].number - first.number > 1
       html << ' '
     end
   
     window_pages.each do |page|
       if paginator.current == page && !options[:link_to_current_page]
         html << page.number.to_s
       else
         #html << link_to(page.number, options[:name] => page)
         html << link_to_remote(page.number, :update => options[:element_name], :url => { :action => options[:action], :page => page })
       end
       html << ' '
     end
   
     if options[:always_show_anchors] && !window_pages.last.last?
       html << ' ... ' if last.number - window_pages[-1].number > 1
       #html << link_to(paginator.last.number, options[:name] => last)
       html << link_to_remote(last.number, :update => options[:element_name], :url => { :action => options[:action], :page => last })
     end
   end
  end
  
end
</pre>

You can even see where I commented out the original @link_to@ method calls and snuck in @link_to_remote@. Aren't I devious? Almost like picking the wrong cup of a carpenter.

So, there you have it, folks, ajaxified lists for you heal the wounded web-paradigm with everlasting, asynchronous pagination!

But don't cross the seal.

--ScottMaclure
