Laravel-Adminを使った管理画面を運用しているのですが、用意されている既存フィールドでは要件に合わない時があります。
例えば、年月日の月を管理したい場合です。
もちろん、月を管理するためのフィールドは初めから用意されています。
しかし、年を跨いで設定したい場合、月のみの扱う形式は使いづらいです。
また、入力時にはカレンダー(datetimepicker)で選択できるのですが、選択時に表示される形式も月のみなので歯痒い状態です。
Laravel-Adminのコアファイルを変更すれば対応自体はできますが、今後ライブラリのアップデートやクローンサイトを作る時の弊害になります。
可能であれば任意のフィールドを追加したいものです。
さて、
今回はLaravel-Adminに、カスタムフィールド(任意のフィールド)を追加する方法について記載します。
要件
検証した環境は下記です。
ライブラリ名 | バージョン |
---|---|
Laravel-Admin | v1.5.19 |
Laravel | 5.5以上 |
実装仕様
冒頭でも触れましたが、年を跨ぐ事も考慮して、年と月を組み合わせて管理できるようにしたいです。
例えば、「対象月」を管理する項目を作るとします。
上記を対応する場合、既存の月を管理するフィールドでは次の不満点があります。
- カレンダーの表示形式が月のみ、例えば1月の場合は「01」で保存。
- 月部分だけ文字として保存される、カレンダーと同様に0埋めの数字で保存される
改善方針
理想としては次のような仕様にしたいです。
- カレンダーの表示形式は「(選択された年)年(選択された月)月」 にしたい
- 保存形式はDate型(
YYYY-MM-DD
)にしたい
公式ドキュメント
カスタムフィールドの作り方については下記で解説されています。
今回は、このドキュメントを参考にしながら進めていきます。
カスタムフィールドを追加
自作のカスタムフィールドを追加したい場合は、App\Admin\Extensions
に属したクラスを作る必要があります。
Extensionsクラス用のディレクトリを用意
laravel-adminを導入すると、app
配下にAdmin
ディレクトリが作られます。
作成するExtensions
は、Admin
配下のExtensions
ディレクトリに設定する必要がありますので、ディレクトリを追加します。
app └── Admin └── Extensions
カスタムフィールド用のクラス追加
実際の処理クラスを追加します。
今回はEncore\Admin\Form\Field\Date
の機能(バリデーションや登録処理)を流用したいので、Date
クラスのラッパーを作ります。
次のようなクラスを用意します。
<?php // CustomMonth.php namespace App\Admin\Extensions; use Carbon\Carbon; use Encore\Admin\Form\Field\Date; class CustomMonth extends Date { // 取得したDateの変換フォーマット protected $format = 'YYYY年MM月'; // DateTimeで変換するためのフォーマット public static $defaultFormat = 'Y年m月'; // 登録前の処理 // そのままだと、self::$formatの形式(YYYY年MM月)で保存されるので手動で置換 public function prepare($value) { $result = null; if ($value) { $date = \DateTime::createFromFormat(self::$defaultFormat, $value); $result = $date->format('Y-m-d'); } return $result; } }
作成したCustomMonth.php
を、前項で作成したapp/Admins/Extentions/
配下に設置します。
app └── Admin └── Extensions └── CustomMonth.php
カスタムフィールドを呼び出せるように調整
作成したフィールドをapp/Admin/bootstrap.php
に追加します。
<?php Encore\Admin\Form::forget(['map', 'editor']); // 関数名を「customMonth」として追加 \Encore\Admin\Form::extend( 'customMonth', \App\Admin\Extensions\CustomMonth::class ); // 省略
関数呼び出し
実際に作成した関数を呼び出します。
前項でbootstrapに追加した、customMonthを呼び出します。
<?php // 省略 protected function form() { // 変更 $form->customMonth('target_at', 対象月) ->default(date('Y-m-d')); // 省略 }
これで、次のように「(選択された年)年(選択された月)月」の形式で表示されるようになります。
一覧表示の見た目も変える
現状ではDBに保存された形式で表示されます。
「2020-11-01」のように指定していない日にちまで出てしまいます。
この表示も「2020年11月」のような形式にしたいです。
表示の変更は、display()
で指定します。
<?php protected function grid() { $grid->target_at('対象月') ->display(function($targetAt) { if(! strptime($targetAt, '%Y-%m-%d')) { return null; } // 日付型から対象のフォーマットに変更 $result = new \DateTime($targetAt); return $result->format(CustomMonth::$defaultFormat); }); }
これで、一覧表示時も変換したい形式で表示できます。