Select2 Widget Select2.php

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 an enhanced Yii2 wrapper for the Select2 jQuery plugin by Igor Vaynberg. 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.

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:
  • 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: This setting is applied for the entire view object by the plugin. So you cannot have multi-language Select2 widgets on the same view page.

  • 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'

  • 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().

  • 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: string placeholder text for the select item.

  • 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 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.

    • query: Similar to data this will override the source for list data. 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. A hidden text input will be rendered instead of a HTML select in this case.

    • tags: If you wish to display tags selection, use this option. It will override any data set at widget level. You can set the tokenSeparators array or tokenizer function to manage tag output the way you want. A hidden text input will be rendered instead of a HTML select in this case.

    • Note

      When using tags with Select2, the tag output is not stored as an array, but a delimited (default comma separated) list. To show the preselected values when in edit mode for your forms, you need to assign the value of the select2 attribute as a delimited string. For example, the following method will set the 'color' attribute to have 'red, black, cyan' preselected.
      // setup the following to get the existing data from database
      $model->color = 'red, black, cyan';
      
      // or if the data is an array you can preselect the tags like this
      $model->color = implode(', ', ["red", "black", "cyan"]);
      
      echo Select2::widget([
      	'model' => $model,
      	'attribute' => 'color',
      	'options' => ['placeholder' => 'Select a color ...', 'class'=>'form-control'],
      	'pluginOptions' => [
      		'tags' => ["red", "green", "white", "black", "purple", "cyan"],
      		'maximumInputLength' => 10
      	],
      ]);
      
  • 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 documentation for details. For example:

    pluginEvents = [
        "change" => "function() { log("change"); }",
        "open" => "function() { log("open"); }",
        "select2-opening" => "function() { log("select2-opening"); }",
    ];
    

 

Usage with ActiveForm and model


 

With a model and without ActiveForm


 

Without model and implementing a multiple select


 

A disabled select2 list input


 

Templating example of formatting each list element


 

Tagging support


Various Select 2 Sizes

 
 
 
 
 
 
use kartik\widgets\Select2

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

// With a model and without ActiveForm
echo Select2::widget([
    'model' => $model, 
    'attribute' => 'state_2',
    'data' => array_merge(["" => ""], $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 ...', 
        'class'=>'form-control', 
        'multiple' => true
    ],
]);

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

// 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' =>  array_merge(["" => ""], $data),
    'options' => ['placeholder' => 'Select a state ...', 'class'=>'form-control'],
    'pluginOptions' => [
        'formatResult' => new JsExpression('format'),
        'formatSelection' => new JsExpression('format'),
        'escapeMarkup' => $escape,
        'allowClear' => true    
    ],
]);

// Tagging support
echo '<label class="control-label">Tag Content</label>';
echo Select2::widget([
    'name' => 'color_1', 
    'options' => ['placeholder' => 'Select a color ...', 'class'=>'form-control'],
    'pluginOptions' => [
        'tags' => ["red", "green", "blue", "orange", "white", "black", "purple", "cyan", "teal"],
        'maximumInputLength' => 10
    ],
]);

// Various Select2 Sizes
$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
    ]
];
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,
    'addon' => $addon,
    'options' => ['placeholder' => 'Select a state ...', 'multiple'=>true],
    'pluginOptions' => [
        'allowClear' => true
    ],
]) .
Select2::widget([
    'name' => 'kv-state-240',
    'data' => $data,
    'size'=>Select2::MEDIUM,
    'addon' => $addon,
    'options' => ['placeholder' => 'Select a state ...', 'multiple'=>true],
    'pluginOptions' => [
        'allowClear' => true
    ],
]) .
Select2::widget([
    'name' => 'kv-state-250',
    'data' => $data,
    'size'=>Select2::LARGE,
    'addon' => $addon,
    'options' => ['placeholder' => 'Select a state ...', 'multiple'=>true],
    'pluginOptions' => [
        'allowClear' => true
    ],
]);

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

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

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

// Script to initialize the selection based on the value of the select2 element
$initScript = <<< SCRIPT
function (element, callback) {
    var id=\$(element).val();
    if (id !== "") {
        \$.ajax("{$url}?id=" + id, {
            dataType: "json"
        }).done(function(data) { callback(data.results);});
    }
}
SCRIPT;

// The widget
echo $form->field($model, 'city')->widget(Select2::classname(), [
    'options' => ['placeholder' => 'Search for a city ...'],
    'pluginOptions' => [
        'allowClear' => true,
        'minimumInputLength' => 3,
        'ajax' => [
            'url' => $url,
            'dataType' => 'json',
            'data' => new JsExpression('function(term,page) { return {search:term}; }'),
            'results' => new JsExpression('function(data,page) { return {results:data.results}; }'),
        ],
        'initSelection' => new JsExpression($initScript)
    ],
]);

/*************
 * Controller
 ************/
public function actionCitylist($search = null, $id = null) {
    $out = ['more' => false];
    if (!is_null($search)) {
        $query = new Query;
        $query->select('id, name AS text')
            ->from('city')
            ->where('name LIKE "%' . $search .'%"')
            ->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];
    }
    else {
        $out['results'] = ['id' => 0, 'text' => 'No matching records found'];
    }
    echo Json::encode($out);
}

An example demonstrating the use of Select2 widget inside a Bootstrap modal window.

use kartik\widgets\Select2;
use yii\bootstrap\Modal;
Modal::begin([
    'options'=>['id'=>'kartik'],
    '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' => array_merge(["" => ""], $data),
    'options' => ['placeholder' => 'Select a state ...'],
    'pluginOptions' => [
        'allowClear' => true
    ],
]);
Modal::end();

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
        ]
    ]
]);