Hi everybody,
I have this problem using Select2 with AJAX-based loading, querying a controller action to get the paginated items. I suspect it is more a javascript issue rather than a Yii2 one, anyway everytime the query result is bigger than the items per page I have set, my Select2 load the items of the first page, display the message "Loading More Result" after scrolling down but never load the items of the second page. Inspecting with the browser I have noticed as the GET to retrieve the second page is never fired. Hope there might be somebody that have already experienced such situation. My code, for the view is:
$formatJs = <<< JS
var formatRepo = function (repo) {
if (repo.loading) {
return repo.name;
}
var markup =
'<div class="row">' +
'<div class="col-sm-6">' +
'<img src="/admin/attachments/file/download?id=' + repo.image_id + '" class="img-rounded" style="width:30px" />' +
'<b style="margin-left:5px">' + repo.name + '</b>' +
'</div>' +
'<div class="col-sm-2"><i class="glyphicon glyphicon-shopping-cart"></i> SKU: ' + repo.sku + '</div>' +
'<div class="col-sm-2"><i class="glyphicon glyphicon-euro"></i> ' + repo.price + '</div>' +
'<div class="col-sm-2"><i class="glyphicon glyphicon-barcode"></i> IVA: ' + repo.vat + '</div>' +
'</div>';
return '<div style="overflow:hidden;">' + markup + '</div>';
};
var formatRepoSelection = function (repo) {
return repo.name;
}
JS;
$this->registerJs($formatJs, View::POS_HEAD);
$resultsJs = <<< JS
function (data, params) {
params.page = params.page || 1;
var more = (params.page * 4) < data.total_count;
return {
results: data.items,
pagination : {
more: more
}
};
}
JS;
....
<?=
$form->field($model, 'id_product')->widget(Select2::className(), [
'id' => 'product_select',
'options' => ['placeholder' => 'Digita il nome di un prodotto o il suo SKU ...'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 1,
'ajax' => [
'url' => "/admin/product/js-retrieve",
'dataType' => 'json',
'delay' => 250,
'data' => new JsExpression('function(params) { return {q: params.term, page: params.page}; }'),
'processResults' => new JsExpression($resultsJs),
'cache' => true
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('formatRepo'),
'templateSelection' => new JsExpression('formatRepoSelection'),
],
]);
?>
.....
The controller:
public function actionJsRetrieve($q) {
if (\Yii::$app->request->isAjax) {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return Product::productsQuery($q);
}
throw new \yii\web\BadRequestHttpException('Errore richiesta non valida');
}
The model:
public static function productsQuery($q) {
$query = Product::find()
->where(['product.is_deleted' => 0])
->andWhere('product.name LIKE :q OR product.sku LIKE :q', [':q' => '%' . $q . '%']);
$count = clone $query;
$pages = new Pagination(['totalCount' => $count->count(), 'defaultPageSize' => 4]);
$models = $query->offset($pages->offset)
->limit($pages->limit)
->all();
$products_array = [];
if (!empty($models)) {
foreach ($models as $product) {
$filesArray = $product->files;
$products_array[] = [
'id' => $product->id,
'name' => $product->name,
'image_id' => $filesArray[0]->id,
'price' => $product->sell_price,
'sku' => $product->sku,
'vat' => $product->vat_rate,
];
}
}
$return['items'] = $products_array;
$return['total_count'] = $count->count();
return $return;
}
I have uploaded also the screenshot of the select2 as post attachment
7229
Thanks everybody