23

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すると「未定義」と表示されます。

4

1 に答える 1

48

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

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

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

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

pageSelect2 は、関数を変更しajax.dataて返すようにページ番号を渡すことができます。

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

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

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

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

LIMITまた、次のクエリを使用して/クエリを生成できOFFSETます (このスタック オーバーフローの質問.

$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);
}
于 2015-09-12T23:51:34.470 に答える