在 Kartik Select2 小部件中向下滚动时加载越来越多的数据

Posted

技术标签:

【中文标题】在 Kartik Select2 小部件中向下滚动时加载越来越多的数据【英文标题】:load more and more data when scroll down in Kartik Select2 widget 【发布时间】:2018-12-26 15:30:36 【问题描述】:

我正在开发库存管理系统,有大量产品,客户希望在 Select2 小部件中显示产品,就像 kartik 小部件一样,他想在向下滚动时越来越多地表示数据,是吗可用或可以使用此小部件完成,还是我必须创建自己的? 这是我的代码

<?php
$url = Url::to ( [ 'products-list' ] );
echo Select2::widget ( [
    'name' => 'state_10' ,
    'options' => [
        'id' => 'select_product' ,
        'placeholder' => 'Select Product...' ,
        'multiple' => false ,
        'class' => ''
    ] ,
    'pluginOptions' => [
        'allowClear' => true ,
        'minimumInputLength' => 1 ,
        'ajax' => [
            'url' => $url ,
            'dataType' => 'json' ,
            'data' => new JsExpression ( 'function(params)  return q:params.term; ' )
        ] ,
        'escapeMarkup' => new JsExpression ( 'function (markup)  return markup; ' ) ,
        'templateResult' => new JsExpression ( 'function(product)  console.log(product);return product.text; ' ) ,
        'templateSelection' => new JsExpression ( 'function (subject)  return subject.text; ' ) ,
    ] ,
] );
?>

我的控制器中有这个动作,一切都运行良好,但我需要首先在 select2 中显示一些产品,然后当滚动时开始变得越来越多

控制器动作:

    public function actionProductsList($q = null, $id = null) 
        Yii::$app->response->format = Response::FORMAT_JSON;
        $out = ['results' => ['id' => '', 'text' => '', 'qtyLeft' => '', 'serialNumbers' => '']];
        if (!is_null($q)) 
            $query = new Query;
            $query->select(['product_id as id', new Expression("CONCAT(product_name,' -- ',product_qty_left) AS text, product_qty_left as qtyLeft, s.serial_number as serialNumbers")])
                    ->from('product')
                    ->join('LEFT JOIN', 'serial_number s', 's.r_product_id = product.product_id')
                    ->where(['like', 'product_name', $q]);
//                    ->limit(20);
            $command = $query->createCommand();
            $data = $command->queryAll();
            $out['results'] = array_values($data);
         elseif ($id > 0) 
            $out['results'] = ['id' => $id, 'text' => AppProduct::find()->where(['product_id' => $id])->one()->product_name];
        
        return $out;
    

【问题讨论】:

嘿,您需要更新 actionProductsList 函数的服务器端代码,请参阅下面我的答案中的更新 你好,非常感谢我遇到了这个问题,导致从数据库中检索到的项目出现冗余,现在我可以说一切都很顺利,谢谢。 【参考方案1】:

根据使用分页的文档,您必须告诉 Select2 通过覆盖 ajax.data 设置将任何必要的分页参数添加到请求中。要检索的当前页面存储在params.page 属性中。

所以你需要把Select2改成如下

$url = Url::to ( [ 'products-list' ] );
echo Select2::widget ( [
    'name' => 'state_10' ,
    'options' => [
        'id' => 'select_product' ,
        'placeholder' => 'Select Product...' ,
        'multiple' => false ,
        'class' => ''
    ] ,
    'pluginOptions' => [
        'allowClear' => true ,
        'minimumInputLength' => 1 ,
        'ajax' => [
            'url' => $url ,
            'dataType' => 'json' ,
            'data' => new JsExpression ( 'function(params)  return q:params.term, page:params.page || 1; ' )
        ] ,
        'escapeMarkup' => new JsExpression ( 'function (markup)  return markup; ' ) ,
        'templateResult' => new JsExpression ( 'function(product)  console.log(product);return product.text; ' ) ,
        'templateSelection' => new JsExpression ( 'function (subject)  return subject.text; ' ) ,
    ] ,
] );

Select2 将在响应中期望 pagination.more 值。 more 的值应该是truefalse,它告诉Select2 是否还有更多页的结果可供检索:


  "results": [
    
      "id": 1,
      "text": "Option 1"
    ,
    
      "id": 2,
      "text": "Option 2"
    
  ],
  "pagination": 
    "more": true
  

因此修改您的服务器端代码以包含 $page 参数并在您的查询中包含 limitoffset。我目前使用 5 条记录作为限制,您可以更改它。

public function actionProductsList($page, $q = null , $id = null ) 
        $limit=5;
        $offset=($page-1)*$limit;

        Yii::$app->response->format = Response::FORMAT_JSON;
        $out = [ 'results' => [ 'id' => '' , 'text' => '' , 'qtyLeft' => '' , 'serialNumbers' => '' ] ];
        if ( !is_null ( $q ) ) 
            $query = new \yii\db\Query;
            $query->select ( [ 'product_id as id' , new Expression ( "CONCAT(product_name,' -- ',product_qty_left) AS text, product_qty_left as qtyLeft, s.serial_number as serialNumbers" ) ] )
                    ->from ( 'product' )
                    ->join ( 'LEFT JOIN' , 'serial_number s' , 's.r_product_id = product.product_id' )
                    ->where ( [ 'like' , 'product_name' , $q ] )
                    ->offset ( $offset )
                    ->limit ( $limit );
            $command = $query->createCommand ();
            $data = $command->queryAll ();
            $out['results'] = array_values ( $data );
            $out['pagination'] = [ 'more' => !empty($data)?true:false ];
         elseif ( $id > 0 ) 
            $out['results'] = [ 'id' => $id , 'text' => AppProduct::find ()->where ( [ 'product_id' => $id ] )->one ()->product_name ];
        
        return $out;
    

Update

我在上面的代码中发现了一些修复并进行了更改

修复偏移量$offset=($page-1)*$limit;,而不是使用$page,如-&gt;offset($page),使用$offset,如-&gt;offset($offset)。 正确配置更多结果以在没有更多结果时返回 false,否则即使没有更多结果,它也会继续向服务器发送 ajax 调用,因此请将其更改为 $out['pagination'] = [ 'more' =&gt; !empty($data)?true:false ];

【讨论】:

谢谢您,现在一切顺利!感激不尽! 乐于帮助@MohamadaliZayat

以上是关于在 Kartik Select2 小部件中向下滚动时加载越来越多的数据的主要内容,如果未能解决你的问题,请参考以下文章

Yii2. Kartik Select2 小部件宽度

yii2 kartik select2 小部件不显示列表的第一个元素

Yii2 在“select2”小部件上需要验证规则

Yii2 Kartik Select2 多个标签输入字符串错误

Kartik/Krajee Select2 未禁用

如何从 Select2 Widget Yii2 将多个值保存到数据库