Context aware table row actions for Laravel Nova
During one of our dev runs, there were some fancy action requirements and I was really happy to find that Laravel Nova supports actions on the index table rows!
So imagine that how bummed we were when we found out that said actions don’t really know anything about the table row’s contents at which ones ends they are sitting at… even though it works just fine on the resource detail screen. But, as always, there’s a way, and you don’t even have to install a 3rd party library to solve this!
You only need to do a couple of things, it’s so easy that you will be facepalming for the rest of the week!
1st, you’ll need to create an attribute on your action with a fluent setter for it:
<?php
namespace App\Nova\Actions;
use App\Models\AccountData;
use Illuminate\Bus\Queueable;
use Laravel\Nova\Actions\Action;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class EmailAccountProfile extends Action
{
use InteractsWithQueue, Queueable; public $resource; /**
* Perform the action on the given models.
*
* @param \Laravel\Nova\Fields\ActionFields $fields
* @param \Illuminate\Support\Collection $models
* @return mixed
*/
public function handle(ActionFields $fields, Collection $models)
{
foreach ($models as $model) {
(new AccountData($model))->send();
}
}
/**
* Get the fields available on the action.
*
* @return array
*/
public function fields()
{
return [];
} public function setResource($value)
{
$this->resource = $value;
return $this;
}
}
2nd, when you’re adding the action to your resource just set the resource on the action, like this:
/**
* Get the actions available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function actions(Request $request)
{
return [
(new MoveAsset)
->onlyOnTableRow()
->setResource($this->resource),
];
}
With this, you can customize each action’s form to the requirements of the actual row, much like in the detail view!