Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Issue #412 paginated collection scope #428

Merged
merged 4 commits into from

3 participants

@samvincent

Adding support for the following features. These were driven by the desire to display multiple paginated collections on one page in the show action. Targets Issue #412.

  • Fix scope issue with :collection method call for #paginated_entries_info
  • Add support for :param_name option
  • Add support for :download_links => false
samvincent added some commits
@samvincent samvincent Issue #412 - Fix scope issue with :collection for PaginatedCollection…
… component

When rendering a PaginatedCollection for an associated collection within the
show context (for example), the :collection method called was referring to the resource
rather than the passed in collection. Also raising error if collection has not been
scoped with Kaminari to help new users figure it out.
c6813b5
@samvincent samvincent Issue #412 - Added support for :param_name to PaginatedCollection
Setting :param_name allows you to put multiple paginated collections
on a single page. (eg. Show action)
1d3895a
@samvincent samvincent Issue #412 - Disable download links option for PaginatedCollection
When rendering a paginated collection on the show screen for example,
it does not make sense to include resource download links for the collection.
2043acb
@samvincent samvincent Issue #412 - Fix for broken cuke complaining of unsymbolized key 3027431
@gregbell gregbell merged commit 3027431 into activeadmin:master
@acurley

I cannot seem to get multiple paginated collections to work properly (i.e. paginate) on one show view. Could someone post an example of their show action that successfully renders multiple tables with pagination?

@samvincent

You'll want to set your param name if you're doing multiple paginated collections.

div :id => "items" do
  collection = resource.items.page(params[:item_page]).per(15)
  pagination_options = {:entry_name => Item.model_name.human, :param_name => :item_page, :download_links => false}
  paginated_collection(collection, pagination_options) do
    table_options = { :id => 'items-table', :sortable => true, :class => "index_table", :i18n => Item }
    table_for collection, table_options do
      column(:code)      { |resource| resource.item.code }
      column(:name)      { |resource| resource.item.name }
      column :created_at
    end
  end
end
@acurley

Thanks! That was very helpful! The only problem that remains is that the "Display Items" information at the top right of the table still defaults to 1-30 despite my use of .per(15). The pagination buttons on the bottom right still increment in groups of 15, but the numbers in the top right are not correct. For a class of objects that has 194 "items", the last page of paginated hits says "Displaying Items 361 - 194 of 194 in total". I'm guessing that .per(15) in this instance does not override system defaults.

@samvincent

That stuff has to do with Kaminari. You may want to take a look there and inspect your collection. I've been getting the expected results for my paginated collections so far.

@acurley

It looks like it is actually a default behavior in lib/active_admin/views/components/paginated_collection.rb. I don't see how my .per method overwrites the active_admin_application.default_per_page.

def page_entries_info(options = {})
  if collection.num_pages < 2
    ....
  else
    offset = collection.current_page * active_admin_application.default_per_page
    total  = collection.total_count
    I18n.t('active_admin.pagination.multiple', :model => entry_name.pluralize, :from => (offset - active_admin_application.default_per_page + 1), :to => offset > total ? total : offset, :total => total)
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 26, 2011
  1. @samvincent

    Issue #412 - Fix scope issue with :collection for PaginatedCollection…

    samvincent authored
    … component
    
    When rendering a PaginatedCollection for an associated collection within the
    show context (for example), the :collection method called was referring to the resource
    rather than the passed in collection. Also raising error if collection has not been
    scoped with Kaminari to help new users figure it out.
Commits on Aug 29, 2011
  1. @samvincent

    Issue #412 - Added support for :param_name to PaginatedCollection

    samvincent authored
    Setting :param_name allows you to put multiple paginated collections
    on a single page. (eg. Show action)
  2. @samvincent

    Issue #412 - Disable download links option for PaginatedCollection

    samvincent authored
    When rendering a paginated collection on the show screen for example,
    it does not make sense to include resource download links for the collection.
Commits on Aug 30, 2011
  1. @samvincent
This page is out of date. Refresh to see the latest.
View
19 lib/active_admin/views/components/paginated_collection.rb
@@ -23,6 +23,7 @@ module Views
class PaginatedCollection < ActiveAdmin::Component
builder_method :paginated_collection
+ attr_reader :collection
# Builds a new paginated collection component
#
@@ -30,9 +31,18 @@ class PaginatedCollection < ActiveAdmin::Component
# @param [Hash] options These options will be passed on to the page_entries_info
# method.
# Useful keys:
- # :entry_name - The name to display for this resource collection
+ # :entry_name - The name to display for this resource collection
+ # :param_name - Parameter name for page number in the links (:page by default)
+ # :download_links - Set to false to skip download format links
def build(collection, options = {})
@collection = collection
+ @param_name = options.delete(:param_name)
+ @download_links = options.delete(:download_links)
+
+ unless collection.respond_to?(:num_pages)
+ raise(StandardError, "Collection is not a paginated scope. Set collection.page(params[:page]).per(10) before calling :paginated_collection.")
+ end
+
div(page_entries_info(options).html_safe, :class => "pagination_information")
@contents = div(:class => "paginated_collection_contents")
build_pagination_with_formats
@@ -52,13 +62,16 @@ def add_child(*args, &block)
def build_pagination_with_formats
div :id => "index_footer" do
- build_download_format_links
+ build_download_format_links unless @download_links == false
build_pagination
end
end
def build_pagination
- text_node paginate(collection)
+ options = request.query_parameters.except(:commit, :format)
+ options[:param_name] = @param_name if @param_name
+
+ text_node paginate(collection, options.symbolize_keys)
end
# TODO: Refactor to new HTML DSL
View
59 spec/unit/views/components/paginated_collection_spec.rb
@@ -0,0 +1,59 @@
+require 'spec_helper'
+
+describe ActiveAdmin::Views::PaginatedCollection do
+ describe "creating with the dsl" do
+ setup_arbre_context!
+
+ let(:collection) do
+ posts = [Post.new(:title => "First Post"), Post.new(:title => "Second Post"), Post.new(:title => "Third Post")]
+ Kaminari.paginate_array(posts).page(1).per(5)
+ end
+
+ before do
+ request.stub!(:query_parameters).and_return({:controller => 'admin/posts', :action => 'index', :page => '1'})
+ controller.params = {:controller => 'admin/posts', :action => 'index'}
+ end
+
+ context "when specifying collection" do
+ let(:pagination) do
+ paginated_collection(collection)
+ end
+
+ it "should set :collection as the passed in collection" do
+ pagination.find_by_tag('div').first.content.should == "Displaying <b>all 3</b> posts"
+ end
+
+ it "should raise error if collection has no pagination scope" do
+ lambda {
+ paginated_collection([Post.new, Post.new])
+ }.should raise_error(StandardError, "Collection is not a paginated scope. Set collection.page(params[:page]).per(10) before calling :paginated_collection.")
+ end
+ end
+
+ context "when specifying :param_name option" do
+ let(:collection) do
+ posts = 10.times.inject([]) {|m| m << Post.new }
+ Kaminari.paginate_array(posts).page(1).per(5)
+ end
+
+ let(:pagination) { paginated_collection(collection, :param_name => :post_page) }
+
+ it "should customize the page number parameter in pagination links" do
+ pagination.find_by_tag('div').last.content.should match(/\/admin\/posts\?post_page=2/)
+ end
+ end
+
+ context "when specifying :download_links => false option" do
+ let(:collection) do
+ posts = 10.times.inject([]) {|m| m << Post.new }
+ Kaminari.paginate_array(posts).page(1).per(5)
+ end
+
+ let(:pagination) { paginated_collection(collection, :download_links => false) }
+
+ it "should not render download links" do
+ pagination.find_by_tag('div').last.content.should_not match(/Download:/)
+ end
+ end
+ end
+end
Something went wrong with that request. Please try again.