/

Custom Cell Rendering: Badges & Avatars

Rendering trusted HTML - colored status badges, avatar thumbnails - inside a grid cell with Xcrud::html(), plus simpler conditional cell/row styling with highlight().

Why column_callback() alone isn't enough

column_callback($field, $fn) lets you replace a cell's value with whatever your callback returns. By default that return is treated as plain text and escaped, exactly like any other value - so a plain string like '<span>Active</span>' would show up as literal angle brackets, not a styled element.

Wrap the callback's return in the static helper Xcrud::html($html, $text = null) when you need the cell to actually render markup instead:

public static function html(string $html, ?string $text = null): array
ParameterTypeDefaultDescription
$htmlstringrequiredThe trusted markup to render in the cell (rendered via innerHTML client-side)
$text?stringnullPlain-text fallback; if omitted, defaults to $html with tags stripped

$text is what actually round-trips as the column's value everywhere styled HTML wouldn't make sense - CSV/XLSX/PDF export, and grid search/sort - since those can't render a colored <span>.

Example: a status badge

A common pattern: color-code a status column with a column_callback() that returns a small pill via Xcrud::html():

$xcrud->column_callback('status', function ($value, $row) {
    $colors = [
        'active'   => '#16a34a',
        'pending'  => '#d97706',
        'canceled' => '#dc2626',
    ];
    $color = $colors[$value] ?? '#6b7280';

    $html = '<span style="background:' . $color . ';color:#fff;'
          . 'padding:2px 10px;border-radius:999px;font-size:12px;">'
          . htmlspecialchars(ucfirst($value)) . '</span>';

    return Xcrud::html($html, ucfirst($value));
});

The grid cell shows the colored pill; a CSV/XLSX/PDF export of the same column shows the plain word ("Active", "Pending", "Canceled") instead, and column search/sort still work against that same plain text.

The same approach works for an avatar - return an <img> tag (or an initials-in-a-circle <span>) wrapped in Xcrud::html(), with a plain name or initials as the $text fallback.

highlight() and highlight_row() - simpler conditional styling

When you just need a cell or row to change color based on a comparison - no custom markup required - highlight()/highlight_row() is simpler than a full callback:

public function highlight(string $field, string $operator, string $value, string $class): self
public function highlight_row(string $field, string $operator, string $value, string $class): self
ParameterTypeDefaultDescription
$fieldstringrequiredColumn to evaluate the condition against
$operatorstringrequiredSame vocabulary as where(): symbols or eq/neq/gt/gte/lt/lte/contains/starts/ends
$valuestringrequiredValue to compare the field against
$classstringrequiredCSS class applied when the condition matches
$xcrud->highlight('amount', 'gt', '100000', 'xcrud-hl-warn');
$xcrud->highlight_row('status', 'eq', 'canceled', 'xcrud-hl-muted');

highlight() applies the class to just the matching cell; highlight_row() applies it to the whole row. Multiple rules can match the same cell/row - their classes stack rather than replace each other.