1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Alpine.js使用時のデータセットメモ

Last updated at Posted at 2024-06-17

はじめに

LaravelとAlpine.jsを組み合わせて使用する際、フロントの操作が楽になります。
しかしながらデータ処理をフロントで使用する場合、バックエンドからのデータをx-dataにセットする際、少し手間取ったのでメモります。

データのセット

Alpine.jsで使用するデータをセットする際、のコンポーネントが初期化される前にセットする必要があります。

以下は、Alpine.jsの初期化前にデータを設定する方法を示した例です。
バックエンドからのデータをフロントで使えるようにセットします。

Bladeテンプレート

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dynamic Form</title>
    <script>
        // PHPでJavaScript変数を設定
        window.defaultRows = @json($defaultRows);
    </script>
    <script src="{{ asset('js/cdn.min.js') }}" defer></script>
</head>

<body>
    <h1>Dynamic Form</h1>

    @if (session('success'))
        <div style="color: green;">
            {{ session('success') }}
        </div>
    @endif

    {{-- デバッグ情報を表示 --}}
    <pre>{{ var_export($defaultRows, true) }}</pre>
    <pre id="debug"></pre>

    {{-- Alpine.jsのx-dataでJavaScript変数を使用 --}}
    <form x-data="{ rows: window.defaultRows }" x-init="console.log(rows)" method="POST" action="{{ route('form.submit') }}">
        @csrf
        <template x-for="(row, index) in rows" :key="index">
            <div>
                <label>
                    <span x-text="index + 1"></span> 番目のフィールド:
                    <input type="text" x-model="row.field" name="rows[][field]" />
                </label>
            </div>
        </template>
        <button type="button" @click.prevent="rows.push({ field: '' });">行の追加</button>
        <input type="submit" value="送信">
    </form>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // デバッグ情報を表示
            document.getElementById('debug').textContent = JSON.stringify(window.defaultRows, null, 2);
        });
    </script>
</body>

</html>

説明

ポイントは以下になります。

  1. <head>内でJavaScript変数を設定:

    • Alpine.jsのスクリプトを読み込む前に、バックエンドからのデータをwindow.defaultRowsにセットします。
      window.defaultRows = @json($defaultRows);
      その際使用する@jsonディレクティブは、LaravelのBladeテンプレートエンジンの機能です。
      このディレクティブは、PHPの配列やオブジェクトをJSON形式の文字列に変換し、そのままHTMLに出力するために使用されます。
      例: @json($array)は、$arrayをJSONエンコードし、その結果をHTMLに出力します。

    • これにより、Alpine.jsのコンポーネントが初期化される前にデータが設定されます。

  2. <script defer>でAlpine.jsを読み込み:

    • defer属性を使用して、HTMLの解析が完了するまでスクリプトの実行を遅らせます。ただし、先に設定したwindow.defaultRowsはすでに利用可能です。
  3. x-datawindow.defaultRowsを使用:

    • x-dataディレクティブ内で、rowswindow.defaultRowsを設定します。これにより、Alpine.jsが初期化されると同時にデータが設定されます。

終わりに

x-dataに@json($変数)をセットできないのが少々面倒でした。
bladeで正しくエスケープ処理がされず、処理するには現状工夫が必要そうです。

その他

以下今回使用したソースを記載します

web.php
<?php

use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;
use App\Http\Controllers\FormController;

Route::get('/form', [FormController::class, 'showForm'])->name('form.show');
Route::post('/form', [FormController::class, 'submitForm'])->name('form.submit');
FormController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FormController extends Controller
{
    public function showForm()
    {
        // デフォルトの行データを設定
        $defaultRows = [
            ['field' => 'default value 1'],
            ['field' => 'default value 2'],
        ];

        return view('form', compact('defaultRows'));
    }

    public function submitForm(Request $request)
    {
        // フォームのデータを処理します。ここではデータのバリデーションと保存などを行います。
        $validatedData = $request->validate([
            'rows' => 'required|array',
            'rows.*.field' => 'required|string|max:255',
        ]);

        // データの処理例
        foreach ($validatedData['rows'] as $row) {
            // 各行のデータを処理します。
            // 例: DBに保存するなど
        }

        return redirect()->route('form.show')->with('success', 'データが送信されました。');
    }
}

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?