Ответ 1
Select2 поддерживает разбиение на страницы при использовании удаленных данных с помощью клавиши pagination
, которая выходит из processResults
.
Для бесконечной прокрутки ожидается, что объект pagination
имеет свойство more
, которое является логическим (true
или false
). Это сообщит Select2, должен ли он загружать больше результатов при достижении дна или если он достиг результатов.
{
results: [array, of, results],
pagination: {
more: true
}
}
В вашем случае у вас есть возможность формировать ваши результаты. Таким образом, вы можете изменить свой ответ JSON в соответствии с ожидаемым форматом, что означает, что вам даже не понадобится использовать processResults
.
Select2 может передать номер страницы как page
, если вы измените функцию 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);
}