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); }',
],
]) ?>
<?= $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);
minimumInputLength 設置;確認 AJAX URL 可訪問initValueText 或使用 data 預載[['tag_ids'], 'each', 'rule' => ['integer']];表單字段名用 tag_ids[]ALTER TABLE user ADD INDEX idx_username (username);'cache' => true 減少重複請求delay (250-300ms) 平衡體驗與服務器壓力minimumInputLength: 2 避免短查詢全表掃描Select2 配合 Yii2 強大的 ActiveForm 和模型綁定,能快速構建專業級的下拉選擇體驗。