yii2-widget-select2是基于jquery和bootstrap的下拉列表,支持搜索、远程数据集调用、无限下拉等功能。

安装

$ php composer.phar require kartik-v/yii2-widget-select2 "@dev"

或添加:

"kartik-v/yii2-widget-select2": "dev-master"

到composer.json文件。

基本使用

use kartik\select2\Select2

// Usage with ActiveForm and model
echo $form->field($model, 'state_1')->widget(Select2::classname(), [
'data' => $data,
'options' => ['placeholder' => 'Select a state ...'],
'pluginOptions' => [
'allowClear' => true
],
]);

// With a model and without ActiveForm
echo Select2::widget([
'model' => $model,
'attribute' => 'state_2',
'data' => $data,
'options' => ['placeholder' => 'Select a state ...'],
'pluginOptions' => [
'allowClear' => true
],
]);

// Without model and implementing a multiple select
echo '<label class="control-label">Provinces</label>';
echo Select2::widget([
'name' => 'state_10',
'data' => $data,
'options' => [
'placeholder' => 'Select provinces ...',
'multiple' => true
],
]);

// A disabled select2 list input
echo '<label class="control-label">State</label>';
echo Select2::widget([
'name' => 'state_11',
'data' => $data,
'disabled' => true
]);

高级用法

use kartik\select2\Select2;
use yii\web\JsExpression;
use yii\bootstrap4\Modal;

// Templating example of formatting each list element
$url = \Yii::$app->urlManager->baseUrl . '/images/flags/';
$format = <<< SCRIPT
function format(state) {
if (!state.id) return state.text; // optgroup
src = '$url' + state.id.toLowerCase() + '.png'
return '<img class="flag" src="' + src + '"/>' + state.text;
}
SCRIPT;
$escape = new JsExpression("function(m) { return m; }");
$this->registerJs($format, View::POS_HEAD);
echo '<label class="control-label">Provinces</label>';
echo Select2::widget([
'name' => 'state_12',
'data' => $data,
'options' => ['placeholder' => 'Select a state ...'],
'pluginOptions' => [
'templateResult' => new JsExpression('format'),
'templateSelection' => new JsExpression('format'),
'escapeMarkup' => $escape,
'allowClear' => true
],
]);

// Disable specific values for selection (for example disable third and fourth value)
echo Select2::widget([
'name' => 'kv-type-01',
'data' => [1 => "First", 2 => "Second", 3 => "Third", 4 => "Fourth", 5 => "Fifth"],
'options' => [
'placeholder' => 'Select a type ...',
'options' => [
3 => ['disabled' => true],
4 => ['disabled' => true],
]
],
]);

// Using a select2 widget inside a modal dialog
Modal::begin([
'options' => [
'id' => 'kartik-modal',
'tabindex' => false // important for Select2 to work properly
],
'title' => 'Select2 Inside Modal',
'toggleButton' => ['label' => 'Show Modal', 'class' => 'btn btn-lg btn-primary'],
]);
echo Select2::widget([
'name' => 'state_40',
'data' => $data,
'options' => ['placeholder' => 'Select a state ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
Modal::end();

// Render a simple select by hiding the search control.
echo '<label class="control-label">Status</label>';
echo Select2::widget([
'name' => 'status',
'hideSearch' => true,
'data' => [1 => 'Active', 2 => 'Inactive'],
'options' => ['placeholder' => 'Select status...'],
'pluginOptions' => [
'allowClear' => true
],
]);

// Localization - set widget language to translate messages in your local language
// russian
echo Select2::widget([
'name' => 'kv_lang_select1',
'language' => 'ru',
'data' => $data,
'options' => ['placeholder' => 'Выберите состояние ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
// french
echo Select2::widget([
'name' => 'kv_lang_select2',
'language' => 'fr',
'data' => $data,
'options' => ['placeholder' => 'Sélectionnez un état ...'],
'pluginOptions' => [
'allowClear' => true
],
]);

// Using themes
// Krajee Bootstrap 4.x Theme
echo Select2::widget([
'bsVersion' => '4.x',
'name' => 'kv_theme_select1a',
'data' => $data,
'theme' => Select2::THEME_KRAJEE, // this is the default if theme is not set
'options' => ['placeholder' => 'Select a state ...'],
'pluginOptions' => [
'allowClear' => true
],
]);

// Krajee Bootstrap 4.x / 3.x Theme
echo Select2::widget([
'bsVersion' => '4.x / 3.x',
'name' => 'kv_theme_select1b',
'data' => $data,
'theme' => Select2::THEME_KRAJEE, // this is the default if theme is not set
'options' => ['placeholder' => 'Select a state ...'],
'pluginOptions' => [
'allowClear' => true
],
]);

<div class="row">
<div class="col-sm-6">
<label>Theme MATERIAL (Single)</label>
<?php
echo Select2::widget([
'name' => 'kv_theme_material_1',
'data' => $data,
'theme' => Select2::THEME_MATERIAL,
'options' => ['placeholder' => 'Select a state ...', 'autocomplete' => 'off'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
<div class="col-sm-6">
<label>Theme MATERIAL (Multiple)</label>
<?php
echo Select2::widget([
'name' => 'kv_theme_material_2',
'data' => $data,
'theme' => Select2::THEME_MATERIAL,
'options' => ['placeholder' => 'Select a state ...', 'multiple' => true, 'autocomplete' => 'off'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
</div>
<br>
<div class="row">
<div class="col-sm-6">
<label>Theme BOOTSTRAP (Single)</label>
<?php
echo Select2::widget([
'name' => 'kv_theme_bootstrap_1',
'data' => $data,
'theme' => Select2::THEME_BOOTSTRAP,
'options' => ['placeholder' => 'Select a state ...', 'autocomplete' => 'off'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
<div class="col-sm-6">
<label>Theme BOOTSTRAP (Multiple)</label>
<?php
echo Select2::widget([
'name' => 'kv_theme_bootstrap_2',
'data' => $data,
'theme' => Select2::THEME_BOOTSTRAP,
'options' => ['placeholder' => 'Select a state ...', 'multiple' => true, 'autocomplete' => 'off'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
</div>
<br>
<div class="row">
<div class="col-sm-6">
<label>Theme CLASSIC (Single)</label>
<?php
echo Select2::widget([
'name' => 'kv_theme_classic_1',
'data' => $data,
'theme' => Select2::THEME_CLASSIC,
'options' => ['placeholder' => 'Select a state ...', 'autocomplete' => 'off'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
<div class="col-sm-6">
<label>Theme CLASSIC (Multiple)</label>
<?php
echo Select2::widget([
'name' => 'kv_theme_classic_2',
'data' => $data,
'theme' => Select2::THEME_CLASSIC,
'options' => ['placeholder' => 'Select a state ...', 'multiple' => true, 'autocomplete' => 'off'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
</div>
<br>
<div class="row">
<div class="col-sm-6">
<label>Theme DEFAULT (Single)</label>
<?php
echo Select2::widget([
'name' => 'kv_theme_default_1',
'data' => $data,
'theme' => Select2::THEME_DEFAULT,
'options' => ['placeholder' => 'Select a state ...', 'autocomplete' => 'off'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
<div class="col-sm-6">
<label>Theme DEFAULT (Multiple)</label>
<?php
echo Select2::widget([
'name' => 'kv_theme_default_2',
'data' => $data,
'theme' => Select2::THEME_DEFAULT,
'options' => ['placeholder' => 'Select a state ...', 'multiple' => true, 'autocomplete' => 'off'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
</div>

Ajax异步加载

/*******
* View
******/

// The controller action that will render the list
$url = \yii\helpers\Url::to(['city-list']);

// The widget
use kartik\select2\Select2; // or kartik\select2\Select2
use yii\web\JsExpression;
use app\models\City;

// Get the initial city description
$cityDesc = empty($model->city) ? '' : City::findOne($model->city)->description;

echo $form->field($model, 'city')->widget(Select2::classname(), [
'options' => ['multiple'=>true, 'placeholder' => 'Search for a city ...'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 3,
'language' => [
'errorLoading' => new JsExpression("function () { return 'Waiting for results...'; }"),
],
'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(city) { return city.text; }'),
'templateSelection' => new JsExpression('function (city) { return city.text; }'),
],
]);

/*************
* Controller
************/
public function actionCityList($q = null, $id = null) {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$out = ['results' => ['id' => '', 'text' => '']];
if (!is_null($q)) {
$query = new Query;
$query->select('id, name AS text')
->from('city')
->where(['like', 'name', $q])
->limit(20);
$command = $query->createCommand();
$data = $command->queryAll();
$out['results'] = array_values($data);
}
elseif ($id > 0) {
$out['results'] = ['id' => $id, 'text' => City::find($id)->name];
}
return $out;
}

Ajax和模板

$formatJs = <<< 'JS'
var formatRepo = function (repo) {
if (repo.loading) {
return repo.text;
}
var markup =
'<div class="row">' +
'<div class="col-sm-5">' +
'<img src="' + repo.owner.avatar_url + '" class="img-rounded" style="width:30px" />' +
'<b style="margin-left:5px">' + repo.full_name + '</b>' +
'</div>' +
'<div class="col-sm-3"><i class="fa fa-code-fork"></i> ' + repo.forks_count + '</div>' +
'<div class="col-sm-3"><i class="fa fa-star"></i> ' + repo.stargazers_count + '</div>' +
'</div>';
if (repo.description) {
markup += '<p>' + repo.description + '</p>';
}
return '<div style="overflow:hidden;">' + markup + '</div>';
};
var formatRepoSelection = function (repo) {
return repo.full_name || repo.text;
}
JS;

// Register the formatting script
$this->registerJs($formatJs, View::POS_HEAD);

// script to parse the results into the format expected by Select2
$resultsJs = <<< JS
function (data, params) {
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
}
JS;
// render your widget
echo Select2::widget([
'name' => 'kv-repo-template',
'value' => '14719648',
'initValueText' => 'kartik-v/yii2-widgets',
'options' => ['placeholder' => 'Search for a repo ...'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 1,
'ajax' => [
'url' => "https://api.github.com/search/repositories",
'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'),
],
]);

参考

​https://github.com/kartik-v/yii2-widget-select2​​​ https://demos.krajee.com/widget-details/select2#installation
https://select2.org/selections