Skip to content

Editing Data โ€‹

Introduction โ€‹

editOnClick() and toggleable() are plugins. They render in the cell and dispatch updates to onPluginUpdated(). They do not auto-save: you persist the value yourself, so they work with any datasource.

Edit on click โ€‹

Clicking a cell turns it into a contenteditable input. Enter submits. Escape discards. If the value is empty, a fallback can be shown.

Chain editOnClick() on a Column:

phpapp/Livewire/ProductTable.php
use PowerComponents\LivewirePowerGrid\PowerGridComponent;
use PowerComponents\LivewirePowerGrid\Column;

class ProductTable extends PowerGridComponent
{
    public function columns(): array
    {
        return [
            Column::add()
                ->title('Name')
                ->field('name')
                ->editOnClick( 
                    hasPermission: auth()->check(),
                    fallback: '- empty -'
                ),
        ];
    }
}

If the column displays a custom field, the second argument to field() (or editOnClick(dataField:)) must be the database column that is saved:

phpapp/Livewire/ProductTable.php
use PowerComponents\LivewirePowerGrid\PowerGridComponent;
use PowerComponents\LivewirePowerGrid\Column;
use PowerComponents\LivewirePowerGrid\Facades\PowerGrid;
use PowerComponents\LivewirePowerGrid\PowerGridFields;
use Illuminate\Support\Number;

class ProductTable extends PowerGridComponent
{
    public function fields(): PowerGridFields
    {
        return PowerGrid::fields()
            ->add('id')
            ->add('price')
            ->add('price_in_eur', function ($product) {
                return Number::currency($product->price, in: 'EUR');
            });
    }

    public function columns(): array
    {
        return [
            Column::add() 
                ->title('Price (EUR)')
                ->field('price_in_eur', 'price')
                ->editOnClick(
                    hasPermission: auth()->check(),
                    fallback: 'โ‚ฌ0,00'
                ),
        ];
    }
}
ParameterDescriptionDefault
(bool) $hasPermissionWhen true, the cell is editable.true
(string) $dataFieldField used as the editor value. Sets the column dataField when filled.''
(?string) $fallbackFallback text for empty values.null
(bool) $saveOnMouseOutIf true, submit when clicking outside the input.false

Toggleable โ€‹

The cell becomes a switch for a boolean. Without permission, a Yes/No badge is shown instead.

Relationship fields (field contains .) are not rendered as a switch.

phpapp/Livewire/ProductTable.php
use PowerComponents\LivewirePowerGrid\PowerGridComponent;
use PowerComponents\LivewirePowerGrid\Column;

class ProductTable extends PowerGridComponent
{
    public function columns(): array
    {
        return [
            Column::add()
                ->title('In Stock')
                ->field('in_stock')
                ->toggleable( 
                    hasPermission: auth()->check(),
                    trueLabel: 'Yes',
                    falseLabel: 'No'
                ),
        ];
    }
}
ParameterDescriptionDefault
(bool) $hasPermissionEnable or disable the switchtrue
(string) $trueLabelLabel when the value is trueYes
(string) $falseLabelLabel when the value is falseNo

Handling updates โ€‹

Editable and Toggleable call only onPluginUpdated(). Validate input before persisting.

ParameterTypeDescription
$plugin'editable' | 'toggleable' | stringPlugin that triggered the event.
$eventstring'updated' for editable and toggleable.
$paramsarray{id: string, field: string, value: string}Record ID (as string), column dataField, and submitted value.
phpapp/Livewire/ProductTable.php
use App\Models\Product;
use PowerComponents\LivewirePowerGrid\PowerGridComponent;

class ProductTable extends PowerGridComponent
{
    public function onPluginUpdated(string $plugin, string $event, array $params): void
    {
        if ($plugin === 'editable' || $plugin === 'toggleable') {
            Product::query()->find($params['id'])->update([
                $params['field'] => $params['value'],
            ]);
        }
    }
}

onUpdatedEditable() and onUpdatedToggleable() remain as deprecated helpers that forward to onPluginUpdated(). The plugins never call them, so overriding them has no effect.

Updating custom fields โ€‹

$params['field'] is the column's dataField (the field() value when no data field is set). If a custom field is edited without a data field (e.g. Column::make('Price', 'price_formatted')), the editor shows and submits the formatted value. Map it back and parse it before saving:

phpapp/Livewire/ProductTable.php
use PowerComponents\LivewirePowerGrid\PowerGridComponent;
use App\Models\Product;

class ProductTable extends PowerGridComponent
{
    public function onPluginUpdated(string $plugin, string $event, array $params): void
    {
        if ($plugin !== 'editable') {
            return;
        }

        $field = $params['field'];
        $value = $params['value'];

        if ($field === 'price_formatted') { 
            $field = 'price';
            $value = str($value)->replace('.', '')
                ->replace(',', '.')
                ->replaceMatches('/[^Z0-9\.]/', '')
                ->toString();
        }

        Product::query()->find($params['id'])->update([
            $field => $value,
        ]);
    }
}

Reload data on update โ€‹

Call $this->fetchDatasource() after a successful write if you need a full datasource refresh:

phpapp/Livewire/ProductTable.php
use PowerComponents\LivewirePowerGrid\PowerGridComponent;
use App\Models\Product;

class ProductTable extends PowerGridComponent
{
    public function onPluginUpdated(string $plugin, string $event, array $params): void
    {
        $updated = Product::query()->find($params['id'])->update([
            $params['field'] => $params['value'],
        ]);

        if ($updated) { 
            $this->fetchDatasource();
        }
    }
}

Reload data from another component โ€‹

Set a unique table name, then dispatch pg:eventRefresh-{tableName}:

phpapp/Livewire/SomeComponent.php
namespace App\Livewire;

use Livewire\Component;

class SomeComponent extends Component
{
    public function save()
    {
        $this->dispatch('pg:eventRefresh-ProductTable'); 
    }
}

Skip re-render after update โ€‹

Call Livewire's skipRender() after the update:

phpapp/Livewire/ProductTable.php
use PowerComponents\LivewirePowerGrid\PowerGridComponent;
use App\Models\Product;

class ProductTable extends PowerGridComponent
{
    public function onPluginUpdated(string $plugin, string $event, array $params): void
    {
        Product::query()->where('id', $params['id'])->update([
            $params['field'] => $params['value'],
        ]);

        $this->skipRender(); 
    }
}

Created By Luan Freitas and @DanSysAnalyst