ComfyCoders TranquilTools
Docs /Laravel Vue TableBuilder
Repository
v1

Columns

Columns define what data is displayed and how each column behaves.

Basic Usage

$table->column('name', 'Name');

Signature

column(
    ?string $key = null,
    ?string $label = null,
    ?bool $canBeHidden = null,
    bool $hidden = false,
    bool|Closure $sortable = false,
    bool|string $searchable = false,
    ?bool $highlight = null,
    array|string|null $classes = null,
    ?callable $as = null,
    string $alignment = 'left',
    bool $clickable = true,
): self

Parameters

Parameter Type Default Description
key string|null auto from label Column key matching the data field name
label string|null auto from key Column header label
canBeHidden bool|null global default (true) Whether the user can toggle this column's visibility
hidden bool false Hidden by default
sortable bool|Closure false Enable sorting; pass a closure for custom sort logic
searchable bool|string false Add a search input for this column
highlight bool|null true for first column if global default enabled Visually highlight the cell
classes array|string|null null CSS classes for this column's cells
as callable|null null Transform the cell value before display
alignment string 'left' Text alignment: 'left', 'center', 'right'
clickable bool true Whether clicking this cell follows the row link

Auto-labeling

If label is omitted, it is generated from key using Str::headline():

->column('created_at') // label: "Created At"
->column('company.name') // label: "Company Name"

If key is omitted, it is generated from label using Str::kebab():

->column(label: 'Full Name') // key: "full-name"

Nested Relationships

Use dot notation to access relationship data:

->column('company.name', 'Company')
->column('company.address.city', 'City')

When used with QueryBuilder, relationships are eager-loaded automatically. Sorting on nested columns requires the kirschbaum-development/eloquent-power-joins package.

Transforming Values

Use as to transform a value before it reaches the frontend:

->column('status', 'Status', as: fn($value) => ucfirst($value))
->column('price', 'Price', as: fn($value, $item) => '$' . number_format($value, 2))

The second argument to the closure is the full row item.

Plain text vs. HTML output

By default, string values returned from an as callback are escaped as plain text. This prevents XSS when displaying user-controlled data.

To render raw HTML, return an HtmlString instance:

use Illuminate\Support\HtmlString;

->column('ticket', 'Ticket', as: fn($ticket) => $ticket
    ? new HtmlString('<a href="' . route('tickets.show', $ticket) . '">' . e($ticket->title) . '</a>')
    : '-'
)

Note: Always escape user-controlled values inside HtmlString using e(). The HtmlString wrapper signals intent, it does not escape for you.

Custom Sort Logic

Pass a closure to sortable to implement custom ordering:

->column('full_name', 'Name', sortable: function ($query, string $direction) {
    $query->orderBy('last_name', $direction)->orderBy('first_name', $direction);
})

Column Visibility

Columns with canBeHidden: true (the default) appear in a visibility dropdown. Users can show/hide them - the selection is persisted in the URL via the columns[] query parameter.

Prevent a column from being hidden:

->column('id', 'ID', canBeHidden: false)

Hide a column by default (user can reveal it):

->column('notes', 'Notes', hidden: true)

CSS Classes

Apply Tailwind or custom classes to a column's cells:

->column('id', 'ID', classes: 'w-16 text-muted-foreground')

For global cell/header classes across all columns, use class():

$table->class(cell: 'py-2', head: 'bg-muted');

Alignment

->column('amount', 'Amount', alignment: 'right')
->column('status', 'Status', alignment: 'center')

Non-clickable Cells

By default, clicking a cell follows the row link. Disable this for action columns:

->column('actions', 'Actions', clickable: false, canBeHidden: false)

Searchable Shorthand

Setting searchable: true automatically registers a search input for that column:

->column('name', 'Name', searchable: true)
// Equivalent to:
->column('name', 'Name')
->searchInput('name', 'Name')

Global Column Defaults

Configure defaults in a service provider:

// All columns hidden by default (user must opt-in)
TableBuilder::defaultColumnCanBeHidden(true);

// Highlight the first column in every table
TableBuilder::defaultHighlightFirstColumn(true);