首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Yii2 整合 Select2 實現下拉框自動搜索與遠程加載

     編輯:PHP 相關知識

Yii2 整合 Select2 實現下拉框自動搜索與遠程加載

Kartik 的 yii2-widget-select2 是 Yii2 整合 Select2 的最佳選擇,支援本地數據、AJAX 遠程加載、標籤模式、多選等豐富功能。本文詳細講解安裝配置與實戰場景。

一、安裝與配置

# Composer 安裝
php composer.phar require kartik-v/yii2-widget-select2 "*"

# 或在 composer.json
"require": {
    "kartik-v/yii2-widget-select2": "@dev"
}

二、基礎用法:本地數據源

<?php
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use app\models\Company;

/* @var $form yii\widgets\ActiveForm */
/* @var $model app\models\Project */
?>
<?= $form->field($model, 'company_id')->widget(Select2::class, [
    'data' => ArrayHelper::map(Company::find()->active()->all(), 'id', 'name'),
    'language' => 'zh-TW',
    'options' => [
        'placeholder' => '請選擇或搜索公司...',
        'id' => 'project-company_id',
    ],
    'pluginOptions' => [
        'allowClear' => true,
        'minimumInputLength' => 1,      // 至少輸入 1 字符觸發搜索
        'maximumSelectionLength' => 1,  // 單選
    ],
    'pluginEvents' => [
        'select2:select' => 'function(e) { console.log("Selected:", e.params.data); }',
    ],
]) ?>

三、進階:AJAX 遠程加載(大數據集必備)

<?= $form->field($model, 'user_id')->widget(Select2::class, [
    'initValueText' => $model->user ? $model->user->username : '', // 編輯頁初始化顯示
    'options' => ['placeholder' => '搜索用戶...', 'multiple' => false],
    'pluginOptions' => [
        'allowClear' => true,
        'minimumInputLength' => 2,
        'ajax' => [
            'url' => \yii\helpers\Url::to(['user/ajax-search']),
            'dataType' => 'json',
            'delay' => 250,              // 防抖延遲
            'data' => new \yii\web\JsExpression('function(params) { return {q: params.term, page: params.page}; }'),
            'processResults' => new \yii\web\JsExpression('function(data) { return {results: data.items, pagination: {more: data.more}; } }'),
            'cache' => true,
        ],
        'templateResult' => new \yii\web\JsExpression('function(item) { return item.text; }'),
        'templateSelection' => new \yii\web\JsExpression('function(item) { return item.text; }'),
        'escapeMarkup' => new \yii\web\JsExpression('function(m) { return m; }'),
    ],
]) ?>

控制器端點實現

public function actionAjaxSearch() {
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    
    $q = \Yii::$app->request->get('q', '');
    $page = \Yii::$app->request->get('page', 1);
    $limit = 20;
    
    $query = User::find()->active();
    if ($q) {
        $query->andWhere(['or',
            ['like', 'username', $q],
            ['like', 'email', $q],
            ['like', 'real_name', $q],
        ]);
    }
    
    $total = $query->count();
    $users = $query->offset(($page - 1) * $limit)->limit($limit)->all();
    
    $items = [];
    foreach ($users as $user) {
        $items[] = [
            'id' => $user->id,
            'text' => $user->username . ' (' . $user->email . ')',
        ];
    }
    
    return [
        'items' => $items,
        'more' => ($page * $limit) < $total,
    ];
}

四、多選與標籤模式

<?= $form->field($model, 'tag_ids')->widget(Select2::class, [
    'data' => ArrayHelper::map(Tag::find()->all(), 'id', 'name'),
    'options' => [
        'placeholder' => '選擇或新建標籤...',
        'multiple' => true,
    ],
    'pluginOptions' => [
        'allowClear' => true,
        'tags' => true,                    // 允許創建新標籤
        'maximumSelectionLength' => 10,
        'tokenSeparators' => [',', ' '], // 分隔符自動創建
        'createTag' => new \yii\web\JsExpression('function(params) { return {id: params.term, text: params.term, new: true}; }'),
    ],
]) ?>

// 控制器保存時處理新標籤
$tagNames = $model->tag_ids; // 包含新舊 ID/名稱
foreach ($tagNames as $name) {
    if (!is_numeric($name)) { // 新標籤
        $tag = new Tag(['name' => $name]);
        $tag->save();
        $model->link('tags', $tag);
    }
}

五、主題樣式客製化

// AssetBundle 覆寫 CSS
namespace app\assets;
use yii\web\AssetBundle;

class Select2Asset extends AssetBundle {
    public $sourcePath = '@vendor/kartik-v/yii2-widget-select2/assets';
    public $css = ['select2.css'];
    public $depends = ['kartik\select2\Select2Asset'];
}

// 視圖中註冊
use app\assets\Select2Asset;
Select2Asset::register($this);

六、常見問題排查

  1. 搜索不觸發:檢查 minimumInputLength 設置;確認 AJAX URL 可訪問
  2. 編輯頁不顯示已選值:必須設置 initValueText 或使用 data 預載
  3. 多選值不保存:模型規則添加 [['tag_ids'], 'each', 'rule' => ['integer']];表單字段名用 tag_ids[]
  4. 樣式衝突:Select2 需 Bootstrap 3/4/5 對應版本 CSS,勿重複引入
  5. 中文搜索:確保資料庫與連接編碼為 utf8mb4;JS 端無需特殊處理

七、性能優化建議

  • 大數據集(>500 條)必須使用 AJAX 模式
  • 後端查詢添加索引:ALTER TABLE user ADD INDEX idx_username (username);
  • 啟用 'cache' => true 減少重複請求
  • 合理設置 delay (250-300ms) 平衡體驗與服務器壓力
  • 考慮使用 minimumInputLength: 2 避免短查詢全表掃描

Select2 配合 Yii2 強大的 ActiveForm 和模型綁定,能快速構建專業級的下拉選擇體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved