Livewire Datatable Action
Tags: laravel, livewire, datatable
Published: 2022-09-10 16:55:57

If you are using [Rappasoft Laravel Livewire Table version 2](https://rappasoft.com/docs/laravel-livewire-tables/v2/introduction), then you might have the situation to add a standard `Actions` column. Version 2 is a bit different that Version 1.

First of all, you need to extend the `Column` class, name it as `ActionColumn`:

```php
<?php

namespace App\View;

use Illuminate\Database\Eloquent\Model;
use Rappasoft\LaravelLivewireTables\Views\Column;

class ActionColumn extends Column
{
    public function setView($view)
    {
        $this->view = $view;

        return $this;
    }

    public function getView(): string
    {
        return property_exists($this, 'view') ? $this->view : 'livewire.datatable-actions';
    }

    public function getContents(Model $row)
    {
        return view($this->getView())
            ->withColumn($this)
            ->withRow($row);
    }
}
```

Then add the `resources/views/livewire/datatable-actions.blade.php`:

```php
<div class="flex justify-items-center">
    @can('view', $row)
        <a class="cursor-pointer mr-4" href="{{ $row->getResourceUrl('show') }}">
            <x-icon name="o-eye" class="text-indigo hover:font-bold mr-3 flex-shrink-0 h-6 w-6">
            </x-icon>
        </a>
    @endcan
    
    @can('update', $row)
        <a class="cursor-pointer mr-4" 
            @if($form) 
                wire:click="$emitTo('{{ $form }}', 'showRecord', '{{ $row->uuid }}')" 
            @else 
                href="{{ $row->getResourceUrl('edit') }}"
            @endif>
            <x-icon name="o-pencil" class="text-indigo hover:font-bold mr-3 flex-shrink-0 h-6 w-6">
            </x-icon>
        </a>
    @endcan

    @can('delete', $row)
        <div class="cursor-pointer"
            wire:click="$emitTo('confirm', 'displayConfirmation', 'Delete Record', 'Are you sure?', '{{ $form }}', 'destroyRecord', '{{ $row->uuid }}')">
            <x-icon name="o-trash" class="text-indigo hover:text-red-500 mr-3 flex-shrink-0 h-6 w-6">
            </x-icon>
        </div>
    @endcan
</div>
```

Few things happened in the above blade file:

1. I use `@can('method', $object)` to determined either to show / hide the icon. You need to setup proper policy for given model.
2. I use `$emitTo('confirm')`, which referred to my post [here](https://dev.to/nasrulhazim/livewire-confirm-4jn).
3. I use `$row->getResourceUrl()` method as my post in [here](https://dev.to/nasrulhazim/simplify-generate-url-for-resourceful-controller-48l6).

Then the usage in your datatable quite straightforward:

```php
<?php

namespace App\Livewire;

use App\Models\User;
use App\View\ActionColumn;
use Illuminate\Database\Eloquent\Builder;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column;

class UserDatatable extends DataTableComponent
{
    protected $model = User::class;

    /**
     * Set any configuration options
     */
    public function configure(): void
    {
        $this->setPrimaryKey('uuid');
    }

    /**
     * The array defining the columns of the table.
     *
     * @return array
     */
    public function columns(): array
    {
        return [
            Column::make('Name', 'name')
                ->sortable(),
            Column::make('Email', 'email')
                ->sortable(),
            Column::make('Created at', 'created_at')
                ->sortable(),
            Column::make('Updated at', 'updated_at')
                ->sortable(),
            ActionColumn::make('Actions', 'uuid'),
        ];
    }
}
```

You may set different `datatable-actions` view if needed:

```php
ActionColumn::make('Actions', 'uuid')
   ->setView('custom.dt-actions');
```