Select2 v4 如何使用 AJAX 分页显示结果

24

我正在尝试使用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时,它会显示“未定义”。

1个回答

52

Select2支持使用processResults返回的pagination键来处理远程数据的分页。

对于无限滚动,pagination对象应该有一个more属性,它是一个布尔值(truefalse)。这会告诉Select2在到达底部时是否应加载更多结果,或者已经到达结果的末尾。

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

在您的情况下,您有能力塑造自己的结果。因此,您可以实际更改JSON响应以匹配预期格式,这意味着您甚至不需要使用processResults

如果您修改ajax.data函数以返回页面号码,Select2可以将页面号码作为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 问题)。

$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);
}

4
哇!你真是太棒了!我只需要更改2个东西... $morePages = $count > $endCount; 并且计数必须根据输入进行 $count = Count(Breed::where('name', 'LIKE', '%' . Input::get("term"). '%')->orderBy('name')->get(['id',DB::raw('name as text')])); 谢谢你! - Diego

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接