如何在选项卡内的 Active Admin 显示页面上添加 sortable table?
How to add a sortable table on ActiveAdmin's show page inside a tab?
考虑以下场景:我在 ActiveAdmin
中有一个包含 index
和 show
页面的资源,而在显示页面上我有更多 Tabs
。
在其中一些(可能不止一个)Tabs
中,我想以表格形式显示与资源相关的信息,并带有可排序的列。
我还要求应用程序在更改表的排序顺序时保留在选定的 Tab
上。
如何在 ActiveAdmin
中实现这一点?
不幸的是,ActiveAdmin 似乎不支持这个开箱即用的功能,但它是可以实现的。
在 ActiveAdmin.register
调用中(通常在 lib/admin/resource.rb
中)这将为 resource
的 some_connection
数据创建一个 table:
tab "Tab 2" do
table_for resource.some_connection do
column :name
...
end
end
不幸的是,这不是排序table table,因此我们应该简单地添加以下选项哈希:
{:sortable => true, :class => 'index_table'}
像这样:
table_for resource.some_connection, {:sortable => true, :class => 'index_table'} do
好吧,这差不多行得通了。遗憾的是,选择排序列会将您带回到第一个 Tab
,但排序将存储在 URL 中(以 whatever/your/page/address/is?order=name_asc
格式)。
为了解决这个问题,我使用以下内容对 ActiveAdmin's
TableFor
class 进行了猴子修补(在我在项目结构中创建的新文件中,例如:ext/active_admin/views/table_for
):
module ActiveAdmin
module Views
class TableFor
def build(obj, *attrs)
options = attrs.extract_options!
@sortable = options.delete(:sortable)
@collection = obj.respond_to?(:each) && !obj.is_a?(Hash) ? obj : [obj]
@resource_class = options.delete(:i18n)
@resource_class ||= @collection.klass if @collection.respond_to? :klass
@columns = []
@row_class = options.delete(:row_class)
@anchor = options.delete(:anchor)
@sort_key_prefix = ''
@sort_key_prefix = @anchor.to_s + '_' unless @anchor.nil?
build_table
super(options)
columns(*attrs)
end
def build_table_header(col)
classes = Arbre::HTML::ClassList.new
sort_key = sortable? && col.sortable? && col.sort_key
params = request.query_parameters.except :page, :order, :commit, :format
classes << 'sortable' if sort_key
classes << "sorted-#{current_sort[1]}" if sort_key && current_sort[0] == @sort_key_prefix + sort_key
classes << col.html_class
if sort_key
th class: classes do
link_to col.pretty_title, params: params, order: "#{@sort_key_prefix}#{sort_key}_#{order_for_sort_key(@sort_key_prefix + sort_key)}", anchor: @anchor
end
else
th col.pretty_title, class: classes
end
end
end
end
end
基本上我在选项中添加了一个锚参数,使用它我们可以在选择排序条件后返回到 table 所在的选项卡。这些条件的名称以这个锚点作为前缀进行扩展,因此在不同的选项卡中使用相同名称的列不会弄乱不同 table 的排序。 (目前我使用锚作为前缀,但这可以更改为一个完全独立的选项参数,以在一个 Tab
中支持更多 table)
我使用初始化程序加载猴子补丁,它只需要包含上面代码的文件(在我的示例中为 ext/active_admin/views/table_for
):
monkey_patches.rb
-----------------
require 'ext/active_admin/views/table_for'
这些更改要求我们稍微修改构建 table 的方式(我们必须从 params
中检索排序设置并将其应用于我们的数据):
tab_name = "Tab 2"
tab tab_name do
tab_anchor = tab_name.parameterize('_')
data = resource.some_conection
unless params['order'].nil?
order = params['order'].to_s.sub(tab_anchor + '_', '').sub("_asc", " ASC").sub("_desc", " DESC")
data = data.order(order) unless order.nil?
end
table_for data, { anchor: tab_anchor, :sortable => true, :class => 'index_table'} do
column :name
...
end
end
这是结果(这里table实际上被放入了一个Panel
,而anchor
指向那个):
实际上,ActiveAdmin 支持这个。
要对 table 进行排序,请调用 order()
方法并传递列名和 desc/asc
,如:
table_for boat.bookings.order('created_at desc') do
column :name
column :created_at
end
感谢 Ryan Bates 的截屏视频:http://railscasts.com/episodes/284-active-admin?view=asciicast
考虑以下场景:我在 ActiveAdmin
中有一个包含 index
和 show
页面的资源,而在显示页面上我有更多 Tabs
。
在其中一些(可能不止一个)Tabs
中,我想以表格形式显示与资源相关的信息,并带有可排序的列。
我还要求应用程序在更改表的排序顺序时保留在选定的 Tab
上。
如何在 ActiveAdmin
中实现这一点?
不幸的是,ActiveAdmin 似乎不支持这个开箱即用的功能,但它是可以实现的。
在 ActiveAdmin.register
调用中(通常在 lib/admin/resource.rb
中)这将为 resource
的 some_connection
数据创建一个 table:
tab "Tab 2" do
table_for resource.some_connection do
column :name
...
end
end
不幸的是,这不是排序table table,因此我们应该简单地添加以下选项哈希:
{:sortable => true, :class => 'index_table'}
像这样:
table_for resource.some_connection, {:sortable => true, :class => 'index_table'} do
好吧,这差不多行得通了。遗憾的是,选择排序列会将您带回到第一个 Tab
,但排序将存储在 URL 中(以 whatever/your/page/address/is?order=name_asc
格式)。
为了解决这个问题,我使用以下内容对 ActiveAdmin's
TableFor
class 进行了猴子修补(在我在项目结构中创建的新文件中,例如:ext/active_admin/views/table_for
):
module ActiveAdmin
module Views
class TableFor
def build(obj, *attrs)
options = attrs.extract_options!
@sortable = options.delete(:sortable)
@collection = obj.respond_to?(:each) && !obj.is_a?(Hash) ? obj : [obj]
@resource_class = options.delete(:i18n)
@resource_class ||= @collection.klass if @collection.respond_to? :klass
@columns = []
@row_class = options.delete(:row_class)
@anchor = options.delete(:anchor)
@sort_key_prefix = ''
@sort_key_prefix = @anchor.to_s + '_' unless @anchor.nil?
build_table
super(options)
columns(*attrs)
end
def build_table_header(col)
classes = Arbre::HTML::ClassList.new
sort_key = sortable? && col.sortable? && col.sort_key
params = request.query_parameters.except :page, :order, :commit, :format
classes << 'sortable' if sort_key
classes << "sorted-#{current_sort[1]}" if sort_key && current_sort[0] == @sort_key_prefix + sort_key
classes << col.html_class
if sort_key
th class: classes do
link_to col.pretty_title, params: params, order: "#{@sort_key_prefix}#{sort_key}_#{order_for_sort_key(@sort_key_prefix + sort_key)}", anchor: @anchor
end
else
th col.pretty_title, class: classes
end
end
end
end
end
基本上我在选项中添加了一个锚参数,使用它我们可以在选择排序条件后返回到 table 所在的选项卡。这些条件的名称以这个锚点作为前缀进行扩展,因此在不同的选项卡中使用相同名称的列不会弄乱不同 table 的排序。 (目前我使用锚作为前缀,但这可以更改为一个完全独立的选项参数,以在一个 Tab
中支持更多 table)
我使用初始化程序加载猴子补丁,它只需要包含上面代码的文件(在我的示例中为 ext/active_admin/views/table_for
):
monkey_patches.rb
-----------------
require 'ext/active_admin/views/table_for'
这些更改要求我们稍微修改构建 table 的方式(我们必须从 params
中检索排序设置并将其应用于我们的数据):
tab_name = "Tab 2"
tab tab_name do
tab_anchor = tab_name.parameterize('_')
data = resource.some_conection
unless params['order'].nil?
order = params['order'].to_s.sub(tab_anchor + '_', '').sub("_asc", " ASC").sub("_desc", " DESC")
data = data.order(order) unless order.nil?
end
table_for data, { anchor: tab_anchor, :sortable => true, :class => 'index_table'} do
column :name
...
end
end
这是结果(这里table实际上被放入了一个Panel
,而anchor
指向那个):
实际上,ActiveAdmin 支持这个。
要对 table 进行排序,请调用 order()
方法并传递列名和 desc/asc
,如:
table_for boat.bookings.order('created_at desc') do
column :name
column :created_at
end
感谢 Ryan Bates 的截屏视频:http://railscasts.com/episodes/284-active-admin?view=asciicast