コンポーネント内のフォーム
アクションの基礎的な内容を紹介したところで、続いてはフォームとサブミットイベントに話を進めていきます。
プロパティの値が双方向連動するwire:model
次に紹介するのは、図2の[カクテルの追加はこちら]のリンク先にある入力画面(図3)です。
この画面のコンポーネントクラスをCocktailAddとするならば、コンポーネントビューファイルはリスト3のようになります。
<div>
<h1>カクテル管理</h1>
<section>
<h2>カクテル追加</h2>
<form wire:submit="add"> // (1)
<label for="cocktailName">カクテル名</label>
<input type="text" wire:model="cocktailName" id="cocktailName"> // (2)
<div>@error("cocktailName") {{$message}} @enderror</div><br> // (3)
<label for="cocktailPrice">金額</label>
<input type="number" wire:model="cocktailPrice" id="cocktailPrice"> // (4)
<div>@error("cocktailPrice") {{$message}} @enderror</div><br> // (5)
<button type="submit">追加</button>
</form>
<a href="/cocktailList">カクテルリストへ戻る</a>
</section>
</div>
リスト3では(1)のformタグにwire:submit属性を記述することで、サブミットイベントのリスナが登録されます。その属性値であるadd()メソッドをコンポーネントクラスに定義することで、その処理内容がサブミットボタンをクリックした際に実行されるようになります。
その際、フォームの処理なので、入力コントロールでの入力値をコンポーネントクラスで受け取る必要があります。
ここで威力を発揮するのが、入力コントロールであるリスト3の(2)や(4)に記載があるwire:model属性です。この属性値として、コントローラクラスのプロパティ名を記述しておくと、そのプロパティと入力コントロールの値が自動連動するようになります。
コンポーネントクラスではwire:modelのプロパティを定義するだけ
リスト3のwire:modelの属性値であるプロパティを定義したCocktailAddクラスは、リスト4のようになります。
class CocktailAdd extends Component
{
#[Validate("required")] // (1)
public string $cocktailName; // (2)
#[Validate("required|gte:100")] // (3)
public int $cocktailPrice; // (4)
public function add() // (5)
{
$this->validate(); // (6)
$cocktail = new Cocktail(); // (7)
$cocktail->name = $this->cocktailName; // (7)
$cocktail->price = $this->cocktailPrice; // (7)
$cocktail->save(); // (7)
return redirect()->to("/cocktailList"); // (8)
}
public function render()
{
return view("livewire.cocktail-add");
}
}
リスト4の(2)が、リスト3の(2)のカクテル名入力コントロールに対応するプロパティです。同様に、リスト4の(4)が、リスト3の(4)の金額入力コントロールに対応するプロパティです。
このように定義しておくだけで、自動的に入力値が格納されます。そのため、サブミットイベント時に実行される(5)のadd()メソッド内では、入力値の取得処理を記述する必要はなく、(7)のように、プロパティの値を利用するだけです。
その(7)では、Cocktailモデルを利用して、データベースへの保存処理を行っています。その後、(8)でカクテルリスト画面にリダイレクトするようにしています。
バリデーションはアトリビュートを利用
では、そのデータベースへの保存処理の前に行うリスト4の(6)の処理は何かと言うと、メソッド名からわかるように、バリデーションの実行です。
コンポーネントクラスに入力コントロールの値と連動するプロパティを定義した場合、そのプロパティには、バリデーションの設定が可能です。リスト4では(1)や(3)が該当し、PHPのアトリビュートとしてValidateを設定します。このValidateアトリビュートの引数として、実行したいバリデーションルール文字列を渡します。(1)ではrequiredを渡しているので、未入力チェックを行うようになっています。
もし複数のルールを適用させたい場合は、Laravel本体のバリデーション同様、(3)のように|で区切った文字列を渡します。(3)では、requiredによる未入力チェックとgteによる最小値の指定を行っています。
ただし、このようにルールをアトリビュートで設定しただけでは、バリデーションは実行されません。バリデーションを実行したい適切なタイミングでvalidate()メソッドを実行しておく必要があります。それが、リスト4の(6)です。
バリデーションエラーメッセージの表示方法はLaravel本体と同じ
リスト4の(6)のvalidate()メソッドによりバリデーションが実行され、入力内容が不適切の場合は、それ以降の処理は行われずに入力画面にエラーメッセージを表示できるようになります。そのためのコンポーネントビューファイルへの記述は、Bladeでの記述と同じであり、@errorディレクティブが利用できます。
リスト3では、(3)がカクテル名、(5)がカクテルの金額のバリデーションエラーメッセージが表示されるタグです。
結果、入力値に不正がある場合は、図4の画面となります。
なお、この画面ではバリデーションエラーメッセージはデフォルトのものを利用しているため英語となっていますが、日本語メッセージに置き換えることも可能です。詳細は割愛しますが、その方法はLaravel本体と同様です。
