42
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Laravel】ajaxを使った検索機能の実装

Last updated at Posted at 2020-07-24

非同期通信で検索機能を実装する

簡単な流れ

検索ボタンを押す→サーバー側の任意のアクションへリクエストを投げる→DBから任意の値をとってくる→レスポンスとしてjsonデータをフロント側に返す→フロントはそれを元にビューを作成

使用したもの

  • user.js
  • UserController.php
  • user/index.blade.php
  • web.php

step1 フロント側

1. イベントの起点を決める

検索フォームとクリックイベントの起点となるボタンを記述

index.blade.php

    <div class="search-wrapper col-sm-4">
      <div class="user-search-form">
        {{ Form::text('search_name', null, ['id' => 'search_name', 'class' => 'form-control shadow', 'placeholder' => 'ユーザーを検索する']) }}
        {{ Form::button('<i class="fa fa-search" aria-hidden="true"></i>', ['class' => 'btn search-icon', 'type' => 'button']) }}
      </div>
    </div>

ポイント

  • フォームファサードを使うがForm::openの記述はいらない
  • buttonタグのtypeはbuttonにしないと遷移が走ってしまう
  • search-iconがイベントの起点

2.ajaxを走らせる

検索ボタンを押下後にサーバーサイドにリクエストを送れるようにする

 $('.user-search-form .search-icon').on('click', function () {
        $('.user-table tbody').empty(); //もともとある要素を空にする
        $('.search-null').remove(); //検索結果が0のときのテキストを消す

        let userName = $('#search_name').val(); //検索ワードを取得

        if (!userName) {
            return false;
        } //ガード節で検索ワードが空の時、ここで処理を止めて何もビューに出さない

        $.ajax({
            type: 'GET',
            url: '/user/index/' + userName, //後述するweb.phpのURLと同じ形にする
            data: {
                'search_name': userName, //ここはサーバーに贈りたい情報。今回は検索ファームのバリューを送りたい。
            },
            dataType: 'json', //json形式で受け取る

            beforeSend: function () {
                $('.loading').removeClass('display-none');
            } //通信中の処理をここで記載。今回はぐるぐるさせるためにcssでスタイルを消す。
         }).done(function (data) {
         //以下は後述

ポイント

  • dataTypeはjson
  • 今回は表示させるだけなのでget通信
  • beforeSendは無くても良い

これでサーバーへ非同期でデータが渡せる

step2 サーバー側

1.コントローラーを呼ぶ

まず、ajaxでurlを設定した通りにweb.phpでルーティングを構築する

Route::get('/user/index/{name}', 'UserController@getUsersBySearchName'); // url: '/user/index/' + userNameと同じ

これでajaxが走ったときにUserコントローラーのgetUsersBySearchNameアクションが呼ばれる

2.DBから値を取得しjsonでフロントへ返却

URLのパラメーターを引数にUserモデルから任意の値を取得する

UserController.php

    public function getUsersBySearchName($userName)
    {
        $users = $this->user->where('name', 'like', '%' . $userName . '%')->withCount('items')->orderBy('items_count', 'desc')->get(); //出品数もほしいため、withCountでitemテーブルのレコード数も取得
        return response()->json($users);
    }

ポイント

  • 返り値は必ずjsonデータ

step3 フロント側

1.サーバーから受け取った値をビューに表示

ajax通信が成功したときの処理としてjsonデータをビューに表示させる。
dataにはサーバーから受け取った値がjson形式で入っている

}).done(function (data) { //ajaxが成功したときの処理
            $('.loading').addClass('display-none'); //通信中のぐるぐるを消す
            let html = '';
            $.each(data, function (index, value) { //dataの中身からvalueを取り出す
    //ここの記述はリファクタ可能
                let id = value.id;
                let name = value.name;
                let avatar = value.avatar;
                let itemsCount = value.items_count;
    // 1ユーザー情報のビューテンプレートを作成
                html = `
                            <tr class="user-list">
                                <td class="col-xs-2"><img src="${avatar}" class="rounded-circle user-avatar"></td> //${}で変数展開
                                <td class="col-xs-3">${name}</td>
                                <td class="col-xs-2">${itemsCount}</td>
                                <td class="col-xs-5"><a class="btn btn-info" href="/user/${id}">詳細</a></td>
                            </tr>
                                `
            })
            $('.user-table tbody').append(html); //できあがったテンプレートをビューに追加
   // 検索結果がなかったときの処理
            if (data.length === 0) {
                $('.user-index-wrapper').after('<p class="text-center mt-5 search-null">ユーザーが見つかりません</p>');
            }

        }).fail(function () {
   //ajax通信がエラーのときの処理
            console.log('どんまい!');
        })

ポイント

  • console.log(data)でdataの中身を確認する
  • 検証ツールのnetwork欄でajaxの情報が確認できる
  • ドット記法でdataの中身を取り出せる
  • eachを使って各テンプレートに変数を代入する
  • それをビューにappendさせる(ちなみに上記コードよりまとめたあとに一つの変数としてappendしたほうがよい)

ちゃんとビューに表示されていれば完成!

参考資料

42
31
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
42
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?