Select2 Widget Select2.php

Latest Stable Version Total Downloads Monthly Downloads Daily Downloads
Thankful to Krajee!
to get more out of us.

NOTE: This extension depends on the yiisoft/yii2-bootstrap extension. Check the composer.json for this extension's requirements and dependencies that may be updated by composer.

The Select2 widget is a Yii 2 wrapper for the Select2 jQuery plugin. This input widget is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results. The widget is specially styled for Bootstrap 3. The widget allows graceful degradation to a normal HTML select or text input, if the browser does not support JQuery. You can setup model validation rules for a model attribute that uses Select2 widget for input like any other field.

New release v2.0: The widget has been revamped and upgraded to v2.0 to implement Select2 plugin release v4.0. Select2 release v4.0 is a major rewrite over Select2 v3.x and hence quite a few enhancements or changes should be expected. The following new functionalities and changes should be expected with this release.

  • New theme property that allows you to set themes in Select2 to style your widget.

  • A brand new theme by Krajee Select2::THEME_KRAJEE is now available and specially styled for yii2-widget-select2. This will help achieve various widget specific enhancements and features. This theme matches the bootstrap 3 styling with various enhancements.

  • Additional themes provided in form of Select2::THEME_DEFAULT, Select2::THEME_CLASSIC, and Select2::THEME_BOOTSTRAP. One can add their own custom theme and configure the widget

  • No more query plugin property needed. It is also not mandatory to configure data even if you have not set tags or query or ajax. Widget will intelligently evaluate the properties and default list values.

  • Enhanced tagging support. Use it just like a multiple select but with taggable values. In addition, one can create tags on the fly.

  • Enhanced ajax support. Refer the usage demos for details.

  • The initSelection method of Select2 3.5.x plugin is obsolete/removed. New initValueText property is been provided with the Select2 widget to cater to this (e.g. for ajax based loading).

  • Ability to disable selective option values in the Select2 dropdown OR add HTML attributes to selective options.

  • Enhancement by Krajee to disable the search box to use like a normal select.

  • Enhancements to locales and translations. Allow multiple language Select2 widgets on the same page.

Important

This widget can be also installed in isolation outside this bundle if needed. In addition to using via \kartik\widgets namespace, this widget can be also installed from the yii2-widget-select2 repository and can also be accessed via \kartik\select2\Select2 namespace.

The widget supports all parameters that one would pass for any Yii Input Widget. The additional parameter settings specially available for the Select2 widget configuration are:
  • data: array the select option data items. The array keys are option values, and the array values are the corresponding option labels. The array can also be nested (i.e. some array values are arrays too). For each sub-array, an option group will be generated whose label is the key associated with the sub-array. If you have a list of data models, you may convert them into the format described above using \yii\helpers\ArrayHelper::map().

  • language: string the locale ID (e.g. fr, de) for the language to be used by the Select2 Widget. If this property not set, then the current application language will be used (i.e. Yii::$app->language). Note:With release v4.0 of the Select2 plugin, you can have multiple language Select2 widgets on the same page.

  • theme: string the theme to be used for the Select2 widget. Defaults to Select2::THEME_KRAJEE. The following themes are available inbuilt with this widget:

    • Select2::THEME_KRAJEE or 'krajee': This theme has been created specially by Krajee which matches bootstrap 3 styles and adds various enhancements to work with Yii2 Select2 widget.

    • Select2::THEME_DEFAULT or 'default': The default inbuilt Select2 theme.

    • Select2::THEME_CLASSIC or 'classic': The classic Select2 theme.

    • Select2::THEME_BOOTSTRAP or 'bootstrap': The bootstrap 3 Select2 theme from github.com/fk/select2-bootstrap-theme.

    You can define your own custom theme by setting this property and rendering the theme specific CSS on your page. Refer to the Select2 plugin documentation for details on creating themes.

  • initValueText: string, the text to displayed in Select2 widget for the initial value. This is useful and applicable when you are using the widget with ajax loaded data AND/OR you are not providing the data. Check the ajax usage section for an example.

  • hideSearch: bool whether to hide the search control and display a simple select. Defaults to false.

  • addon: array Adds an input group addon to the Select2 widget

    • prepend: array the prepend addon configuration, where you set the following keys:

      • content: string the prepend addon content

      • asButton: boolean whether the addon is a button or button group. Defaults to false.

    • append: array the append addon configuration, where you set the following keys:

      • content: string the append addon content

      • asButton: boolean whether the addon is a button or button group. Defaults to false.

    • groupOptions: array HTML options for the input group

    • contentBefore: string content placed before addon. This is not HTML encoded.

    • contentAfter: string content placed after addon. This is not HTML encoded.

  • size: string size of the Select2 input, must be one of the size constants

    • LARGE or 'lg'

    • MEDIUM or 'md'

    • SMALL or 'sm'

  • disabled: boolean whether the input widget is to be entirely disabled. Defaults to false.

  • readonly: boolean whether the input widget is to be entirely readonly. Defaults to false.

  • options: array the HTML attributes for the input tag. The following options are important:

    • multiple: boolean whether multiple or single item should be selected.

    • placeholder or prompt: string placeholder text for the select item. To set a placeholder, you must set one of placeholder or prompt.

  • pluginLoading: boolean, whether to show a loading progress indicator in place of the input before plugin is completely loaded. Defaults to true.

  • pluginOptions: array the Select2 JQuery plugin options. Refer the plugin options documentation for details. The widget automatically reacts to the following pluginOptions

    • data: If you set this within the pluginOptions, it will override the data set at widget level. A hidden text input will be rendered instead of a HTML select in this case.

    • ajax: If you wish to use ajax set this option instead of a separate ajax function.

    • tags: If you wish to display tags selection, use this option. Usually you must set this to true with the options['multiple'] enabled. However you can set this to true to add custom tags for both single and multiple select. When options['multiple'] is enabled, the tags work very similar to a multiple select input and reads and sends data as an array.

  • pluginEvents: array the Select2 JQuery events. You must define events in event-name => event-function format. All events will be stacked in the sequence. Refer the plugin options documentation for details. For example:

    pluginEvents = [
        "change" => "function() { log('change'); }",
        "select2:opening" => "function() { log('select2:opening'); }",
        "select2:open" => "function() { log('open'); }",
        "select2:closing" => "function() { log('close'); }",
        "select2:close" => "function() { log('close'); }",
        "select2:selecting" => "function() { log('selecting'); }",
        "select2:select" => "function() { log('select'); }",
        "select2:unselecting" => "function() { log('unselecting'); }",
        "select2:unselect" => "function() { log('unselect'); }"
    ];
    

Basic usage of single and multiple select with Select2 widget with model, ActiveForm or without a model.

 

Usage with ActiveForm and model. Check the model and active form validation outcomes & messages styled via bootstrap contextual classes. For example select a value and unselect it using the clear icon.


 

With a model and without ActiveForm


 

Without model and implementing a multiple select


 

A disabled select2 list input

use kartik\widgets\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
]);

Advanced usages of the Select2 widget.

 

Templating example of formatting each list element


 

Disable specific values for selection (for example disable third and fourth value).


Using a select2 widget inside a modal dialog.


 

Render a simple select by hiding the search control.


 
 

Using localization. For example set the widget to use Russian language and French Language. You can use multiple widgets with different languages on the same page with release 4.0 of Select2 plugin.


 
 
 
 

Using themes. By default the widget uses the specially created theme by Krajee Select2::THEME_KRAJEE. You can use one of the other themes available: THEME_DEFAULT, THEME_CLASSIC or THEME_BOOTSTRAP, or build your own custom theme and set in here.

use kartik\widgets\Select2;
use yii\web\JsExpression;
use yii\bootstrap\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
    ],
    'header' => '<h4 style="margin:0; padding:0">Select2 Inside Modal</h4>',
    '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 Theme
echo Select2::widget([
    'name' => 'kv_theme_select2',
    'data' => $data,
    'theme' => Select2::THEME_KRAJEE, // this is the default if theme is not set
    'options' => ['placeholder' => 'Select a state ...', 'style' => 'width:343%;'],
    'pluginOptions' => [
        'allowClear' => true
    ],
]);// Classic Theme

// Bootstrap Theme
echo Select2::widget([
    'name' => 'kv_theme_select2',
    'data' => $data,
    'theme' => Select2::THEME_BOOTSTRAP,
    'options' => ['placeholder' => 'Select a state ...'],
    'pluginOptions' => [
        'allowClear' => true
    ],
]);// Classic Theme
echo Select2::widget([
    'name' => 'kv_theme_select3',
    'data' => $data,
    'theme' => Select2::THEME_CLASSIC,
    'options' => ['placeholder' => 'Select a state ...'],
    'pluginOptions' => [
        'allowClear' => true,
        'width' => '343%'
    ],
]);
// Default Theme
echo Select2::widget([
    'name' => 'kv_theme_select4',
    'data' => $data,
    'theme' => Select2::THEME_DEFAULT,
    'options' => ['placeholder' => 'Select a state ...'],
    'pluginOptions' => [
        'allowClear' => true,
        'width' => '343%'
    ],
]);

An example demonstrating the various sizes of Select 2 widget with orientation for right to left languages.

Single Select

 
 
 

Multi Select

 
 
 

Single Select (RTL)

 
 
 

Multi Select (RTL + Addon)

 
 
 
use kartik\widgets\Select2;
// Various Select2 Sizes
echo Select2::widget([
    'name' => 'kv-state-200',
    'data' => $data,
    'size' => Select2::SMALL,
    'options' => ['placeholder' => 'Select a state ...'],
    'pluginOptions' => [
        'allowClear' => true
    ],
]) .
Select2::widget([
    'name' => 'kv-state-210',
    'data' => $data,
    'size' => Select2::MEDIUM,
    'options' => ['placeholder' => 'Select a state ...'],
    'pluginOptions' => [
        'allowClear' => true
    ],
]) .
Select2::widget([
    'name' => 'kv-state-220',
    'data' => $data,
    'size' => Select2::LARGE,
    'options' => ['placeholder' => 'Select a state ...'],
    'pluginOptions' => [
        'allowClear' => true
    ],
]) .
Select2::widget([
    'name' => 'kv-state-230',
    'data' => $data,
    'size' => Select2::SMALL,
    'options' => ['placeholder' => 'Select a state ...', 'multiple' => true],
    'pluginOptions' => [
        'allowClear' => true
    ],
]) .
Select2::widget([
    'name' => 'kv-state-240',
    'data' => $data,
    'size' => Select2::MEDIUM,
    'options' => ['placeholder' => 'Select a state ...', 'multiple' => true],
    'pluginOptions' => [
        'allowClear' => true
    ],
]) .
Select2::widget([
    'name' => 'kv-state-250',
    'data' => $data,
    'size' => Select2::LARGE,
    'options' => ['placeholder' => 'Select a state ...', 'multiple' => true],
    'pluginOptions' => [
        'allowClear' => true
    ],
]);
$addon = [
    'prepend' => [
        'content' => Html::icon('globe')
    ],
    'append' => [
        'content' => Html::button(Html::icon('map-marker'), [
                'class' => 'btn btn-primary',
                'title' => 'Mark on map',
                'data-toggle' => 'tooltip'
            ]),
        'asButton' => true
    ]
];
// FOR RTL orientation with addon, set 'options' => ['dir' => 'rtl'] in all of the above
// and set addon property to $addon

Tagging support for Select2 widget including ability to add one's own tags. This typically is effective with options['multiple'] set to true. However, you can use it for single tagging as well. You must write your own server/ajax code for saving these added values and/or refreshing the select2 via javascript or page refresh.

 

Tagging support (Multiple). Allow automatic tokenization and add choices automatically as the user is typing into the search field. Try typing in the search field and entering a space or a comma set as tokenSeparators.


 

Tagging support for a single select. Allow automatic tokenization and add choices automatically as the user is typing into the search field. You can create option values even for a single select on the fly in the search box. However, you must write your own server/ajax code for saving these added values and/or refreshing the select2 via javascript or page refresh.

use kartik\widgets\Select2;
$data = [
    "red" => "red",
    "green" => "green",
    "blue" => "blue",
    "orange" => "orange",
    "white" => "white",
    "black" => "black",
    "purple" => "purple",
    "cyan" => "cyan",
    "teal" => "teal"
];

// Tagging support Multiple
echo '<label class="control-label">Tag Multiple</label>';
echo Select2::widget([
    'name' => 'color_1',
    'value' => ['red', 'green'], // initial value
    'data' => $data,
    'options' => ['placeholder' => 'Select a color ...', 'multiple' => true],
    'pluginOptions' => [
        'tags' => true,
        'maximumInputLength' => 10
    ],
]);

// Tagging support Single
echo '<label class="control-label">Tag Single</label>';
echo Select2::widget([
    'name' => 'color_1',
    'value' => 'red', // initial value
    'data' => $data,
    'options' => ['placeholder' => 'Select a color ...'],
    'pluginOptions' => [
        'tags' => true,
        'tokenSeparators' => [',', ' '],
        'maximumInputLength' => 10
    ],
]);

An example demonstrating the use of Select2 loaded with a remote ajax action querying a large number of records.

 

Fetching and querying large data using ajax. For example type cal. The initial value display text can be set via initValueText.

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

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

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

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

echo $form->field($model, 'city')->widget(Select2::classname(), [
    'initValueText' => $cityDesc, // set the initial display text
    'options' => ['placeholder' => 'Search for a city ...'],
    'pluginOptions' => [
        'allowClear' => true,
        'minimumInputLength' => 3,
        '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('name LIKE "%' . $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;
}

An advanced example that combines AJAX based loading, querying a remote repository, and templating to display formatted results.

 

Querying a remote repository via AJAX with output results formatted via templates. This example also includes pagination of results and infinite scrolling of displayed results. You can search for example yii2-grid OR yii2-widgets.

$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 += '<h5>' + repo.description + '</h5>';
    }
    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'),
    ],
]);

An example demonstrating the use of input group addons with Select2. You can prepend or append addons or use both as seen in the example.

 
use kartik\widgets\Select2;
use kartik\helpers\Html;

echo Select2::widget([
    'name' => 'state_200',
    'data' => $us_states,
    'size' => Select2::MEDIUM,
    'addon' => [
        'prepend' => [
            'content' => Html::icon('globe')
        ],
        'append' => [
            'content' => Html::button(Html::icon('map-marker'), [
                'class' => 'btn btn-primary', 
                'title' => 'Mark on map', 
                'data-toggle' => 'tooltip'
            ]),
            'asButton' => true
        ]
    ]
]);