HTMLヘルパー
はじめに
例えばテキストボックスを複数作成する場合、共通する内容ってありますよね?
{{ thml()->text('fuga', old('fuga', ''))->class($errors->has('fuga') ? 'form-text is-error' : 'form-text')->style('width:300px;') }}
上記2で共通するものは何でしょう?
CLASSの内容は、同じテキストなので『通常時』『エラー時』のSTYLEは同じ設定となり【共通】となります。
幅の設定は各テキストボックスにより異なるため共通には無理っぽい。。
いいえ、実は上記2つのコードはほぼ全てが共通するものばかりで以下の様に記述できます。
{{ thml()->text('fuga', '', 300, $errors) }}
メチャメチャ簡素になりましたよね!! どうして、こんな簡素なコードが複雑なコードに化けるのかを順を追って説明します。
まずはHTMLヘルパークラスの骨組みを作成してみましょう。
「~\app\Helpers\MyHtmlHelper.php」へ作成します。
<?php
namespace App\Helpers;
use Spatie\Html\Html as HtmlBuilder;
class MyHtmlHelper extends HtmlBuilder {
public function form($method = 'POST', $action = null) {
var_dump("OK");exit;
}
}
基本的なヘルパーの作成方法は同じですが、種類(text,radio等)によって、必須の引数に違いがあるのでそこだけ注意です!!
サービスプロバイダにヘルパーを登録
試しに『form』タグを作成したビューへアクセスしてみてください。
ヘルパーに発火すればコード『var_dump("OK");exit;』が実行されるハズです。
どうですか?
発火しませんでしよね。 これはLaravelに対して『ヘルパーを使うよ!!』と宣言していないためです。
それではサービスプロバイダに宣言してみましょう。
<?php
namespace hoge\foo;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends HogeFoo {
public function fuga(): void {
$this->app->bind(HogeBuilder::class, MyHtmlHelper::class);
}
public function bar(): void {
//
}
}
今度は『var_dump("OK");exit;』が発火するハズです。
{{ html()->form() }} のカスタマイズ
手打ちでハードコーディングせずに、動的に設定できればタイプミスによる無意味な障害を未然に防げます。
ではビュー側に以下の様な「form」を記述します。
{{ html()->form('POST')->route('hoge.index')->open() }} 上記の内容をそのままレンダリングすると以下の様なタグとなります。
<form method="POST" action="http://localhost/laravel_12/hoge"> それでは「HTMLヘルパー」を修正してみます。
<?php
namespace App\Helpers;
use Spatie\Html\Html as HtmlBuilder;
use Illuminate\Support\Facades\Route;
class MyHtmlHelper extends HtmlBuilder {
public function form($method = 'POST', $action = null) {
$route_name = Route::currentRouteName();
$form = parent::form($method, $action);
// 属性を追加する
return $form->name($route_name)->id($route_name);
}
}
<form method="POST" name="hoge.index" id="hoge.index" action="http://localhost/laravel_12/hoge">
{{ html()->text() }} のカスタマイズ
どうしても『text』を含む各種部品では、バリデーションを意識する必要があるため異常な文字数のコードになりやすいです。
ではヘルパーを見てみましょう。
<?php
namespace App\Helpers;
use Spatie\Html\Html as HtmlBuilder;
use Illuminate\Support\Facades\Route;
class MyHtmlHelper extends HtmlBuilder {
function text($name = null, $value = null, $w = 200, $errors = null) {
$text = parent::text($name, $value);
return $text->value(old($name))->class($errors->has($name) ? 'form-text is-error' : 'form-text')->style('width:' . $w . 'px;');
}
}
『はじめに』で紹介したコードをレンダリングした結果は以下となります。
<input class="form-text" type="text" name="hoge" id="text_name" value style="width:200px;">
{{ html()->radio() }} のカスタマイズ
2.初期状態(ヘルパー側で制御するため[null]とする)
3.値
これをヘルパーで実現するために以下3種類のパターンを作成しました。
① 開始用ラジオ
5.枠の幅(ピクセル)
6.バリデーション様エラー変数
③ 終了用ラジオ
{{ html()->radio('gender', null, '2', '女') }}
{{ html()->radio('gender', null, '3', '無', 'close') }}
// ID名作成(ユニークにする)
$id = $name . '_' . $value;
// ラジオボタン作成(初期値=3:無)
$radio = $radio->id($id)->class('form-radio');
// ラベル作成
$div = $div->class($errors->has($name) ? 'is-error-radio' : 'form-area-border');
$div = $div->style('width:' . $w . 'px;');
}
<label for="gender_1" style="padding:0 5px 0 5px;">男</label>
<input class="form-radio" type="radio" name="gender" id="gender_2" value="2">
<label for="gender_2" style="padding:0 5px 0 5px;">女</label>
<input class="form-radio" type="radio" name="gender" id="gender_3" value="3" checked>
<label for="gender_3" style="padding:0 5px 0 5px;">無</label>
レンダリング結果の通り『div』『radio』『label』タグを出力させています。
これを実現するには【子要素を追加】する(青色)メソッドを使います。
注意する点は、メソッド『open』『close』は必ずメソッドチェーンの最後に設定する必要があります。
※ 文字列にデコードされるのが原因らしい
従って、「open」時は『DIV要素の子』として、「close」は「radio要素の子」として設定します。
{{ html()->checkbox() }} のカスタマイズ
※ 必須の第1引数が文字列の配列型となります('hoge[]')
ビュー側に記述するコードは以下とします。
{{ html()->checkbox('cars[]', null, '2', 'クレスタ') }}
{{ html()->checkbox('cars[]', null, '3', 'RX-7', 'close') }}
<?php
namespace App\Helpers;
use Spatie\Html\Html as HtmlBuilder;
use Illuminate\Support\Facades\Route;
class MyHtmlHelper extends HtmlBuilder {
// チェックボックス作成
$radio = $radio->id($id)->class('form-radio');
// ラベル作成
$div = $div->class($errors->has($name) ? 'is-error-radio' : 'form-area-border');
$div = $div->style('width:' . $w . 'px;');
}
<label for="cars_1" style="padding:0 5px 0 5px;">デミオ</label>
<input class="form-check" type="checkbox" name="cars[]" id="cars_2" value="2">
<label for="cars_2" style="padding:0 5px 0 5px;">クレスタ</label>
<input class="form-check" type="checkbox" name="cars[]" id="cars_3" value="3">
<label for="cars_3" style="padding:0 5px 0 5px;">RX-7</label>
{{ html()->select() }} のカスタマイズ
2.option配列(['1'=>'hoge',・・・])
3.初期値(ヘルパーで設定するのでブランクとする)
{{ html()->select('books', ['' => '--', '1' => 'まんが', '2' => '小説', '3' => '写真集'], '', $errors) }}
<?php
namespace App\Helpers;
use Spatie\Html\Html as HtmlBuilder;
use Illuminate\Support\Facades\Route;
class MyHtmlHelper extends HtmlBuilder {
function select($name = null, $options = [], $value = null, $errors = null) {
// プルダウンリスト作成
$select = parent::select($name, $options, old($name, ''));
// ブロック要素作成(ここに装飾設定をいれます)
$div = parent::div();
$div = $div->class($errors->has($name) ? 'form-select is-error-select' : 'form-select');
return $div->addChild($select);
}
}
<option value="1">まんが</option>
<option value="2">小説</option>
<option value="3">写真集</option>
オーバーライドできるメソッド一覧
function i($contents = null)
function p($contents = null)
function button($contents = null, $type = null, $name = null)
function class($classes): Htmlable
function checkbox($name = null, $checked = null, $value = '1')
function div($contents = null)
function email($name = null, $value = null)
function search($name = null, $value = null)
function date($name = '', $value = null, $format = true)
function datetime($name = '', $value = null, $format = true)
function range($name = '', $value = null, $min = null, $max = null, $step = null)
function time($name = '', $value = null, $format = true)
function element($tag)
function input($type = null, $name = null, $value = null)
function fieldset($legend = null)
function form($method = 'POST', $action = null)
function hidden($name = null, $value = null)
function img($src = null, $alt = null)
function label($contents = null, $for = null)
function legend($contents = null)
function mailto($email, $text = null)
function multiselect($name = null, $options = [], $value = null)
function number($name = null, $value = null, $min = null, $max = null, $step = null)
function option($text = null, $value = null, $selected = false)
function password($name = null)
function radio($name = null, $checked = null, $value = null)
function select($name = null, $options = [], $value = null)
function span($contents = null)
function submit($text = null)
function reset($text = null)
function tel($number, $text = null)
function text($name = null, $value = null)
function file($name = null)
function textarea($name = null, $value = null)
function token()
function model($model)
function modelForm($model, $method = 'POST', $action = null): Form
function endModel()
function closeModelForm(): Htmlable
function old($name, $value = null)
function value($name, $default = null)
function fieldName($name)
function ensureModelIsAvailable()
function formatDateTime($value, $format)
function getEnumValue($value)





「text('text_name', '', $errors)」部分が非常に重要となり、以下の役割があります。
② [必須] value属性となり初期値を設定する
③ [任意] 好きな値を設定できます
「$w」を使い、テキストボックスの幅を指定しています。
「$errors」を使い、通常時とエラー時の[STYLE]を出し分けています。