2022/07/18
Laravel × JavaScript(Fetch) × MySQL を利用した非同期通信の第3回になります。
このシリーズについてのイントロは以下になります。
Laravel × JavaScript(Fetch)× MySQL を利用した非同期通信(第1回:イントロ)
今回は非同期通信(JavaScript の Fetch)を使って詳細検索させる機能を解説をします。
デモ画面
デモサイト(Laravel × JavaScript(Fetch) × MySQL の非同期通信)
【 ベーシック認証 】laraweb : laraweb
↓クリックするとアニメーション 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 を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら。