Relationships, custom formatters, status badges, and action buttons.
Filters
Drag to reorder, pin columns, and show/hide:
Table definition
app/infotable/orders_table.rb
class OrdersTable < Infotable::Base
query do
Order.includes(:user)
end
column :order_number,
label: "Order #",
type: :string,
width: "140px",
sortable: true,
filterable: true,
filter_type: :text,
visible: true,
formatter: ->(value, record) {
"<code class='px-2 py-1 font-mono text-sm bg-gray-100 rounded'>#{value}</code>".html_safe
}
column :user,
label: "Customer",
type: :string,
width: "200px",
sortable: true,
filterable: true,
filter_type: :text,
visible: true,
formatter: ->(value, record) { record.user&.name || "-" }
column :status,
label: "Status",
type: :badge,
width: "110px",
sortable: true,
filterable: true,
filter_type: :select,
filter_options: [ "pending", "processing", "shipped", "delivered", "cancelled" ],
visible: true,
formatter: {
type: :badge,
options: {
colors: {
"pending" => "yellow",
"processing" => "blue",
"shipped" => "cyan",
"delivered" => "green",
"cancelled" => "red"
}
}
}
column :total,
label: "Total",
type: :decimal,
sortable: true,
filterable: true,
filter_type: :number,
visible: true,
formatter: :currency,
formatter_options: { precision: 2 }
column :order_date,
label: "Order Date",
type: :datetime,
sortable: true,
filterable: true,
filter_type: :date,
visible: true,
formatter: :date,
formatter_options: { format: :short }
column :actions,
label: "Actions",
width: "150px",
type: :action,
visible: true,
formatter: :action,
formatter_options: {
actions: [
{
label: "View",
url: ->(record) { "/orders/#{record.id}" },
color: "primary"
},
{
label: "Invoice",
url: ->(record) { "/orders/#{record.id}/invoice" },
color: "secondary"
}
]
}
per_page 25
per_page_options [ 10, 25, 50, 100 ]
default_sort :order_date, :desc
table_min_height "500px"
table_max_height "700px"
end