ただメモができるだけのブラウザアプリ「TextArea」はこちらw

Laravel Adminのgridでの細かい検索とformでの1対多のデータ登録のやり方~todoリストを作成しつつ解説~

Laravel Adminのgridとformの使い方について記載していきます。

Laravel Adminって何者?という方は以下の記事をご参照ください。

Laravel Adminで効率的に管理画面を作成する。Dockerを使用した環境構築と使い方について記載。
Laravel Adminは、ウェブアプリケーションの管理画面を効率的かつ簡単に作成できるツールです。 この記事では、Laravel Adminの利点と使い方について詳しく記載します。 Laravel Adminを利用すると、データベースの...

gridとformについて簡単に書くと、以下のようになります。gridとformを理解することでLaravel Adminの大部分を使いこなせると思います。

  • grid:一覧表示
  • form:新規登録・編集機能

本記事でやること

  • 登録・編集(formメソッド)
    • セレクトボックスの設置
      • 選択肢はDBから取得
    • 入力ボックスを使わないデフォルト値設定
    • 1対多のテーブルでのデータ登録
  • フィルター・一覧(gridメソッド)
    • デフォルトでの検索条件の指定
    • チェックボックスでor検索の実装
    • 一覧の文字色変更

 

では、todoリストを作成しつつ、説明していきます

Laravel Adminを動作させる環境構築

環境構築は以下の記事をご参照ください。Dockerで簡単に構築できます。

Laravel Adminで効率的に管理画面を作成する。Dockerを使用した環境構築と使い方について記載。
Laravel Adminは、ウェブアプリケーションの管理画面を効率的かつ簡単に作成できるツールです。 この記事では、Laravel Adminの利点と使い方について詳しく記載します。 Laravel Adminを利用すると、データベースの...

テーブルと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 Comment

Modelは以下のように修正します。

<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メソッドの編集内容

編集前(コマンドでコントローラ作成直後)は、以下の登録画面になっています。

直したいポイントは以下です。

  1. Target user id(todoの担当者) を選択形式にしたい
  2. Regist user id(todoの作成者)はセッション情報から自動的に登録したい
  3. Statusは「0:未完了」で自動的に登録したい
  4. コメントを登録できるようにしたい(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メソッドとは

以下のような機能を持っています。一覧ページ表示用のメソッドですね。

  • データ表示:データベースのレコードをテーブル形式で表示。
  • フィルタリング:条件に基づいてデータを絞り込む。
  • ソート:特定のカラムでデータを昇順または降順に並べ替え。

一覧画面の直したいポイント

直したいポイントは以下です。

  1. 自分が登録したtodoまたは自分が担当のtodoで検索したい
  2. 一覧で自分が担当の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検索の実装
    • 一覧の文字色変更
スポンサーリンク
Laravel
フォローする
さゆフィクション