Yii2, set default value for select2 widget - yii2

use kartik\widgets\Select2;
echo Select2::widget([
'model' => $myModel,
'name' => 'company[]',
'options' => [
'placeholder' => 'Select a company ...',
'multiple' => true,
],
'value' => 6, //doesn't work
'initValueText' => '6', //doesn't work
'pluginOptions' => [
'allowClear' => true,
'ajax' => [
'url' => Url::to(['/company/default/get-company-list']),
'dataType' => 'json',
'data' => new JsExpression('function(term,page) {
return {term : term.term};
}'),
'results' => new JsExpression('function(data,page) {return {results:data.results}; }'),
],
'initSelection' => new JsExpression('function(element, callback) {
$(element).val(6); //doen't work
callback({"text" : "Vendor B", "id" : 6}); // it does only set text, not id
}'),
],
]);
... many many select2 form below too, that named 'company[]'
After form submit, if user come back to this page, I want to set what user selected as default.
How can I set default value for Select2 widget?

When you update the model, it will automatically have the last selected value.
$myModel = new \app\models\myModel;
$myModel->attributes = \Yii::$app->request->post('myModel');

Related

Kartik Select2 error when try to use it with ajax

I've used kartiks select2 many time with ajax before. Now when I tried to implement it again this error is thrown in console:
jquery.js:3850 Uncaught Error: Option 'ajax' is not allowed for Select2 when attached to a <select> element.
There is no other errors. My implementation looks like:
<?php
echo $form->field($model, 'destination_from')->widget(Select2::class, [
'initValueText' => isset($_GET['MassManagementSearch']) ? $_GET['MassManagementSearch']['destination_from'] : [], // set the initial display text
'options' => [
'placeholder' => 'Destination from ...',
'multiple' => true
],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 3,
'language' => [
'errorLoading' => new JsExpression("function () { return 'Waiting for results...'; }"),
],
'ajax' => [
'url' => \yii\helpers\Url::to(['destination-from']),
'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; }'),
],
]); ?>
EDIT This my select2 version in composer.json:
"kartik-v/yii2-widget-select2": "#dev"

Transfer of date to the database

the beginner in Yii, connected DatePicker in GridView, but when I set date, in the Database nothing changes, there are old values. I do not understand how to make so that data came to the Database.
View:
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
'avito_login',
'avito_password',
'Region',
"City",
"legal_entity",
"manager_contact_phone",
"avito_user_id",
"teg",
[
'label' => 'Date begin subscription',
'value' => function ($model, $key, $value) {
return \kartik\date\DatePicker::widget([
'name' => 'date_subscription',
'model' => $model,
'value' => $model->date_subscription,
'type' => DatePicker::TYPE_INPUT,
'pluginOptions' => [
'format' => 'yyyy-mm-dd',
'autoclose' => true,
],
'pluginEvents'=>[
'changeDate'=>"function(e) {[jQuery.ajax({ url: '/admin/clients/date-subscription', type: 'post', contentType: 'application/x-www-form-urlencoded', dataType: 'html', data: { data: this.value }, success: function (data) { alert(data) });
}",
],
]);
},
'format' => 'raw',
],
?>
Controller
public function actionDateSubscription()
{
$datesubscription = Yii::$app->request->post('date_subscription');
}
Nothing occurs, fields with date stopped being active
You basically need to bind an ajax call to the datepicker which sends the date to the server controller/action which updates the new date into the database and sends the response back to the frontend, where if everything is OK it refreshes the gridview to reflect the new date.
Here is a similar answer which uses toggle-switch to update the database status column, you can have the general idea about the process.
The only thing that is different in your case is that you have to use the pluginEvents option to specify the changeDate event and bind the ajax call to that event like below
[
'label' => 'Date begin subscription',
'value' => function ($model, $key, $value) {
return \kartik\date\DatePicker::widget([
'name' => 'date_subscription',
'model' => $model,
'value' => $model->date_subscription,
'type' => DatePicker::TYPE_INPUT,
'pluginOptions' => [
'format' => 'yyyy-mm-dd',
'autoclose' => true,
],
'pluginEvents'=>[
'changeDate'=>"function(e) { //call your ajax fuction here }",
]
]);
},
'format' => 'raw',
],
Note: if you have aloowed date_subscription to be empty/null then make sure you call the ajax in the clearDate event too along with the changeDate.
For a complete list of events See the DOCS

Show Select2 option as selected

<?=
$form->field($model, 'contributors')->widget(Select2::classname(), [
'initValueText' => '',
'options' => ['placeholder' => 'Search for a Contributor ...'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 3,
'ajax' => [
'url' => \yii\helpers\Url::to(['data2']),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(contributor_id) { return contributor_id.text; }'),
'templateSelection' => new JsExpression('function (contributor_id) { return contributor_id.text; }'),
],
])->label('Contributors');
?>
How to show selected value, now it shows id as a selected.
please anyone help me.
UPDATE
Sorry for late reply didn't notice you need to set the initial text for the select2 as you are using the ajax option so you should use the option initValueText. According to the docs
initValueText : 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.
So you need to use it like below add this line inside your controller action and pass it to the view or add it inside the view before the select2
$contributorName = empty($model->contributors) ? '' : Contributors::findOne($model->contributors)->name;
<?=
$form->field($model, 'contributors')->widget(Select2::classname(), [
'initValueText' => $contributorName, // set the initial display text
'options' => ['placeholder' => 'Search for a Contributor ...'],
'data'=>yii\helpers\ArrayHelper::map(Contributors::find()->all(),'id','name')
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 3,
'ajax' => [
'url' => \yii\helpers\Url::to(['data2']),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(contributor_id) { return contributor_id.text; }'),
'templateSelection' => new JsExpression('function (contributor_id) { return contributor_id.text; }'),
],
])->label('Contributors');
?>
You need to provide the data option to the set of values from which the selected value would be shown you want the text to be shown instead of the id, provide the data options in form of an array with key=>value pairs.
Looking at your code you want to show the contributor name against the id in database table so you should use ArrayHelper:map() along with querying your Contributors model, see below and update your field names for the Contributors model/table inside the ArrayHelper::map()
<?=
$form->field($model, 'contributors')->widget(Select2::classname(), [
'options' => ['placeholder' => 'Search for a Contributor ...'],
'data'=>yii\helpers\ArrayHelper::map(Contributors::find()->all(),'id','name')
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 3,
'ajax' => [
'url' => \yii\helpers\Url::to(['data2']),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(contributor_id) { return contributor_id.text; }'),
'templateSelection' => new JsExpression('function (contributor_id) { return contributor_id.text; }'),
],
])->label('Contributors');
?>

Yii2: Select2, How to set initValueText in Gridview or Tabularform?

I need to set initValueText for Select2, which is in loop, like gridview or Tabularform. but I don't know how to set right value for each.
<?= TabularForm::widget([
'dataProvider' => $dataProvider,
'form' => $form,
'actionColumn' => false,
'checkboxColumn' => false,
'attributeDefaults' => [
'type' => TabularForm::INPUT_RAW,
],
'attributes' => [
'test' => [
'type' => Form::INPUT_WIDGET,
'widgetClass' => Select2::className(),
'options' => [
'name' => 'test',
'options' => [
'class' => 'test-to-select',
],
'pluginOptions' => [
'allowClear' => true,
'minimumResultsForSearch' => 'Infinity',
'ajax' => [
'url' => Url::to(['/test/get-list']),
'dataType' => 'json',
'data' => new JsExpression('function(term,page) {
return {term : term.term};
}'),
'results' => new JsExpression('function(data,page) {
return {results:data.results};
}'),
'cache' => true
]
],
'initValueText' => 'Selected Text' /// how can I set this in gridview or Tabularform?
],
],
]
]) ?>
Of course this is not working,
'initValueText' => function($model){
retur $model->textValue;
}
Any help would be appreciated.
Into tabularform if you want dynamic initValueText, you can use options closure in this manner:
'test' => [
'type' => Form::INPUT_WIDGET,
'widgetClass' => Select2::className(),
'options' => function($model, $key, $index, $widget) {
$initValueText = empty($model['textValue']) ? '' : $model['textValue'];
return [
'name' => 'test',
'options' => [
'class' => 'test-to-select',
],
'initValueText' => $initValueText,
'pluginOptions' => [
'allowClear' => true,
'minimumResultsForSearch' => 'Infinity',
'ajax' => [
'url' => Url::to(['/test/get-list']),
'dataType' => 'json',
'data' => new JsExpression('function(term,page) {
return {term : term.term};
}'),
'results' => new JsExpression('function(data,page) {
return {results:data.results};
}'),
'cache' => true
]
],
];
}
],
If for example attribute for city, so try this..
$cityDesc = empty($model->city) ? '' : City::findOne($model->city)->description;
'initValueText' => $cityDesc, // set the initial display text
For init value first assign value to $model attribute, if you should not assign so this attribute can take value.
Set the data parameter with the array including the option you want to show. For example for cities:
'options' => [
'data' => \yii\helpers\ArrayHelper::map(\app\models\City::find()->orderBy('id')->asArray()->all(), 'id', 'name'),
]
try to put inside the options instead ouside
'widgetClass' => Select2::className(),
'options' => [
'initValueText' => 'Selected Text'
Don't use isset it return error if more the one filter are use there.
[
'attribute' => 'ad_partner_id',
'value' => function ($model, $key, $index, $widget) {
return $model->partner->name;
},
'filter' => Select2::widget([
'model' => $searchModel,
'initValueText' => !empty($searchModel->ad_partner_id) ? $searchModel->partner->name : "",
'attribute' => 'ad_partner_id',
'options' => ['placeholder' => Yii::t('app', 'Search Partner ...')],
'pluginOptions' => ['allowClear' => true, 'autocomplete' => true,
'ajax' => ['url' => Url::base() . '/partner/get-partners',
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }'),
],
],
]),
],

Yii2 kartik typeahead - get number of suggestions

I'm using kartik's typeahead widget for Yii2 in a view:
echo \kartik\typeahead\Typeahead::widget([
'name' => 'serial_product',
'options' => [
'placeholder' => 'Filter as you type ...',
'autofocus' => "autofocus"
],
'scrollable' => TRUE,
'pluginOptions' => [
'highlight' => TRUE,
'minLength' => 3
],
'dataset' => [
[
'remote' => Url::to(['transfers/ajaxgetinventoryitemsnew']) . '?search=%QUERY',
'limit' => 10
]
],
'pluginEvents' => [
"typeahead:selected" => "function(obj, item) { add_item(item.id); return false;}",
],
]);
How can i get the number of loaded suggestions after the remote dataset is retrieved to execute a javascript function like:
displaynumber(NUMBEROFSUGGESTIONS);
After checking through the source of kartiks widget i came up with the following solution:
echo \kartik\typeahead\Typeahead::widget([
'name' => 'serial_product',
'options' => [
'placeholder' => 'Filter as you type ...',
'autofocus' => "autofocus",
'id' => 'serial_product'
],
'scrollable' => TRUE,
'pluginOptions' => [
'highlight' => TRUE,
'minLength' => 3
],
'dataset' => [
[
'remote' => [
'url' => Url::to(['transfers/ajaxgetinventoryitemsnew']) . '?search=%QUERY',
'ajax' => ['complete' => new JsExpression("function(response)
{
jQuery('#serial_product').removeClass('loading');
checkresult(response.responseText);
}")]
],
'limit' => 10
]
],
'pluginEvents' => [
"typeahead:selected" => "function(obj, item) { checkresult2(item); return false;}",
],
]);
where response.responseText is containing the response from server (json).
function checkresult(response) {
var arr = $.parseJSON(response);
console.log(arr.length);
}
With this function i can get then count of suggestions delivered from server.