I have a scenario where I want to conditionally make a Select2 input control visible or invisible. This condition can change while a user is filling out a form. So we first need to determine if the widget is visible when the form is instantiated and then using JQuery determine if the condition has changed while the form is being completed.
The problem is the Kartik’s Select2 widget is made up of many components and setting the CSS style of the control to display: none
seems to do nothing:
View
use kartik\widgets\Select2;
use kartik\form\ActiveForm;
<?= $form->field($model, 'product_id',
['showLabels' => false])
->widget(Select2::class,
[
'data' => $data,
'options' => [
'placeholder' => 'Select item...',
'style' => $model->type == TYPE_PRODUCT ? 'display:none' : '',
],
'pluginEvents' => [
'change' => 'function(event) {onProductChange(event);}'
],
'pluginOptions' => [
'allowClear' => true,
'disabled' => !$model->isNewRecord ? true : false,
],
]);
?>
The solution is quite simple. Rather than trying to hide the widget, place the widget into an HTML div container and hide this. Here is a working example:
<div class="product-select2-widget" style="<?=$model->type == TYPE_PRODUCT ? 'display:none' : ''?>">
<?= $form->field($model, 'product_id',
['showLabels' => false])
->widget(Select2::class,
[
'data' => $data,
'options' => [
'placeholder' => 'Select item...',
],
'pluginEvents' => [
'change' => 'function(event) {onProductChange(event);}'
],
'pluginOptions' => [
'allowClear' => true,
'disabled' => !$model->isNewRecord ? true : false,
],
]);
?>
</div>
Javascript
/**
* Event fired when form's type attribute is changed
* Used to decide if product select2 widget is visible or not
*/
$(document).on('change', '#modelform-type', function () {
if ($(this).val() == TYPE_PRODUCT)
$('.product-select2-widget').show();
else
$('.product-select2-widget').hide();
});