Last active
August 29, 2015 14:15
-
-
Save Fivell/d45653841cee22a890f5 to your computer and use it in GitHub Desktop.
AA tfoot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module ActiveAdmin | |
| module Views | |
| class IndexAsTable < ActiveAdmin::Component | |
| def build(page_presenter, collection) | |
| table_options = { | |
| id: "index_table_#{active_admin_config.resource_name.plural}", | |
| sortable: true, | |
| class: "index_table index", | |
| i18n: active_admin_config.resource_class, | |
| paginator: page_presenter[:paginator] != false, | |
| row_class: page_presenter[:row_class], | |
| has_footer: page_presenter[:has_footer] | |
| } | |
| table_for collection, table_options do |t| | |
| table_config_block = page_presenter.block || default_table | |
| instance_exec(t, &table_config_block) | |
| end | |
| end | |
| end | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| @has_footer = options.delete(:has_footer) | |
| @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 | |
| # Build our footer item | |
| within @footer_row do | |
| build_table_footer(col) | |
| end if @has_footer | |
| # 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_foot if @has_footer | |
| build_table_body | |
| end | |
| def build_table_foot | |
| @tfoot = tfoot do | |
| @footer_row = tr | |
| end | |
| end | |
| def build_table_head | |
| @thead = thead do | |
| @header_row = tr | |
| end | |
| end | |
| def build_table_footer(col) | |
| td class: col.html_class do | |
| col.footer_proc(@collection) | |
| 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 | |
| def footer_proc(collection) | |
| if @options[:footer_proc].is_a?(Proc) | |
| instance_exec(collection, &@options[:footer_proc]) | |
| 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment