Laravel Adminのgridとformの使い方について記載していきます。
Laravel Adminって何者?という方は以下の記事をご参照ください。
gridとformについて簡単に書くと、以下のようになります。gridとformを理解することでLaravel Adminの大部分を使いこなせると思います。
- grid:一覧表示
 - form:新規登録・編集機能
 
本記事でやること
- 登録・編集(formメソッド) 
- セレクトボックスの設置 
- 選択肢はDBから取得
 
 - 入力ボックスを使わないデフォルト値設定
 - 1対多のテーブルでのデータ登録
 
 - セレクトボックスの設置 
 - フィルター・一覧(gridメソッド) 
- デフォルトでの検索条件の指定
 - チェックボックスでor検索の実装
 - 一覧の文字色変更
 
 

では、todoリストを作成しつつ、説明していきます
Laravel Adminを動作させる環境構築
環境構築は以下の記事をご参照ください。Dockerで簡単に構築できます。
テーブルとModelとControllerの準備
テーブルの作成
テーブル構成は以下のようになります。
- todo情報を格納するtodosテーブル
 - todo情報に対するコメントを格納するcommentsテーブル
 
では、以下のコマンドでマイグレートファイルを作成します。
php artisan make:migration create_todos_table --create=todos
php artisan make:migration create_comments_table --create=commentsマイグレーションファイルは以下のように修正します。
<todosテーブル>
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->increments('id');
            $table->string('todo_name')->nullable(false)->index();    # todoの名前
            $table->string('target_user_id')->nullable(false);    # todoの担当者
            $table->string('regist_user_id')->nullable(true);    # todoの登録者
            $table->integer('status')->nullable(true)->default(0);    # 完了ステータス 0:未完了、1:完了
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('todos');
    }
};<commentsテーブル>
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('todo_id');
            $table->text('comment');
            $table->string('regist_user_id')->nullable(true);
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('comments');
    }
};
Modelの準備
以下のコマンドでModelを作成します。
php artisan make:model Todo
php artisan make:model CommentModelは以下のように修正します。
<Todo.php>
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Todo extends Model
{
    use HasFactory;
    public function comments()
    {
        return $this->hasMany(comment::class);
    }
}
<Comment.php>
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
    protected $fillable = [
        'todo_id',
        'comment',
        'regist_user_id',
    ];
    use HasFactory;
    
    public function todo()
    {
        return $this->belongsTo(Todo::class);
    }
}
動作確認
http://localhost:8000/admin/todos にアクセスして、以下のようにカラのリスト画面が表示されればOKです。

準備ができましたので、formメソッドを編集しつつ、説明していきます。
Laravel adminのformメソッドの使い方
まずformメソッドについて記載します。
formメソッドとは
以下のような機能を持っています。新規登録・編集用のメソッドですね。
- 入力フィールド:テキスト、数値、パスワード、セレクトボックス、ラジオボタン、チェックボックスなど。
 - バリデーション:入力データの検証機能。
 - リレーション管理:関連するデータモデルの管理。
 - イベントフック:フォームの保存前後に処理を追加。
 

それではformメソッドを編集していきます。
formメソッドの編集内容
編集前(コマンドでコントローラ作成直後)は、以下の登録画面になっています。

直したいポイントは以下です。
- Target user id(todoの担当者) を選択形式にしたい
 - Regist user id(todoの作成者)はセッション情報から自動的に登録したい
 - Statusは「0:未完了」で自動的に登録したい
 - コメントを登録できるようにしたい(1対多のデータ登録)
 
完成系の画面イメージは以下のような感じです。

では順番に修正していきます。
Target user id(todoの担当者) を選択形式にしたい
ファイル上部でLaravel-adminのAdminクラスの名前空間を宣言します。
use Encore\Admin\Facades\Admin;次に以下のように「target_user_id」をテキストからセレクトボックスに変更し、セレクトボックスの選択肢に、Adminユーザを指定します。
// $form->text('target_user_id', __('Target user id'));  //コメントアウト
$form->select('target_user_id', __('Target user id'))->options(Admin::user()->pluck('username', 'id')); //追加完了です。次にいきます。
Regist user id(todoの作成者)はセッション情報から自動的に登録したい
regist_user_idの入力ボックスをコメントアウトします。
//$form->text('regist_user_id', __('Regist user id'));次に$form->savingを使ってregist_user_idにログイン中ユーザのIDを登録します。
        $form->saving(function (Form $form) {
            // regist_user_idは「Admin::user()->id」を設定する
            $form->model()->regist_user_id = Admin::user()->id;
        });完了です。次にいきます。
Statusは「0:未完了」で自動的に登録したい
statusの入力ボックスをコメントアウトします。
//$form->number('status', __('Status'));次に$form->savingを使ってstatusに「0」を登録します。
        $form->saving(function (Form $form) {
            // regist_user_idは「Admin::user()->id」を設定する
            $form->model()->regist_user_id = Admin::user()->id;
            // statusは「0」を設定する
            $form->model()->status = 0;   //ここを追加
        });完了です。次はコメントです。
コメントを登録できるようにしたい(1対多のデータ登録)
以下のように記載することで、コメントを登録できるようになります。
        # コメント
        $form->hasMany('comments', 'コメント欄', function (Form\NestedForm $form) {
            $form->hidden('regist_user_id', __('regist_user_id'))->default(Admin::user()->id);
            $form->textarea('comment','コメント');
        });hasManyメソッドを使い、複数のコメントをフォームに追加できるようにしています。
完成した画面
以下の通り、実現したかった画面が出来上がりましたー

編集画面でステータスを完了できるようにする
このままだと、ステータスを完了にできないので、編集画面でステータスを完了できるようにします。
以下のコードを書いてあげれば、ステータス更新可能になります。
        // ステータス更新(編集時のみ更新可能)
        if ($form->isEditing()) {
            $form->switch('status', '完了')->states([
                'on' => ['value' => 1, 'text' => '完了', 'color' => 'success'],
                'off' => ['value' => 0, 'text' => '未完了', 'color' => 'danger'],
            ]);
        }$form->isEditing()で登録か更新かの判定をしています。
更新の場合、入力パーツswitchを表示するコードになっています。
編集画面の完成系は以下のようになります!

Laravel adminのgridメソッドの使い方
まずgridメソッドについて記載します。
gridメソッドとは
以下のような機能を持っています。一覧ページ表示用のメソッドですね。
- データ表示:データベースのレコードをテーブル形式で表示。
 - フィルタリング:条件に基づいてデータを絞り込む。
 - ソート:特定のカラムでデータを昇順または降順に並べ替え。
 
一覧画面の直したいポイント
直したいポイントは以下です。
- 自分が登録したtodoまたは自分が担当のtodoで検索したい
 - 一覧で自分が担当のtodoは赤文字表示したい
 
自分が登録したtodoまたは自分が担当のtodoで検索したい
以下のコードを書いてあげれば、検索可能になります。
作成者(regist_user_id)と担当者(target_user_id)のor検索になります。
        $grid->filter(function ($filter) {
            $filter->where(function ($query) {
                if(array_search('1', $this->input) !== false) {
                    $query->orWhere('regist_user_id', Admin::user()->id);
                }
                if(array_search('2', $this->input) !== false) {
                    $query->orWhere('target_user_id', Admin::user()->id);
                }
            }, '自分のtodoを表示', 'search_tantou')->checkbox([
                '1' => '作成したtodoを表示',
                '2' => '担当のtodoを表示',
            ]);
        });デフォルトで(画面アクセス時に)「作成者(regist_user_id)と担当者(target_user_id)のor検索」で絞り込みをしたい場合は、メニュー編集で対応できます。http://localhost:8000/admin/auth/menu にアクセスし、メニューを編集します。編集時に、URIを以下の通り設定します。
todos?&search_tantou%5B%5D=1&search_tantou%5B%5D=2画面で説明すると、以下の画面のURIに上記の値を入力して保存です。

一覧で自分が担当のtodoは赤文字表示したい
以下のコードで、自分が担当のtodoを赤字で表示できます。
        // 文字色設定
        $grid->rows(function ($row) {
            # 自分が担当のtodoは、赤字にする
            if ($row->target_user_id == Admin::user()->id ) {
                $row->style('color: red');
            }
        });完成した画面
完成した一覧画面は以下の通りです。
URIを「todos?&search_tantou%5B%5D=1&search_tantou%5B%5D=2」に変更した場合、画面表示直後は、「自分のtodoの表示」のチェックボックスはONになっているはずです。

以下が実現できましたー
- デフォルトでの検索条件の指定
 - チェックボックスでor検索の実装
 - 一覧の文字色変更
 
修正後のコントローラの全体ソース
修正後のコントローラの全体ソースは以下の通りです。
<?php
namespace App\Admin\Controllers;
use App\Models\Todo;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Show;
use Encore\Admin\Facades\Admin;
class TodoController extends AdminController
{
    /**
     * Title for current resource.
     *
     * @var string
     */
    protected $title = 'Todo';
    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        $grid = new Grid(new Todo());
        $grid->filter(function ($filter) {
            $filter->where(function ($query) {
                if(array_search('1', $this->input) !== false) {
                    $query->orWhere('regist_user_id', Admin::user()->id);
                }
                if(array_search('2', $this->input) !== false) {
                    $query->orWhere('target_user_id', Admin::user()->id);
                }
            }, '自分のtodoを表示', 'search_tantou')->checkbox([
                '1' => '作成したtodoを表示',
                '2' => '担当のtodoを表示',
            ]);
        });
        $grid->column('id', __('Id'));
        $grid->column('todo_name', __('Todo name'));
        $grid->column('target_user_id', __('Target user id'));
        $grid->column('regist_user_id', __('Regist user id'));
        $grid->column('status', __('Status'));
        $grid->column('created_at', __('Created at'));
        $grid->column('updated_at', __('Updated at'));
        // 表示色
        $grid->rows(function ($row) {
            # 自分が担当のtodoは、赤字にする
            if ($row->target_user_id == Admin::user()->id ) {
                $row->style('color: red');
            }
        });
        return $grid;
    }
    /**
     * Make a show builder.
     *
     * @param mixed $id
     * @return Show
     */
    protected function detail($id)
    {
        $show = new Show(Todo::findOrFail($id));
        $show->field('id', __('Id'));
        $show->field('todo_name', __('Todo name'));
        $show->field('target_user_id', __('Target user id'));
        $show->field('regist_user_id', __('Regist user id'));
        $show->field('status', __('Status'));
        $show->field('created_at', __('Created at'));
        $show->field('updated_at', __('Updated at'));
        return $show;
    }
    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        $form = new Form(new Todo());
        $form->text('todo_name', __('Todo name'));
//        $form->text('target_user_id', __('Target user id'));
        $form->select('target_user_id', __('Target user id'))->options(Admin::user()->pluck('username', 'id'));
//        $form->text('regist_user_id', __('Regist user id'));
//        $form->number('status', __('Status'));
        # コメント
        $form->hasMany('comments', 'コメント欄', function (Form\NestedForm $form) {
            $form->hidden('regist_user_id', __('regist_user_id'))->default(Admin::user()->id);
            $form->textarea('comment','コメント');
        });
        // ステータス更新(編集時のみ更新可能)
        if ($form->isEditing()) {
            $form->switch('status', '完了')->states([
                'on' => ['value' => 1, 'text' => '完了', 'color' => 'success'],
                'off' => ['value' => 0, 'text' => '未完了', 'color' => 'danger'],
            ]);
        }
        $form->saving(function (Form $form) {
            // regist_user_idは「Admin::user()->id」を設定する
            $form->model()->regist_user_id = Admin::user()->id;
            // statusは「0」を設定する
            $form->model()->status = 0;
        });
        return $form;
    }
}
まとめ
Laravel adminで以下の修正をしてみました。結構短時間でできたと思います。Laravel admin素晴らし〜
- 登録・編集(formメソッド) 
- セレクトボックスの設置 
- 選択肢はDBから取得
 
 - 入力ボックスを使わないデフォルト値設定
 - 1対多のテーブルでのデータ登録
 
 - セレクトボックスの設置 
 - フィルター・一覧(gridメソッド) 
- デフォルトでの検索条件の指定
 - チェックボックスでor検索の実装
 - 一覧の文字色変更
 
 


