Repository URL to install this package:
|
Version:
1.0.0.pre ▾
|
module ActiveAdmin
module Views
class TableFor < Arbre::HTML::Table
builder_method :table_for
def tag_name
'table'
end
def build(obj, *attrs)
options = attrs.extract_options!
@sortable = options.delete(:sortable)
@resource_class = options.delete(:i18n)
@collection = obj.respond_to?(:each) && !obj.is_a?(Hash) ? obj : [obj]
@columns = []
@row_class = options.delete(:row_class)
build_table
super(options)
columns(*attrs)
end
def columns(*attrs)
attrs.each {|attr| column(attr) }
end
def column(*args, &block)
options = default_options.merge(args.extract_options!)
title = args[0]
data = args[1] || args[0]
col = Column.new(title, data, @resource_class, options, &block)
@columns << col
# Build our header item
within @header_row do
build_table_header(col)
end
# Add a table cell for each item
@collection.each_with_index do |item, i|
within @tbody.children[i] do
build_table_cell col, item
end
end
end
def sortable?
!!@sortable
end
protected
def build_table
build_table_head
build_table_body
end
def build_table_head
@thead = thead do
@header_row = tr
end
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
classes << col.html_class
if sort_key
th class: classes do
link_to col.pretty_title, params: params, order: "#{sort_key}_#{order_for_sort_key(sort_key)}"
end
else
th col.pretty_title, class: classes
end
end
def build_table_body
@tbody = tbody do
# Build enough rows for our collection
@collection.each do |elem|
classes = [cycle('odd', 'even')]
if @row_class
classes << @row_class.call(elem)
end
tr(class: classes.flatten.join(' '), id: dom_id_for(elem))
end
end
end
def build_table_cell(col, item)
td class: col.html_class do
render_data col.data, item
end
end
def render_data(data, item)
value = if data.is_a? Proc
data.call item
elsif item.respond_to? data
item.public_send data
elsif item.respond_to? :[]
item[data]
end
value = pretty_format(value) if data.is_a?(Symbol)
value = status_tag value if is_boolean? data, item
value
end
def is_boolean?(data, item)
if item.respond_to? :has_attribute?
item.has_attribute?(data) &&
item.column_for_attribute(data) &&
item.column_for_attribute(data).type == :boolean
end
end
# Returns an array for the current sort order
# current_sort[0] #=> sort_key
# current_sort[1] #=> asc | desc
def current_sort
@current_sort ||= begin
order_clause = OrderClause.new params[:order]
if order_clause.valid?
[order_clause.field, order_clause.order]
else
[]
end
end
end
# Returns the order to use for a given sort key
#
# Default is to use 'desc'. If the current sort key is
# 'desc' it will return 'asc'
def order_for_sort_key(sort_key)
current_key, current_order = current_sort
return 'desc' unless current_key == sort_key
current_order == 'desc' ? 'asc' : 'desc'
end
def default_options
{
i18n: @resource_class
}
end
class Column
attr_accessor :title, :data , :html_class
def initialize(*args, &block)
@options = args.extract_options!
@title = args[0]
html_classes = [:col]
if @options.has_key?(:class)
html_classes << @options.delete(:class)
elsif @title.present?
html_classes << "col-#{@title.to_s.parameterize('_')}"
end
@html_class = html_classes.join(' ')
@data = args[1] || args[0]
@data = block if block
@resource_class = args[2]
end
def sortable?
if @options.has_key?(:sortable)
!!@options[:sortable]
elsif @resource_class
@resource_class.column_names.include?(sort_column_name)
else
@title.present?
end
end
#
# Returns the key to be used for sorting this column
#
# Defaults to the column's method if its a symbol
# column :username
# # => Sort key will be set to 'username'
#
# You can set the sort key by passing a string or symbol
# to the sortable option:
# column :username, sortable: 'other_column_to_sort_on'
#
# If you pass a block to be rendered for this column, the column
# will not be sortable unless you pass a string to sortable to
# sort the column on:
#
# column('Username', sortable: 'login'){ @user.pretty_name }
# # => Sort key will be 'login'
#
def sort_key
# If boolean or nil, use the default sort key.
if @options[:sortable] == true || @options[:sortable] == false
@data.to_s
elsif @options[:sortable].nil?
sort_column_name
else
@options[:sortable].to_s
end
end
def pretty_title
if @title.is_a? Symbol
default = @title.to_s.titleize
if @options[:i18n].respond_to? :human_attribute_name
@title = @options[:i18n].human_attribute_name @title, default: default
else
default
end
else
@title
end
end
private
def sort_column_name
@data.is_a?(Symbol) ? @data.to_s : @title.to_s
end
end
end
end
end