Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-5 of 5 total  RSS 

PHP: Pagination

// Another example for creating pagination.
// Usage:
// print get_page_nav($page_current, $page_total);

	/**
	 * Creates links to pages.
	 * 
	 * @param	integer	$page_current The current page number.
	 * @param	integer	$page_total The total number of pages.
	 * @return 	string	HTML-code.
	 */
	function get_page_nav($page_current, $page_total)
	{
		$ar_pages = array();
		/* HTML-tag to select the current page */
		$str_tag = 'strong';
		/* Language strings */
		$str_page_prev = 'Предыдущая';
		$str_page_next = 'Следующая';
		/* String placed between the first and last page numbers */
		$str_more = '..';
		/* String to separate page numbers */
		$str_d = $this->sys['char_split_pages'];
		/* URL for paging */
		$str_url = 'index.php?book='.$this->gv['book'].'&page=%d';
		
		/* The number of links to pages displayed before and after the current page. 1 2 (3) 1 2 */
		$int_max = 2;
		$cnt_new = $page_current;
		$cnt_max = $page_current + $int_max;
		$cnt_min = $page_current - $int_max;
		/* Fix the maximum number of pages */
		if ($cnt_max > $page_total)
		{
			$cnt_max = $page_total;
		}
		/* First page */
		if ($cnt_min > 1)
		{
			$ar_pages[] = '<a href="'.sprintf($str_url, 1).'">1</a>';
			$ar_pages[] = $str_more;
		}
		/* For each page number */
		for ($i = 1; $i <= $page_total; $i++)
		{
			if ( ($i >= $cnt_min && $i <= $cnt_max) )
			{
				if ($i == $page_current)
				{
					$ar_pages[] = '<a href="'.sprintf($str_url, $i).'"><'.$str_tag.'>'.$i.'</'.$str_tag.'></a>';
				}
				else
				{
					$ar_pages[] = '<a href="'.sprintf($str_url, $i).'">'.$i.'</a>';
				}
			}
			$cnt_new++;
		}
		/* The last page */
		if ($cnt_max > 1 && ($page_current + $int_max) < $page_total)
		{
			$ar_pages[] = $str_more;
			$ar_pages[] = '<a href="'.sprintf($str_url, $page_total).'">'.$page_total.'</a>';
		}
		/* Links to Next/Prev pages */
		if ($page_current > 1)
		{
			$ar_pages[] = '<a href="'.sprintf($str_url, ($page_current - 1) ).'">'.$str_page_prev.'</a>';
		}
		if ($page_current < $page_total)
		{
			$ar_pages[] = '<a href="'.sprintf($str_url, ($page_current + 1) ).'">'.$str_page_next.'</a>';
		}
		return implode($str_d, $ar_pages);
	}

ActiveRecord each_by_page

Perform an operation on a set of models including ActiveRecord callbacks, without instantiating all models at once.

Step through and instantiate each member of the class and execute on it, but instantiate no more than per_page instances at any given time.
Safe for destructive actions or actions that modify the fields your :order or :conditions clauses operate on.

module ActiveRecord
  class Base
    def each_by_page per_page, options = {}, &block
      # By-id for model-modifying blocks
      # Build SQL to get ids of all matching records using the options provided by the user
      sql = construct_finder_sql(options.dup.merge({ :select => 'id' }))
      # Get the results as an array of tiny hashes { "id" => "1" } and flatten them out to just the ids
      all_ids = connection.select_all(sql).map { |h| h['id'] }
      at_a_time = 0..(per_page-1)
 
      # chop apart the all_ids array a segment at a time
      begin
        ids = all_ids.slice!(at_a_time)
        ids_cases = []
        ids.each_with_index { |id, i| ids_cases << "WHEN #{id} THEN #{i}" }
        ids_cases = ids_cases.join(' ')
 
        # Do the deed on this page of results
        find(:all, options.merge(
          :conditions => [ 'id IN (?)', ids ],
          :order => "CASE id #{ids_cases} END"
        )).each &block
 
      end until all_ids.empty?
    end
  end
end


link to blog entry

Paginate an already-fetched result set (i.e. collection or array)

Sometimes it's nearly impossible to paginate a result set using the built-in :limit and :offset parameters of find(:all). Instead, you can fetch a complicated query and paginate the results afterward.

Add the following to application.rb:

  def paginate_collection(collection, options = {})
    default_options = {:per_page => 10, :page => 1}
    options = default_options.merge options
    
    pages = Paginator.new self, collection.size, options[:per_page], options[:page]
    first = pages.current.offset
    last = [first + options[:per_page], collection.size].min
    slice = collection[first...last]
    return [pages, slice]
  end


Call it from within your action like this:
@pages, @users = paginate_collection User.find_custom_query, :page => @params[:page]

ajax_pagination_links

Put in a helper somewhere, and use like this:
<%= ajax_pagination_links @client_pages, {:update => 'search_results', :params => {:search_query => @params[:search_query]} } %>

and just update the div your results (and the above line) are in.
       def ajax_pagination_links(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_remote(first.number, :update => options[:update], :url => { options[:name] => first }.update(options[:params] ))
             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_remote(page.number, :update => options[:update], :url => { options[:name] => page }.update(options[:params] ))
             end
             html << ' '
           end
           
           if options[:always_show_anchors] && !window_pages.last.last?
             html << ' ... ' if last.number - window_pages[-1].number > 1
             html << link_to_remote(paginator.last.number, :update => options[:update], :url => { options[:name] => last }.update( options[:params]))
           end
         end
       end

paginate on custom sql queries in rails

Someone in #rubyonrails wrote this. Forget who!

def paginate_from_sql(model, sql, total, per_page)
  @object_pages = Paginator.new self, total, per_page, @params['page']
  @objects = model.find_by_sql(sql + " LIMIT #{per_page} " +
                               "OFFSET #{@object_pages.current.to_sql[1]}")
end
« Newer Snippets
Older Snippets »
Showing 1-5 of 5 total  RSS