lib/active_admin/views/components/table_for.rb in activeadmin-0.6.6 vs lib/active_admin/views/components/table_for.rb in activeadmin-1.0.0.pre1
- old
+ new
@@ -5,19 +5,27 @@
def tag_name
'table'
end
- def build(collection, options = {})
- @sortable = options.delete(:sortable)
+ def build(obj, *attrs)
+ options = attrs.extract_options!
+ @sortable = options.delete(:sortable)
@resource_class = options.delete(:i18n)
- @collection = collection
- @columns = []
+ @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]
@@ -30,24 +38,19 @@
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)
+ build_table_cell col, item
end
end
end
def sortable?
- @sortable
+ !!@sortable
end
- # Returns the columns to display based on the conditional block
- def visible_columns
- @visible_columns ||= @columns.select{|col| col.display_column? }
- end
-
protected
def build_table
build_table_head
build_table_body
@@ -58,51 +61,81 @@
@header_row = tr
end
end
def build_table_header(col)
- classes = Arbre::HTML::ClassList.new
+ 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.merge(:order => "#{sort_key}_#{order_for_sort_key(sort_key)}").except(:page))
+ 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)
+ th col.pretty_title, class: classes
end
end
def build_table_body
@tbody = tbody do
# Build enough rows for our collection
- @collection.each{|elem| tr(:class => cycle('odd', 'even'), :id => dom_id(elem)) }
+ @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
- rvalue = call_method_or_proc_on(item, col.data, :exec => false)
- if col.data.is_a?(Symbol)
- rvalue = pretty_format(rvalue)
- end
- rvalue
+ 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 ||= if params[:order] && params[:order] =~ /^([\w\_\.]+)_(desc|asc)$/
- [$1,$2]
- else
- []
+ @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
#
@@ -114,37 +147,41 @@
current_order == 'desc' ? 'asc' : 'desc'
end
def default_options
{
- :i18n => @resource_class
+ i18n: @resource_class
}
end
class Column
attr_accessor :title, :data , :html_class
- def initialize(*args, &block)
+ def initialize(*args, &block)
@options = args.extract_options!
@title = args[0]
- @html_class = @options.delete(:class) || @title.to_s.downcase.underscore.gsub(/ +/,'_')
- @data = args[1] || 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 @data.is_a?(Proc)
- [String, Symbol].include?(@options[:sortable].class)
- elsif @options.has_key?(:sortable)
- @options[:sortable]
- elsif @data.respond_to?(:to_sym) && @resource_class
- !@resource_class.reflect_on_association(@data.to_sym)
+ if @options.has_key?(:sortable)
+ !!@options[:sortable]
+ elsif @resource_class
+ @resource_class.column_names.include?(sort_column_name)
else
- true
+ @title.present?
end
end
#
# Returns the key to be used for sorting this column
@@ -153,38 +190,46 @@
# 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'
+ # 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 }
+ # 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 || @options[:sortable].nil?
+ 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 = @title.to_s.titleize
- if @options[:i18n] && @options[:i18n].respond_to?(:human_attribute_name)
- @title = @options[:i18n].human_attribute_name(@title, :default => default_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_title
+ 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