Beartropy Tables
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()
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 sorting3 ->searchable() // Enable searching4 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
$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
settings() method and pass them to the callback via a property.