J'essaie de paginer les résultats (toutes les 25 lignes) en utilisant Select2 4.0, mais je ne sais pas comment y parvenir. Quelqu'un sait-il comment le faire?
Si l'utilisateur atteint la fin des 25 lignes et s'il y a plus de lignes, je voudrais le charger et l'afficher.
Voici mon modèle HTML
<div class="form-group">
{!! Form::select('breed_id', $breeds, null, ['class' => 'form-control', 'id' =>'breed_id'] ) !!}
</div>
Et voici le JavaScript pour 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
}
});
Et c'est le code que j'ai pour mon contrôleur
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);
}
Aussi quand j'ai essayé de mettre params.page
il dit "non défini".
Select2 prend en charge la pagination lors de l'utilisation de données distantes via la touche pagination
qui provient de processResults
.
Pour un défilement infini, l'objet pagination
devrait avoir une propriété more
qui est un booléen (true
ou false
). Cela indiquera à Select2 s'il doit charger plus de résultats lorsqu'il atteint le bas ou s'il a atteint la fin des résultats.
{
results: [array, of, results],
pagination: {
more: true
}
}
Dans votre cas, vous avez la possibilité de façonner vos résultats. Vous pouvez donc réellement modifier votre réponse JSON pour qu'elle corresponde au format attendu, ce qui signifie que vous n'aurez même pas besoin d'utiliser processResults
.
Select2 peut transmettre le numéro de page en tant que page
si vous modifiez la fonction ajax.data
Pour le renvoyer.
data: function(params) {
return {
term: params.term || "",
page: params.page || 1
}
},
Et puis vous pourrez obtenir la page en utilisant Input::get('page')
. Et vous pouvez calculer le nombre total de résultats à ignorer en utilisant (page - 1) * resultCount
, Où resultCount
est 25
Dans votre cas. Cela vous permettra de modifier votre requête pour combiner LIMIT
et OFFSET
pour obtenir exactement les résultats dont vous avez besoin.
$page = Input::get('page');
$resultCount = 25;
$offset = ($page - 1) * $resultCount;
Et vous pouvez utiliser la requête suivante pour générer une requête LIMIT
/OFFSET
(basée sur cette question de débordement de pile .
$breeds = Breed::where('name', 'LIKE', '%' . Input::get("term"). '%')->orderBy('name')->skip($offset)->take($resultCount)->get(['id',DB::raw('name as text')]);
Donc maintenant $breeds
Ne contiendra que les résultats demandés. La seule chose qui reste à faire est de façonner la réponse pour qu'elle corresponde à la manière dont Select2 l'attend. Vous pouvez déterminer s'il y a plus de pages en vérifiant le nombre total de résultats et en vérifiant si vous avez dépassé la limite.
$count = Breed::count();
$endCount = $offset + $resultCount;
$morePages = $endCount > $count;
Alors maintenant, $morePages
Devrait être un booléen, c'est exactement ce que Select2 recherche dans pagination.more
. Maintenant, vous avez juste besoin de façonner la réponse pour qu'elle corresponde au format que j'ai mentionné plus tôt.
$results = array(
"results" => $breeds,
"pagination" => array(
"more" => $morePages
)
);
Et puis rendre cela
return response()->json($results);
Tout mettre ensemble, vous obtenez ceci pour 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
}
});
Et ce qui suit pour votre contrôleur
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);
}