Laravel × JavaScript(Fetch) × MySQL を利用した非同期通信(第3回:詳細検索)

2022/07/18

Laravel × JavaScript(Fetch) × MySQL を利用した非同期通信の第3回になります。

このシリーズについてのイントロは以下になります。

今回は非同期通信(JavaScript の Fetch)を使って詳細検索させる機能を解説をします。

 

デモ画面

↓クリックするとアニメーション Gif で確認できます。↓

 

手順

 

考え方

テキストボックスで入力された ID を Fetch で API 通信を行い、Laravelのコントローラで ID からレコードを抽出して Fetch に返します。

Fetch を使って通信する際、CSRFトークンも送らなければエラーになります。

 

1)Blade ファイル(index)

ID を入力するテキストボックスに id="id_number" を指定します。
後ほど JavaScript 側で document.getElementById('id_number').value でこの値を取得します。

「詳細ボタン」にも id="ajax_show" を指定し、ボタンをクリックすると JavaScript で記述したスクリプトが発火するようにします。

入力した ID 情報は Fetch を使って POST 送信するので、CSRFトークン対策が必要です。

HTML の <head> 内に CSRFトークンを埋め込みます。

 

Blade ファイル(index)

CSS のフレームワークは Bootstrap4 を使っています。


<!--CSRFトークン対策-->
<meta name="csrf-token" content="{{ csrf_token() }}">
:
<div class="col-sm-4">
<div class="card mb-5">
    <div class="card-header">詳細検索</div>
    <div class="card-body">
        <p class="card-text">
        <div class="form-group row">
            <div class="col-md-4">IDを入力:</div>
            <div class="col-md-4">
                <input class="form-control" id="id_number">
            </div>
        </div>
        <div class="form-group row">
            <div class="col-md-12">
                <button id="ajax_show" class="btn btn-info text-white">詳細ボタン</button>
            </div>
        </div>
        </div>
        <!-- 取得したレコードを表示 -->
        <div class="col-md-12" id="result"></div>
        </p>
    </div>
</div>
:

 

 

2)JavaScript(Fetch)

ビューに側で記述していた「詳細ボタン」をクリックすると以下の JavaScript が実行されます。

ここでのポイントは Fetch で通信する際に CSRFトークンも送ること。

でないと CSRFトークンエラーになります。

Fetch の通信先 「ajax-test/show」は Laravel のコントローラで記述したスクリプトが実行されるようにします。

コントローラで記述したスクリプトの値を受け取ったら .then 以降に受け取った値をもとに、ビュー側に表示してあげます。


/*************************
 指定したidのレコードを取得する
 ************************/

ajax_show.addEventListener('click', () => {

    console.log("イベント発火");

    /*--------------------
     POST送信
     -------------------*/
    const postData = new FormData; // フォーム方式で送る場
    postData.set('id', document.getElementById('id_number').value); // set()で格納する

    fetch('ajax-test/show', { // 第1引数に送り先
        method: 'POST',
        headers: {'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content}, // CSRFトークン対策
        body: postData
    })
        .then(response => response.json()) // 返ってきたレスポンスをjsonで受け取って次のthenへ渡す
        .then(res => {
            console.log('res: '+res[0].id); // やりたい処理
            document.getElementById("result").innerHTML = "

ID番号" + res[0].id + "は「" + res[0].name + "」です。
価格は「" + res[0].price+"円」です。

"; }) .catch(error => { console.log(error); // エラー表示 }); });

 

3)ルーティング

先ほど記述した Fetch の通信先である ajax-test/show の URL をここで作成してあげます。


:
Route::post('ajax-test/show', 'AjaxTestController@show');       // 1件表示

 

4)コントローラ(1件表示)

ビュー側で入力した ID をここでレコードを抽出して Fetch に返すスクリプトをコーディングしていきます。

json_encode で JSON に変換したあと、echo すると Fetch の通信に返すことができます。

JSONで Fetch に返却するときは header()メソッドで JSON を指定してあげると通信が安定します。


/**
 * products 1件表示
 */
public function show(Request $request)
{
    $id = $request->input('id');
    $products = \DB::table('products')->where('id',$id)->get();

    $productList = array();
    foreach($products as $product){
        $productList[] = array(
            'id'    => $product->id,
            'name'  => $product->name,
            'price' => $product->price
        );
    }

    header('Content-type: application/json');
    echo json_encode($productList);
}

 
これで、検索による1件表示はできるようになるかと思います。

以上です。

本庄マサノリ

仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら

>> Twitter をフォローする

 

-チュートリアル, 中級