欢迎您的光临,本博所发布之文章皆为作者亲测通过,如有错误,欢迎通过各种方式指正。由于本站位于香港虚拟主机,故速度比较慢。

文摘  Yii2使用yii-widget-select2组件实现下拉搜索功能

PHP框架 本站 272 0评论

刚开始使用Yii,需要实现下拉多选搜索,就找到了select2这个组件,先看看实现后的效果:

111.jpg


1.插件的安装


插件下载地址:

github中源代码地址:https://github.com/kartik-v/yii2-widget-select2 

详细文档和解释:http://demos.krajee.com/widget-details/select2 


插件的安装:

利用composer.phar安装此插件:

php composer.phar require kartik-v/yii2-widget-select2 "*"

开发版安装:composer require kartik-v/yii2-widget-select2 "@dev"


2.使用实例


完成后只需要在视图文件use kartik\select2\Select2就可以了。

use kartik\select2\Select2;


具体的视图中的代码如下:

<?=
    $form->field($model, 'search')->widget(Select2::classname(), [
        'options' => ['placeholder' => '请输入用户ID ...'],
        'pluginOptions' => [
            'id' =>  new JsExpression("function(rs) {
                return rs.taskId;
            }"),
            'placeholder' => 'search ...',
            'multiple' => true,
            'allowClear' => true,
            'language' => [
                'errorLoading' => new JsExpression("function () { return 'Waiting...'; }"),
            ],
            'ajax' => [
                'url' => Url::to(['gm-account-info/search-title']),
                'dataType' => 'json',
                'data' => new JsExpression('function(params) {
                return {q:params.term}; }')
            ],
            'escapeMarkup' => new JsExpression('function (markup) {
             return markup; }'),
            'templateResult' => new JsExpression('function(res) {
             return res.text; }'),    
            'templateSelection' => new JsExpression('function (res) {
             return res.text; }'),
        ],
    ]);
?>

控制器中代码如下:

$out = ['results' => ['userid' => '', 'text' => '']];
        if (!$q) {
            echo json_encode($out);die;
        }
        $data = GmAccountInfo::find()
            ->select('uid as userid, account_name as text')
            ->andFilterWhere(['like', 'uid', $q])
            ->asArray()
            ->all();
        $out['results'] = array_values($data);
        echo json_encode($out);die;

这样出来的结果是这样的:

222.jpg


搜索结果是下拉显示出来了,但是无法选中。 

333.jpg


最后将控制器中的代码做了一点修改:

$out = ['results' => ['id' => '', 'text' => '']];
        if (!$q) {
            echo json_encode($out);die;
        }
        $data = GmAccountInfo::find()
            ->select('uid as id, uid as text')   //userid=>id
            ->andFilterWhere(['like', 'uid', $q])
            ->asArray()
            ->all();
        $out['results'] = array_values($data);
        echo json_encode($out);die;

将返回数据的格式调整为[‘id’=>”,’text’=>],就正常了。


结论:使用select2 组件时,后端返回的数据格式必须是[‘id’=>”,’text’=>]这个格式的。


3.使用详解


//如果你的表单是ActiveForm,请使用

use kartik\select2\Select2; 
//$data是键值对数组哦,key-value ,下面所声明的所有$data均为键值对数组,以该数组为例 
$data = [2 => 'widget', 3 => 'dropDownList', 4 => 'yii2']; 
echo $form->field($model, 'title')->widget(Select2::classname(), [  
    'data' => $data, 
    'options' => ['placeholder' => '请选择 ...'], 
]);


//如果你的表单是非ActiveForm,可以参考下面的

use kartik\select2\Select2; 
echo Select2::widget([ 'name' => 'title', 
    'data' => $data, 
    'options' => ['placeholder' => '请选择...'] 
]);


#非ActiveForm生成的更新数据的时候就需要默认选中,好办,加value值即可

use kartik\select2\Select2; 
echo Select2::widget([ 
    'name' => 'title', 
    'value' => 2, 
    'data' => $data, 
    'options' => ['placeholder' => '请选择...'] 
]);

#但是如果你的表单是ActiveForm生成的,但是往往字段不是表字段怎么办呢?更好办啦,以上面的为例,你只需要指定$model->title = ['title1', 'title2'];即可


基本上就是这么回事,我们也就很简单的实现了下拉选择并可搜索的功能。但是,一次选择一个太麻烦了,能不能多选呀?也简单,一行代码解决掉。

echo $form->field($model, 'title')->widget(Select2::classname(), [ 
    'data' => $data, 
    'options' => ['multiple' => true, 'placeholder' => '请选择 ...'], 
]);

#多选的添加默认值同上


眼尖的注意到了,加了一个multiple选项。非ActiveForm生成的表单操作一致。

Select2::widget([ 
    'name' => 'title', 
    'value' => 2, 
    'data' => $data, 
    'options' => ['multiple' => true, 'placeholder' => '请选择...'] 
]);


我们看看效果是怎么样的。

444.png


等等,好像忘记什么了,有眼尖的小伙伴可能注意到了,$data都是我们预先准备好的数据,你说这数据量万一很大的情况,不搞死人了嘛,那接下来让我们看看如何实现异步搜索结果。举一个例子,我们现在要查询某一个书名,但是我们的书的数据量大概有100W,很简单,这需要我们根据你的搜索结果异步获取下拉框里面的数据。


我们来看看如何使用异步搜索功能,工作中尤其是进行关联数据的时候其用途更是大大的,方便性嘛,看看就知道了,好用的不得了。


我们先来预览下异步搜索的效果图

555.png


注意哦,图中标记的部分是我们通过输入的关键词搜索出来的,异步这效果呢,我截图上来估计你也看不到效果。好了,我们干脆直接上代码看具体操作吧。

// view层
use kartik\select2\Select2;
use yii\web\JsExpression;
<?php
    echo $form->field($model, 'title')->widget(Select2::classname(), [
        'options' => ['placeholder' => '请输入标题名称 ...'],
        'pluginOptions' => [
            'placeholder' => 'search ...',
            'allowClear' => true,
            'language' => [
                'errorLoading' => new JsExpression("function () { return 'Waiting...'; }"),
            ],
            'ajax' => [
                'url' => '这里是提供数据源的接口',
                'dataType' => 'json',
                'data' => new JsExpression('function(params) { return {q:params.term}; }')
            ],
            'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
            'templateResult' => new JsExpression('function(res) { return res.text; }'),
            'templateSelection' => new JsExpression('function (res) { return res.text; }'),
        ],
    ]);
?>

上面的代码可直接复制使用,唯独需要修改的就是ajax里对应的url地址。下面我们看看controller层代码是怎么提供数据的。

//controller层
public function actionSearchTitle ($q)
{
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    $out = ['results' => ['id' => '', 'text' => '']];
    if (!$q) {
        return $out;
    }
    $data = Article::find()
                ->select('id, title as text')
                ->andFilterWhere(['like', 'title', $q])
                ->limit(50)
                ->asArray()
                ->all();
                
    $out['results'] = array_values($data);
    return $out;
}


笔记:


在实际项目中,我把data直接从model层获取来,并加上了id

$form->field($model, 'back_reason')->widget(Select2::classname(),
    [
        'name'  => 'search',
        'value' => isset($params['company_id'])?$params['company_id']:'',
        'data'  => \yii\helpers\ArrayHelper::map(\app\models\BackReason::find()->where(
        ['level'=>\app\models\BackReason::LEVEL_2])->asArray()->all(),'id','reason'),
        'options' => ['placeholder' => '退稿原因搜索','style'=>'width:110px;','id'=>'searchreason',],
        'pluginOptions' => [
            'allowClear' => true,
            'width' => '220px',
        ],
    ])

正常情况下这样就可以使用了,但是如果是在bootstrap的模态框中使用select2插件的话,会出现无法输入的问题,插件一直无法获取焦点

666.jpg

解决办法:

首先查看主div中是否有tabindex="-1"

重写enforceFocus方法

<script>
    $(function() {
        $.fn.modal.Constructor.prototype.enforceFocus = function () {};
    });
</script>


转载请注明: ITTXX.CN--分享互联网 » Yii2使用yii-widget-select2组件实现下拉搜索功能

最后更新:2018-12-19 15:49:33

赞 (1) or 分享 ()
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽