😽

Filament で確認モーダルを表示する

2023/12/11に公開

この記事について

  • この記事はLaravel Advent Calendar 2023 11日目の投稿です
  • Filamentのフォームボタン実行時に、確認モーダルを表示する方法について検証しました
  • PanelBuilderとPageBuilderのそれぞれで実装しましたので、一例として紹介させていいただきます

Filamentのバージョンについて

https://zenn.dev/eg_nakamura/articles/a9708a390078f0

  • 上の記事にて、Filamentのバージョンをv2からv3にアップグレードしておりますので、今回からこの環境で検証しております
  • v2系での動作は保証しておりませんのでご留意ください

PanelBuilderで生成したフォームで確認モーダルを表示する

PostResource の作成ページに実装します。
修正対象のファイルは Resources/PostResource/Pages/CreatePost.php です。

下記のメソッドを追加します。

/Resources/PostResource/Pages/CreatePost.php
+ use Filament\Actions\Action;

class CreatePost extends CreateRecord
{
+    protected function getCreateFormAction(): Action
+    {
+        return Action::make("create")
+            ->label('さくせい')
+            ->requiresConfirmation()
+            ->action(fn () => $this->create());
+    }
}

getCreateFormAction は、CreatePost が継承している CreateRecord の同名メソッドのオーバーライドになります。
vendor/filament/filament/resources/views/resources/pages/create-record.blade.php を見てみると、getCachedFormActions でボタンアクションを呼び出しており、これを辿っていくとCreateRecord.getFormActions にたどり着きます。
getFormActions の中身は、作成ページの

  • 「作成ボタン」 getCreateFormAction
  • 「保存して、続けて作成ボタン」 getCreateAnotherFormAction(canCreateAnothertrueの時のみ)
  • 「キャンセルボタン」 getCancelFormAction

を呼び出しているので、今回は getCreateFormAction をオーバーライドし、ボタン名の変更と、押下時に確認モーダルを表示しています。
「保存して、続けて作成ボタン」についても同様で、getCreateAnotherFormAction をオーバーライドすることで変更可能です。

確認モーダルは requiresConfirmation を呼び出すことで表示されます。

https://filamentphp.com/docs/3.x/actions/overview

また、確認モーダル内にフォームで入力した内容を表示させ、確認を促すこともできます。
これは PostResourceformメソッドも編集が必要です。
form を下記のように編集します。

/Resources/PostResource.php
    return $form->schema([
        // ここに編集したい項目を追加する
        Forms\Components\TextInput::make("title")
            ->required()
            ->label("タイトル")
            ->hint("ブログのタイトル入力")
+           ->live(),
        Forms\Components\TextInput::make("sub_title")
            ->required()
            ->label("サブタイトル")
            ->hint("ブログのサブタイトル入力")
+           ->live(),
        Forms\Components\Textarea::make("body")
            ->required()
            ->label("本文")
            ->helperText("本文を入力します")
            ->columnSpan("full")
+           ->live(),
    ]);

live()を呼び出すことで、対象のフィールドの入力をリアルタイムに受け取れます。
次に、CreatePostgetCreateFormActionを下記のように編集します。

/Resources/PostResource/Pages/CreatePost.php

class CreatePost extends CreateRecord
{
+    protected string $modalView = 'filament.pages.create-post-confirm-modal';

    protected function getCreateFormAction(): Action
    {
        return Action::make("create")
            ->label('さくせい')
            ->requiresConfirmation()
+           ->modalContent(view($this->modalView, ['input' => $this->data]))
            ->action(fn () => $this->create());
    }
}

modalContentは、確認モーダルに表示したい内容を書いたviewファイルとパラメータを指定することで表示できます。
入力された内容は$this->dataにリアルタイムで格納されており、input というパラメータ名でviewに渡します。
次に、下記内容でviewファイルを作成します。

/resources/views/filament/pages/create-post-confirm-modal.php
<p><span>タイトル:</span><span style="color: #00ff00;">{{$input['title']}}</span></p>
<p><span>サブタイトル:</span><span style="color: #00ff00;">{{$input['sub_title']}}</span></p>
<p><span>本文:</span><span style="color: #00ff00;">{{$input['body']}}</span></p>

ここまで実装すると、下記モーダルが表示されます。

ただ、このままだと未入力の状態でもボタンが押せてしまうので、未入力状態では「さくせい」ボタンが押せないようにしてみます。
CreatePostgetCreateFormActionを下記のように編集します。

/Resources/PostResource/Pages/CreatePost.php

    protected function getCreateFormAction(): Action
    {
        return Action::make("create")
            ->label('さくせい')
            ->requiresConfirmation()
            ->modalContent(view($this->modalView, ['input' => $this->data]))
            ->action(fn () => $this->create())
+           ->disabled(function () {
+               foreach ($this->data as $input) {
+                   if (empty($input)) {
+                       return true;
+                   }
+               }
+               return false;
+           });
    }

disabledの引数にコールバック関数で処理を追加することで、任意にボタンのdisabled属性を変更できます。
編集後、未入力状態だと「さくせい」ボタンが非活性になり、全項目を入力するとボタンが活性化し押せるようになります。

未入力状態

入力状態

PageBuilderで生成したフォームで確認モーダルを表示する

上で紹介した方法と基礎は同じなので簡単です。
以前紹介した新規カスタマイズで作成したOtherページに実装していきます。

Otherクラスに下記formメソッドとボタンメソッドを追加します。

/app/Filament/Pages/Other.php
+use Filament\Forms;
+use Filament\Forms\Form;
~省略~
+    public function form(Form $form): Form
+    {
+        return $form->schema([
+            Forms\Components\TextInput::make("other")
+                ->required()
+                ->label("何か入力")
+                ->live(),
+        ]);
+    }

+    public function addButton() : Action {
+        return Action::make('addButton')
+            ->label('実行')
+            ->requiresConfirmation()
+            ->action(fn () => $this->notice())
+            ->disabled(function () {
+                return empty($this->other);
+            });
+    }

+    public function notice() : void
+    {
+        // ただ通知するだけ
+        Notification::make()
+            ->title('実行ボタン押下')
+            ->color('success')
+            ->send();
+    }

「実行」ボタンを押すと確認モーダルが表示されます。
(「確定」ボタンを押すと通知を表示するようにしています)
次に、viewファイルを下記内容で編集します。

/resources/views/filament/pages/other.blade.php
<x-filament::page>
    <form>
        {{ $this->form }}
        {{ $this->addButton }}
    </form>
</x-filament::page>

ここまで実装すると、フォームに入力後ボタンを押すことで確認モーダルが表示されます。

確認モーダル

まとめ

  • 公式ドキュメントとコードを読み進めると、だんだんカスタマイズ方法がわかってきました
  • 今後も有用なカスタマイズ方法を発見次第紹介していきたいと思います

関連記事

EGSTOCK,Inc.

Discussion