Beartropy Tables

Column Data & Search
Transform cell values, render custom views, and configure per-column sorting and searching.

Custom Data

Transform cell values using closures.

Closure Transformation

customData(Closure $function) — Transform cell content with a closure that receives $row and $value.

1Column::make('Upper Name','name')
2 ->customData(function($row, $value){
3 return strtoupper($value);
4 })
5 
6Column::make('Full Name')
7 ->customData(function($row, $value){
8 return $row['firstname'] . " " . $row['lastname'];
9 })
10 
11Column::make('Big Name','name')
12 ->customData(function($row, $value){
13 return '<div class="text-3xl">'.$value.'</div>';
14 })->toHtml()

HTML output requires toHtml()

When returning HTML from customData(), you must chain ->toHtml() to prevent the output from being escaped.

Custom Blade View

Render a custom Blade view for the cell content.

Custom View

view(string $view) — Render a custom Blade view for the cell content. The view receives $row, $value, and $column variables.

1Column::make('Status','status')
2 ->view('components.columns.status-pill')

Sorting & Searching

Enable per-column sorting and searching, with support for custom logic.

Basic Sorting & Searching

sortable(bool|Closure $callback = true) — Enable sorting for the column (default: false).

searchable(bool|Closure $callback = true) — Enable global search inclusion (default: true).

1Column::make('Name', 'name')
2 ->sortable() // Enable sorting
3 ->searchable() // Enable searching
4 
5Column::make('Sensitive Data', 'field')
6 ->sortable(false)
7 ->searchable(false) // Disable searching

Sort by Different Column

sortColumnBy(string $column_key) — Override which column is used for sorting when this header is clicked. Useful for computed columns that should sort by a database field.

1Column::make('Full Name')
2 ->sortColumnBy('lastname')

Custom Sort & Search Logic

Pass closures to sortable() and searchable() for full control over query behavior. This is essential for computed columns or relationship data.

1Column::make('Theme', 'theme_setting')
2 ->sortable(function($query, $direction) {
3 $query->orderBy(
4 UserSetting::select('value')
5 ->whereColumn('user_settings.user_id', 'users.id')
6 ->where('key', 'theme'),
7 $direction
8 );
9 })
10 ->searchable(function($query, $term) {
11 $query->orWhereHas('settings', function($q) use ($term) {
12 $q->where('key', 'theme')->where('value', 'like', "%$term%");
13 });
14 });

Custom closures for Eloquent mode

Custom sort/search closures are most useful in Eloquent mode ($model property). They give you direct access to the query builder for subqueries, joins, and relationship queries.

Secondary Header (Aggregation Row)

Display computed values like totals, averages, or counts in a secondary row below the main header.

secondaryHeader()

secondaryHeader(callable $callback) — Add a secondary header row with computed content. The callback receives the current page's rows as a Collection and should return the content to display. Output supports HTML (rendered unescaped).

The secondary header row only appears when at least one column defines it. Columns without a callback render an empty cell in that row.

1Column::make('Quantity', 'qty')
2 ->centered()
3 ->secondaryHeader(fn($rows) => 'Total: ' . $rows->sum('qty')),
4 
5Column::make('Unit Price', 'unit_price')
6 ->pushRight()
7 ->secondaryHeader(fn($rows) => 'Avg: $' . number_format($rows->avg('unit_price'), 2)),
8 
9Column::make('Total', 'total')
10 ->pushRight()
11 ->styling('font-bold')
12 ->secondaryHeader(fn($rows) => '<strong>$' . number_format($rows->sum('total'), 2) . '</strong>'),

Page-scoped aggregation

The callback receives only the current page's rows, not the entire dataset. For full-dataset aggregations, compute the values in your table component's settings() method and pass them to the callback via a property.
Beartropy Logo

© 2026 Beartropy. All rights reserved.

Provided as-is, without warranty. Use at your own risk.