クマのブログ

つまづいたところ、学びを書いていきます

【Laravel-admin】GridとWidgetの同時利用

前提

  • Windows 10

  • PHP 8.0

  • Laravel 8.0.2

  • Laravel-admin(ライブラリ)

背景

  • 業務中、Laravel-adminを使っており、試行錯誤した中でかなり時間を使ったので、メモ

  • Laravel-adminとは、WEBアプリで必須の「管理画面」を簡単に作ってくれるライブラリ

laravel-admin.org

事象(やりたいこと)

「Laravel-AdminのGridという機能と、Widget(Table)という機能を同じページ内で使いたい」

↓Grid

laravel-admin.org

Widget(Table)

laravel-admin.org

  • Grid:ユーザーリスト一覧ユーザー登録など管理画面で必要なCRUD機能が簡単に実装できる機能

  • Widget:上記GridのようなリストをBoxやinfoBox、Tableの形で表示する機能。今回はTableという機能。

困ったこと

この二つを同時に表示する方法がわからない

試したこと

1,demoサイトを確認

  • 公式マニュアルにdemoサイトと、Githubのコードがあったので、同じような使われ方していないか確認してみた

↓demoサイト

demo.laravel-admin.org

↓demoサイトGithub

github.com

結果

GridとTableを同時に表示させているdemoはなく、解決せず。

2,ソースコードを読み込んでみる

Grid

    protected function grid()
    {
        $grid = new Grid(new User());
        $grid->column('id', 'ID')->sortable();
        ~~~...
    
        return $grid;
    }
  • gridメソッドによってGridの中身を生成

  • $gridにGridクラスのインスタンスを生成し、用意されているcolumnなどのメソッドを使っている

引き数にはモデルやJsonを使ってデータベースなどから値を取得できる。

今回はUserモデルから値を取得

戻り値までに冒頭に生成したインスタンスの内容を設定していき、最後にreturnすることで画面を構成する、という流れ。

Widget(Table)

    public function table(Content $content)
    {
        $content->title('Table');
        $headers = ['Id', 'Email', 'Name', 'age', 'Company'];
        $rows = [
            [1, 'labore21@yahoo.com', 'Ms. Clotilde Gibson', 25, 'Goodwin-Watsica'],
            [2, 'omnis.in@hotmail.com', 'Allie Kuhic', 28, 'Murphy, Koepp and Morar'],
            [3, 'quia65@hotmail.com', 'Prof. Drew Heller', 35, 'Kihn LLC'],
            [4, 'xet@yahoo.com', 'William Koss', 20, 'Becker-Raynor'],
            [5, 'ipsa.aut@gmail.com', 'Ms. Antonietta Kozey Jr.', 41, 'MicroBist'],
        ];
        $table1 = new Widgets\Table($headers, $rows);
        $content->row((new Widgets\Box('Table-1', $table1))->style('info')->solid());
        ~~~...
        return $content;
}
  • Contentクラスを引数にしたtableメソッドを使い、メソッド内で$contentによりContentクラスを使用

  • $header, $rowsでそれぞれヘッダーと一覧の要素を生成

  • $header, $rowsを引数にして$table1でWidgetsクラス内にあるTableクラスをインスタンス化。

  • インスタンス化した$table1を引数にして、$content(Contentクラス)内のrowメソッドすることで、構成する画面の要素を格納

  • $contentをreturnすることで、画面の生成できる

着眼点

  • Gridを使うUserControllerはAdminControllerを継承しており、画面の出力はAdminControllerのindexメソッドで実行していると判明。
class AdminController extends Controller
{
~...
    public function index(Content $content)
    {
        return $content
            ->title($this->title())
            ->description($this->description['index'] ?? trans('admin.list'))
            ->body($this->grid());
    }
~...
}
  • ここにGridを表示する$this->grid()があることと、$contentがあることから

「このindexメソッドをUsersControllerでオーバーライドし、AdminControllerと同じように$contentをリターンすれば表示できるかも」

と推測。

  • 以下のように実装。
    // Contentクラスを引数にして、indexメソッドをオーバーライド
    public function index(Content $content)
    {
        /* Tableの生成*/
        // WidgetController同様、$contentの中身を生成
        ~...
        // Tableのインスタンス化
        $table = new Widgets\Table($headers, $rows);
        // ContentクラスのbodyメソッドでTable内容を設定
        $content->body((new Widgets\Box($select_timestamp, $table))->style('danger')->solid());

        /* Gridの生成 */
        // Gridクラスのインスタンス化
        $grid = new Grid(new Order());
        // Gridの中身生成
        $grid->column('id', __('ID'));
        ~...
        // $grid内容をbodyに格納
        $content->body($grid);
        // $content(Contentクラス)を返す
        return $content;
}

結果

無事表示させれました。

所感

「関連するソースコードは深層までクラスやメソッド、プロパティを確認しすべての流れを理解せねばいけない」

と思っていた

  • 実務の業務の中で大切なのは

    • 「どこに(どのファイルに)、何が(クラスなのか、単一な値なのか)、どんな形で(配列か、数値か、文字列か)返ってくるか」を意識

    • 「こうなるかも?」と想像を働かせながらパズルを組むようにソースコードを見て、トライ&エラ―を繰り返して答えを見つけていく

この工程だなと実感。

  • もちろん、深層まで見ることもあるが、それよりも普段大切なのは「~したら、~になるかもな」という推察力。

今回はこれに気づけた事象でした。