jquery - descargar - Select2 v4 cómo paginar los resultados usando AJAX
select2 selected (1)
Estoy tratando de paginar los resultados (cada 25 filas) usando Select2 4.0, pero no sé cómo lograrlo. ¿Alguien sabe cómo hacerlo?
Si el usuario llega al final de las 25 filas y si hay más filas me gustaría cargarlo y mostrarlo.
Aquí está mi plantilla HTML
<div class="form-group">
{!! Form::select(''breed_id'', $breeds, null, [''class'' => ''form-control'', ''id'' =>''breed_id''] ) !!}
</div>
Y aquí está el JavaScript para Select2.
$("#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
}
});
Y este es el código que tengo para mi controlador.
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);
}
También cuando intenté poner params.page
dice "indefinido".
Select2 admite la paginación cuando se usan datos remotos a través de la clave de pagination
que sale de processResults
.
Para el desplazamiento infinito, se espera que el objeto de pagination
tenga una propiedad more
que es un valor booleano ( true
o false
). Esto le dirá a Select2 si debería cargar más resultados al llegar al final, o si ha llegado al final de los resultados.
{
results: [array, of, results],
pagination: {
more: true
}
}
En su caso, tiene la capacidad de dar forma a sus resultados. Por lo tanto, realmente puede cambiar su respuesta JSON para que coincida con el formato esperado, lo que significa que ni siquiera necesitará usar processResults
.
Select2 puede pasar el número de página como page
si modifica la función ajax.data
para devolverlo.
data: function(params) {
return {
term: params.term || "",
page: params.page || 1
}
},
Y luego podrá obtener la página utilizando Input::get(''page'')
. Y puede calcular el número total de resultados a omitir usando (page - 1) * resultCount
, donde resultCount
es 25
en su caso. Esto le permitirá modificar su consulta para combinar LIMIT
y OFFSET
para obtener los resultados que necesita.
$page = Input::get(''page'');
$resultCount = 25;
$offset = ($page - 1) * $resultCount;
Y puede usar la siguiente consulta para generar una consulta LIMIT
/ OFFSET
(basada en esta pregunta de desbordamiento de pila) .
$breeds = Breed::where(''name'', ''LIKE'', ''%'' . Input::get("term"). ''%'')->orderBy(''name'')->skip($offset)->take($resultCount)->get([''id'',DB::raw(''name as text'')]);
Así que ahora $breeds
contendrá solo los resultados solicitados. Lo único que queda por hacer es dar forma a la respuesta para que coincida con la forma en que Select2 la espera. Puede determinar si hay más páginas al verificar el número total de resultados y ver si ha superado el límite.
$count = Breed::count();
$endCount = $offset + $resultCount;
$morePages = $endCount > $count;
Así que ahora $morePages
debería ser un booleano, que es exactamente lo que Select2 está buscando en pagination.more
. Ahora solo necesita configurar la respuesta para que coincida con el formato que mencioné anteriormente.
$results = array(
"results" => $breeds,
"pagination" => array(
"more" => $morePages
)
);
Y luego haciendo que
return response()->json($results);
Poniendo todo junto, obtienes esto para 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
}
});
Y lo siguiente para tu controlador.
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);
}