Ish Ish - 2 months ago 36
jQuery Question

yii2 kartik select2 plugin doesnt work in modal

The dropdown doesnot appear when I try to use kartik select2 plugin in modal. It works like charm when I use it without modal.
This the same code taken from the plugin website, But it still doesn't work. I have found in the source code generated by the browser that select2 plugin css and js are not been loaded from assets folder

This is how the HTML looks
enter image description here

Modal::begin([

'header' => '<h1>Assign Applicant</h1>',
'options' => [
'id' => 'assignApplicantModal',
'tabindex' => false
],
]);
?>


<div class="job-positions-form">

<?php
$form = ActiveForm::begin();
?>
<div class="row">
<div class="col-sm-12">
<div class="col-sm-6">

<?php
$data = ArrayHelper::map(Applicant::find()->where('status = :status', [':status' => 'Active'])->all(), 'id', function($model) {
return $model->first_name . ' ' . $model->last_name;
});

echo $form->field($assign_model, 'applicant_id')->widget(Select2::classname(), [
'data' => $data,
'attribute' => 'applicant_id',
'options' => ['placeholder' => 'Select an applicant'],
'pluginEvents' => [
"select2:selecting" => "function() { "
. "no_position = $('body').data('no_position');"
. "if(no_position>= " . $model->no_of_persons . "){alert('You can select only " . $model->no_of_persons . " applicant(s)');return false;} }",
"select2:select" => "function() { "
. "no_position = $('body').data('no_position');"
. "$('body').data('no_position',++no_position);}",
"select2:unselect" => "function() { "
. "no_position = $('body').data('no_position');"
. "$('body').data('no_position',--no_position);}",
]
]);
?>
</div>
<div class="col-sm-6">
<?php echo $form->field($assign_model, 'applicant_pay')->textInput(['maxlength' => true]); ?>
</div>

<div class="form-group" style="text-align: center;">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php
$inlineScript = "$('body').data('no_position'," . count($applicant_id) . ")";
$this->registerJs($inlineScript, \yii\web\View::POS_END, 'my-inline-js');
Modal::end();


HTML taken from browser:

<div id="assignApplicantModal" class="fade modal" role="dialog">
<div class="modal-dialog ">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h1>Assign Applicant</h1>
</div>
<div class="modal-body">


<div class="job-positions-form">

<form id="w0" action="/staffing/scheduler/web/scheduler/assign_applicant" method="post">
<input type="hidden" name="_schedulerCSRF" value="eEI4TnpSZWcaFnYWNQQcKx0ndC8VEVUyDAl6LAgfBzUTKQw3EBAEEg
=="> <div class="row">
<div class="col-sm-12">
<div class="col-sm-6">

<div class="form-group field-assignapplicant-applicant_id required">
<label class="control-label" for="assignapplicant-applicant_id">Applicant</label>
<div class="kv-plugin-loading loading-assignapplicant-applicant_id">&nbsp;</div><select id="assignapplicant-applicant_id"
class="form-control" name="AssignApplicant[applicant_id]" data-s2-options="s2options_d6851687" data-krajee-select2
="select2_86691c6a" style="display:none">
<option value="">Select an applicant</option>
<option value="12">ASD</option>
<option value="13">qwe</option>
<option value="14">zxc</option>
</select>

<div class="help-block"></div>
</div> </div>
<div class="col-sm-6">
<div class="form-group field-assignapplicant-applicant_pay required">
<label class="control-label" for="assignapplicant-applicant_pay">Applicant Pay</label>
<input type="text" id="assignapplicant-applicant_pay" class="form-control" name="AssignApplicant[applicant_pay
]">

<div class="help-block"></div>
</div> </div>

<div class="form-group" style="text-align: center;">
<button type="submit" class="btn btn-primary">Update</button> </div>
</div>
</div>
</form></div>

</div>

</div>
</div>
</div>

Answer

When content of the modal is dynamic, Select2 assets will not be loaded because initially there is no Select2 related code in DOM.

1) You can register Select2 assets in advance by calling:

\kartik\select2\Select2Asset:register($this);

And then you need to initialize Select2 on every modal content change by calling something like:

$('#field-id').select2();

2) Instead of replacing all HTML inside modal, just render it in advance including empty select (or with some initial data) and only change data inside of it after clicking on different modal triggers.

See this related SO questions:

And according Select2 issue.

The way I used last time:

$dependentDropdown.find('option:not([value=""])').remove();
$dependentDropdown.select2('val', '');
// This can come from AJAX request
var data = [
    {'id': 1, 'text': 'Some text 1'},
    {'id': 2, 'text': 'Some text 2'}
],
var html = '';
$.each(data, function(key, value) {
    html += '<option value="' + value.id + '">' + value.text + '</option>';
});
$dependentDropdown.append(html);
Comments