在本文中,我们将深入探讨在 Filament 页面中制作上一页和下一页导航按钮的过程。这些按钮设计为 Filament Header 操作,可以应用在 ViewPages 和 EditPages 之间无缝导航。
引入新的 Action
首先,我们需要引入两个新 Action:PreviousAction 和 NextAction。我将这两个 Action 放在 app/Filament/Resources/Actions
文件夹中。
PreviousAction.php
//Path:app/Filament/Resources/Actions/PreviousAction.php
namespace App\Filament\Resources\Actions;
use Filament\Actions\Action;
class PreviousAction extends Action
{
public static function getDefaultName(): ?string
{
return '上一页';
}
protected function setUp(): void
{
parent::setUp();
$this->hiddenLabel()
->icon('heroicon-o-arrow-left')
->outlined()
->tooltip("Previous {$this->getRecordTitle()}");
}
}
NextAction.php
//Path:app/Filament/Resources/Actions/NextAction.php
namespace App\Filament\Resources\Actions;
use Filament\Actions\Action;
class NextAction extends Action
{
public static function getDefaultName(): ?string
{
return '下一页';
}
protected function setUp(): void
{
parent::setUp();
$this->hiddenLabel()
->icon('heroicon-o-arrow-right')
->outlined()
->tooltip("Next {$this->getRecordTitle()}");
}
}
在 Pages 中配置 Action
接下来,我们通过添加 CanPaginateViewRecord
Trait来扩展 ViewRecord 和 EditRecord 类的功能。我将这个特性放在 app/Filament/Resources/Pages/Concerns
文件夹中,用于配置分页操作,并提供根据当前记录检索上一条和下一条记录的方法。
# Laravel 11 及更高版本可以运行下面的命令创建 trait
php artisan make:trait Filament/Resources/Pages/Concerns/CanPaginateViewRecord
# Laravel 10 及以下的版本需要手动创建 trait 文件
namespace App\Filament\Resources\Pages\Concerns;
use App\Filament\Resources\Actions\NextAction;
use App\Filament\Resources\Actions\PreviousAction;
use Filament\Actions\Action;
use Illuminate\Database\Eloquent\Model;
trait CanPaginateViewRecord
{
protected function configureAction(Action $action): void
{
$this->configureActionRecord($action);
match (true) {
$action instanceof PreviousAction => $this->configurePreviousAction($action),
$action instanceof NextAction => $this->configureNextAction($action),
default => parent::configureAction($action),
};
}
protected function configurePreviousAction(Action $action): void
{
if ($this->getPreviousRecord()) {
$action->url(fn (): string => static::getResource()::getUrl(static::getResourcePageName(), ['record' => $this->getPreviousRecord()]));
} else {
$action
->disabled()
->color('gray');
}
}
protected function configureNextAction(Action $action): void
{
if ($this->getNextRecord()) {
$action->url(fn (): string => static::getResource()::getUrl(static::getResourcePageName(), ['record' => $this->getNextRecord()]));
} else {
$action
->disabled()
->color('gray');
}
}
protected function getPreviousRecord(): ?Model
{
return $this
->getRecord()
->where('id', '<', $this->getRecord()->id)
->orderBy('id', 'desc')
->first();
}
protected function getNextRecord(): ?Model
{
return $this
->getRecord()
->where('id', '>', $this->getRecord()->id)
->orderBy('id', 'asc')
->first();
}
}
注意:在此示例中,我们默认表格使用了自动递增的 ID。如果您的表配置不同,则需要相应地调整
getPreviousRecord
和getNextRecord
方法。
使用示例
现在,让我们在 ViewRecord 和 EditRecord 页面中实现这些操作。通过包含 CanPaginateViewRecord
Trait 并在 getHeaderActions
数组中注册 Action,您可以启用上一个和下一个导航按钮。以下是在 ViewPost 页面中的使用示例:
namespace App\Filament\Resources\PostResource\Pages;
use App\Filament\Resources\Actions\NextAction;
use App\Filament\Resources\Actions\PreviousAction;
use App\Filament\Resources\Pages\Concerns\CanPaginateViewRecord;
use App\Filament\Resources\PostResource;
use Filament\Actions;
use Filament\Resources\Pages\ViewRecord;
class ViewPost extends ViewRecord
{
use CanPaginateViewRecord;
protected static string $resource = PostResource::class;
protected function getHeaderActions(): array
{
return [
Actions\EditAction::make(),
PreviousAction::make(),
NextAction::make(),
];
}
}