web-dev-qa-db-ja.com

Select2 v4 AJAXを使用して結果をページ分割する方法

Select2 4.0を使用して結果(25行ごと)をページ分割しようとしていますが、それを実現する方法がわかりません。誰かがそれを行う方法を知っていますか?

ユーザーが25行の最後に到達し、さらに行がある場合は、ロードして表示したいと思います。

これが私のHTMLテンプレートです

<div class="form-group">
    {!! Form::select('breed_id', $breeds, null, ['class' => 'form-control', 'id' =>'breed_id'] ) !!}
</div>

Select2のJavaScriptは次のとおりです。

$("#breed_id").select2({
    placeholder: 'Breed...',
    width: '350px',
    allowClear: true,
    ajax: {
        url: '',
        dataType: 'json',
        data: function(params) {
            return {
                term: params.term
            }
        },
        processResults: function (data, page) {
            return {
                results: data
            };
        },
        cache: true
    }
});

そして、これは私のコントローラーのために持っているコードです

if ($request->ajax())
{
    $breeds = Breed::where('name', 'LIKE',  '%' . Input::get("term"). '%')->orderBy('name')->take(25)->get(['id',DB::raw('name as text')]);

    return response()->json($breeds);
}

また、params.page「未定義」と表示されます。

19
Diego

Select2は、paginationから出てくるprocessResultsキーを介してリモートデータを使用する場合のページネーションをサポートします。

無限スクロールの場合、paginationオブジェクトには、ブール値(moreまたはtrue)であるfalseプロパティが必要です。これにより、Select2が最下部に到達したときにさらに結果をロードする必要があるか、結果の最後に到達したかがわかります。

_{
  results: [array, of, results],
  pagination: {
    more: true
  }
}
_

あなたの場合、あなたはあなたの結果を形作る能力を持っています。したがって、実際にJSONレスポンスを変更して、期待される形式に一致させることができます。つまり、processResultsを使用する必要さえありません。

Select2は、_ajax.data_関数を変更して返す場合、pageとしてページ番号を渡すことができます。

_data: function(params) {
    return {
        term: params.term || "",
        page: params.page || 1
    }
},
_

そして、Input::get('page')を使用してページを取得できます。また、_(page - 1) * resultCount_を使用してスキップする結果の総数を計算できます。ここでresultCountは_25_です。これにより、クエリを変更してLIMITOFFSETを組み合わせて、必要な結果だけを取得できます。

_$page = Input::get('page');
$resultCount = 25;

$offset = ($page - 1) * $resultCount;
_

そして、次のクエリを使用してLIMIT/OFFSETクエリを生成できます( このStack Overflow question に基づきます)。

_$breeds = Breed::where('name', 'LIKE',  '%' . Input::get("term"). '%')->orderBy('name')->skip($offset)->take($resultCount)->get(['id',DB::raw('name as text')]);
_

したがって、_$breeds_には要求された結果のみが含まれます。行うべき唯一のことは、Select2が期待する方法に一致するように応答を整形することです。結果の総数をチェックし、制限を超えたかどうかを確認することで、ページがさらにあるかどうかを判断できます。

_$count = Breed::count();
$endCount = $offset + $resultCount;
$morePages = $endCount > $count;
_

したがって、_$morePages_はブール値である必要があります。これは、Select2が_pagination.more_で探しているものです。これで、先ほど述べた形式に一致するように応答を整形する必要があります。

_$results = array(
  "results" => $breeds,
  "pagination" => array(
    "more" => $morePages
  )
);
_

そしてそれをレンダリングする

_return response()->json($results);
_

すべてをまとめると、JavaScriptでこれが得られます

_$("#breed_id").select2({
    placeholder: 'Breed...',
    width: '350px',
    allowClear: true,
    ajax: {
        url: '',
        dataType: 'json',
        data: function(params) {
            return {
                term: params.term || '',
                page: params.page || 1
            }
        },
        cache: true
    }
});
_

そして、コントローラーの次の

_if ($request->ajax())
{
    $page = Input::get('page');
    $resultCount = 25;

    $offset = ($page - 1) * $resultCount;

    $breeds = Breed::where('name', 'LIKE',  '%' . Input::get("term"). '%')->orderBy('name')->skip($offset)->take($resultCount)->get(['id',DB::raw('name as text')]);

    $count = Breed::count();
    $endCount = $offset + $resultCount;
    $morePages = $endCount > $count;

    $results = array(
      "results" => $breeds,
      "pagination" => array(
        "more" => $morePages
      )
    );

    return response()->json($results);
}
_
38
Kevin Brown