Class: Katalyst::TableComponent

Inherits:
ViewComponent::Base
  • Object
show all
Includes:
HtmlAttributes, Katalyst::Tables::HasTableContent
Defined in:
app/components/katalyst/table_component.rb

Overview

A component for rendering a table from a collection, with a header row. “‘erb <%= Katalyst::TableComponent.new(collection: @people) do |row, person| %>

<%= row.text :name do |cell| %>
  <%= link_to cell.value, person %>
<% end %>
<%= row.text :email %>

<% end %> “‘

Direct Known Subclasses

SummaryTableComponent

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Katalyst::Tables::HasTableContent

#model_name

Constructor Details

#initialize(collection:, header: true, caption: true, generate_ids: false, object_name: nil, partial: nil, as: nil) ⇒ TableComponent

Construct a new table component. This entry point supports a large number of options for customizing the table. The most common options are: If no block is provided when the table is rendered then the table will look for a row partial: In addition to these options, standard HTML attributes can be passed which will be added to the table tag.

Parameters:

  • collection (Katalyst::Tables::Collection::Core)

    the collection to render

  • header (Boolean) (defaults to: true)

    whether to render the header row (defaults to true, supports options)

  • caption (Boolean, Hash) (defaults to: true)

    whether to render the caption (defaults to true, supports options)

  • generate_ids (Boolean) (defaults to: false)

    whether to generate dom ids for the table and rows

  • object_name (Symbol) (defaults to: nil)

    the name of the object to use for partial rendering (defaults to collection.model_name.i18n_key)

  • partial (String) (defaults to: nil)

    the name of the partial to use for rendering each row (defaults to to_partial_path on the object)

  • as (Symbol) (defaults to: nil)

    the name of the local variable to use for rendering each row (defaults to collection.model_name.param_key)



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'app/components/katalyst/table_component.rb', line 48

def initialize(collection:,
               header: true,
               caption: true,
               generate_ids: false,
               object_name: nil,
               partial: nil,
               as: nil,
               **)
  @collection = normalize_collection(collection)

  # header: true means render the header row, header: false means no header row, if a hash, passes as options
  @header_options = header

  # caption: true means render the caption, caption: false means no caption, if a hash, passes as options
  @caption_options = caption

  @header_row_callbacks = []
  @body_row_callbacks = []
  @header_row_cell_callbacks = []
  @body_row_cell_callbacks = []

  super(generate_ids:, object_name:, partial:, as:, **)
end

Instance Attribute Details

#collectionObject (readonly)

Returns the value of attribute collection.



23
24
25
# File 'app/components/katalyst/table_component.rb', line 23

def collection
  @collection
end

#object_nameObject (readonly)

Returns the value of attribute object_name.



23
24
25
# File 'app/components/katalyst/table_component.rb', line 23

def object_name
  @object_name
end

Instance Method Details

#before_renderObject



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/components/katalyst/table_component.rb', line 72

def before_render
  super

  if @caption_options
    options = (@caption_options.is_a?(Hash) ? @caption_options : {})
    with_caption(self, **options)
  end

  if @header_options
    options = @header_options.is_a?(Hash) ? @header_options : {}
    with_header_row(**options) do |row|
      @header_row_callbacks.each { |callback| callback.call(row, record) }
      row_content(row, nil)
    end
  end

  collection.each do |record|
    with_body_row do |row|
      @body_row_callbacks.each { |callback| callback.call(row, record) }
      row_content(row, record)
    end
  end
end

#boolean(column, label: nil, heading: false) {|cell| ... } ⇒ void

This method returns an undefined value.

Generates a column from boolean values rendered as “Yes” or “No”.

If a block is provided, it will be called with the boolean cell component as an argument.

Examples:

Render a boolean column indicating whether the record is active

<% row.boolean :active %> # => <td>Yes</td>

Parameters:

  • column (Symbol)

    the column’s name, called as a method on the record

  • label (String|nil) (defaults to: nil)

    the label to use for the column header

  • heading (boolean) (defaults to: false)

    if true, data cells will use ‘th` tags

  • ** (Hash)

    HTML attributes to be added to column cells

  • & (Proc)

    optional block to alter the cell content

Yield Parameters:



159
160
161
162
163
# File 'app/components/katalyst/table_component.rb', line 159

def boolean(column, label: nil, heading: false, **, &)
  with_cell(Tables::Cells::BooleanComponent.new(
              collection:, row:, column:, record:, label:, heading:, **,
            ), &)
end

#currency(column, label: nil, heading: false, options: {}) {|cell| ... } ⇒ void

This method returns an undefined value.

Generates a column from numeric values rendered using ‘number_to_currency`.

If a block is provided, it will be called with the currency cell component as an argument.

Examples:

Render a currency column for the price of a product

<% row.currency :price %> # => <td>$3.50</td>

Parameters:

  • column (Symbol)

    the column’s name, called as a method on the record

  • label (String|nil) (defaults to: nil)

    the label to use for the column header

  • heading (boolean) (defaults to: false)

    if true, data cells will use ‘th` tags

  • options (Hash) (defaults to: {})

    options to be passed to ‘number_to_currency`

  • ** (Hash)

    HTML attributes to be added to column cells

  • & (Proc)

    optional block to alter the cell content

Yield Parameters:



288
289
290
291
292
# File 'app/components/katalyst/table_component.rb', line 288

def currency(column, label: nil, heading: false, options: {}, **, &)
  with_cell(Tables::Cells::CurrencyComponent.new(
              collection:, row:, column:, record:, label:, heading:, options:, **,
            ), &)
end

#date(column, label: nil, heading: false, format: Tables.config.date_format, relative: true) {|cell| ... } ⇒ void

This method returns an undefined value.

Generates a column from date values rendered using I18n.l. The default format is :default, can be configured or overridden.

If a block is provided, it will be called with the date cell component as an argument.

Examples:

Render a date column describing when the record was created

<% row.date :created_at %> # => <td>29 Feb 2024</td>

Parameters:

  • column (Symbol)

    the column’s name, called as a method on the record

  • label (String|nil) (defaults to: nil)

    the label to use for the column header

  • heading (boolean) (defaults to: false)

    if true, data cells will use ‘th` tags

  • format (Symbol) (defaults to: Tables.config.date_format)

    the I18n date format to use when rendering

  • relative (Boolean) (defaults to: true)

    if true, the date may be shown as a relative date (if within 5 days)

  • ** (Hash)

    HTML attributes to be added to column cells

Yield Parameters:



182
183
184
185
186
# File 'app/components/katalyst/table_component.rb', line 182

def date(column, label: nil, heading: false, format: Tables.config.date_format, relative: true, **, &)
  with_cell(Tables::Cells::DateComponent.new(
              collection:, row:, column:, record:, label:, heading:, format:, relative:, **,
            ), &)
end

#datetime(column, label: nil, heading: false, format: Tables.config.datetime_format, relative: true) {|cell| ... } ⇒ void

This method returns an undefined value.

Generates a column from datetime values rendered using I18n.l. The default format is :default, can be configured or overridden.

If a block is provided, it will be called with the date time cell component as an argument.

Examples:

Render a datetime column describing when the record was created

<% row.datetime :created_at %> # => <td>29 Feb 2024, 5:00pm</td>

Parameters:

  • column (Symbol)

    the column’s name, called as a method on the record

  • label (String|nil) (defaults to: nil)

    the label to use for the column header

  • heading (boolean) (defaults to: false)

    if true, data cells will use ‘th` tags

  • format (Symbol) (defaults to: Tables.config.datetime_format)

    the I18n datetime format to use when rendering

  • relative (Boolean) (defaults to: true)

    if true, the datetime may be(if today) shown as a relative date/time

  • ** (Hash)

    HTML attributes to be added to column cells

  • & (Proc)

    optional block to alter the cell content

Yield Parameters:



206
207
208
209
210
# File 'app/components/katalyst/table_component.rb', line 206

def datetime(column, label: nil, heading: false, format: Tables.config.datetime_format, relative: true, **, &)
  with_cell(Tables::Cells::DateTimeComponent.new(
              collection:, row:, column:, record:, label:, heading:, format:, relative:, **,
            ), &)
end

#enum(column, label: nil, heading: false) {|cell| ... } ⇒ void

This method returns an undefined value.

Generates a column from an enum value rendered as a tag. The target attribute must be defined as an ‘enum` in the model.

When rendering an enum value, the component will check for translations using the key ‘active_record.attributes./[column].`, e.g. `active_record.attributes.banner/status.published`.

If a block is provided, it will be called with the cell component as an argument.

Examples:

Render a generic text column for any value that supports ‘to_s`

<% row.enum :status %>
<%# label => <th>Status</th> %>
<%# data => <td class="type-enum"><span data-enum="status" data-value="published">Published</span></td> %>

Parameters:

  • column (Symbol)

    the column’s name, called as a method on the record.

  • label (String|nil) (defaults to: nil)

    the label to use for the column header

  • heading (boolean) (defaults to: false)

    if true, data cells will use ‘th` tags

  • ** (Hash)

    HTML attributes to be added to column cells

  • & (Proc)

    optional block to wrap the cell content

Yield Parameters:



234
235
236
237
238
# File 'app/components/katalyst/table_component.rb', line 234

def enum(column, label: nil, heading: false, **, &)
  with_cell(Tables::Cells::EnumComponent.new(
              collection:, row:, column:, record:, label:, heading:, **,
            ), &)
end

#html_attributes=(attributes) ⇒ Object

When rendering a row we pass the table to the row instead of the row itself. This lets the table define the column entry points so it’s easy to define column extensions in subclasses. When a user wants to set html attributes on the row, they will call ‘row.html_attributes = { … }`, so we need to proxy that call to the current row (if set).



114
115
116
117
118
119
120
# File 'app/components/katalyst/table_component.rb', line 114

def html_attributes=(attributes)
  if row.present?
    row.html_attributes = attributes
  else
    @html_attributes = HtmlAttributes.options_to_html_attributes(attributes)
  end
end

#inspectObject



96
97
98
# File 'app/components/katalyst/table_component.rb', line 96

def inspect
  "#<#{self.class.name} collection: #{collection.inspect}>"
end

#number(column, label: nil, heading: false, format: :delimited, options: {}) {|cell| ... } ⇒ void

This method returns an undefined value.

Generates a column from numeric values formatted appropriately.

Supports Rails’ built in number formatters, i.e.

* +phone+: ActiveSupport::NumberHelper#number_to_phone
* +currency+: ActiveSupport::NumberHelper#number_to_currency
* +percentage+: ActiveSupport::NumberHelper#number_to_percentage
* +delimited+: ActiveSupport::NumberHelper#number_to_delimited
* +rounded+: ActiveSupport::NumberHelper#number_to_rounded
* +human_size+: ActiveSupport::NumberHelper#number_to_human_size
* +human+: ActiveSupport::NumberHelper#number_to_human

If a block is provided, it will be called with the number cell component as an argument.

Examples:

Render the number of comments on a post

<% row.number :comment_count %> # => <td>0</td>

Parameters:

  • column (Symbol)

    the column’s name, called as a method on the record

  • label (String|nil) (defaults to: nil)

    the label to use for the column header

  • heading (boolean) (defaults to: false)

    if true, data cells will use ‘th` tags

  • format (String|Symbol) (defaults to: :delimited)

    Rails number_to_X format option, defaults to delimited

  • options (Hash) (defaults to: {})

    options to be passed to ‘number_to_<format>`

  • ** (Hash)

    HTML attributes to be added to column cells

  • & (Proc)

    optional block to alter the cell content

Yield Parameters:



266
267
268
269
270
# File 'app/components/katalyst/table_component.rb', line 266

def number(column, label: nil, heading: false, format: :delimited, options: {}, **, &)
  with_cell(Tables::Cells::NumberComponent.new(
              collection:, row:, column:, record:, label:, heading:, format:, options:, **,
            ), &)
end

#recordObject



106
107
108
# File 'app/components/katalyst/table_component.rb', line 106

def record
  @current_record
end

#rich_text(column, label: nil, heading: false, options: {}) {|cell| ... } ⇒ void

Note:

This method assumes that the method returns HTML-safe content. If the content is not HTML-safe, it will be escaped.

This method returns an undefined value.

Generates a column containing HTML markup.

If a block is provided, it will be called with the rich text cell component as an argument.

Examples:

Render a description column containing HTML markup

<% row.rich_text :description %> # => <td><em>Emphasis</em></td>

Parameters:

  • column (Symbol)

    the column’s name, called as a method on the record

  • label (String|nil) (defaults to: nil)

    the label to use for the column header

  • heading (boolean) (defaults to: false)

    if true, data cells will use ‘th` tags

  • ** (Hash)

    HTML attributes to be added to column cells

  • & (Proc)

    optional block to alter the cell content

Yield Parameters:



312
313
314
315
316
# File 'app/components/katalyst/table_component.rb', line 312

def rich_text(column, label: nil, heading: false, options: {}, **, &)
  with_cell(Tables::Cells::RichTextComponent.new(
              collection:, row:, column:, record:, label:, heading:, options:, **,
            ), &)
end

#rowObject



102
103
104
# File 'app/components/katalyst/table_component.rb', line 102

def row
  @current_row
end

#text(column, label: nil, heading: false) {|cell| ... } ⇒ void Also known as: cell

This method returns an undefined value.

Generates a column from values rendered as text.

If a block is provided, it will be called with the cell component as an argument.

Examples:

Render a generic text column for any value that supports ‘to_s`

<% row.text :name %> # label => <th>Name</th>, data => <td>John Doe</td>

Parameters:

  • column (Symbol)

    the column’s name, called as a method on the record

  • label (String|nil) (defaults to: nil)

    the label to use for the column header

  • heading (boolean) (defaults to: false)

    if true, data cells will use ‘th` tags

  • ** (Hash)

    HTML attributes to be added to column cells

  • & (Proc)

    optional block to wrap the cell content

Yield Parameters:



137
138
139
140
141
# File 'app/components/katalyst/table_component.rb', line 137

def text(column, label: nil, heading: false, **, &)
  with_cell(Tables::CellComponent.new(
              collection:, row:, column:, record:, label:, heading:, **,
            ), &)
end