Search code examples
phpajaxyii2jquery-select2pjax

Select2 Widget & Pjax Yii2


I'm trying to add multiple Select2 widgets dynamically in the TabularForm using Pjax (build-in Ajax component in Yii2). For some reason the Select2 input is rendering on the wrong place at the top of the view (see gif1 below). As I understood, this issue is related specifically to the Select2 widget as everthing is working fine if I use some default component e.g. Html::a (see gif2 below).

gif1: https://i.sstatic.net/9gUJu.gif

gif2: https://i.sstatic.net/wojwB.gif

How I can get rid of that strange behaviour with the Select2 widget? Thanks is advance!

Controller:

class ProfileController extends Controller
{
// ...
    public function actionCreate()
    {   
        if (Yii::$app->request->isAjax) { 
            // some logic here ...
            return $this->renderAjax('object/create', [
                // ...
            ]);
        }
    }
// ...

}

View:

// ...
use kartik\select2\Select2;
use kartik\select2\Select2Asset;

Select2Asset::register($this);

// a bunch of html code

<?php Pjax::begin(['id' => 'product-add']); ?>
    $form1 = ActiveForm::begin();
    $attribs = [
        'name' => [
         'type' => TabularForm::INPUT_RAW,
          'value' => function($productModel) { 
               return Select2::widget([
                   'name' => 'state_10',
                   'data' => ['1' => '1', '2' => '2'],
                   'pjaxContainerId' => 'product-add',
                   'options' => [
                       'placeholder' => $productModel->tmpId,
                       'multiple' => true
                   ],
               ]);
               //return Html::a('product ' . $productModel->tmpId); <- works fine if I use this piece of code
           },
    ],

    // ...

    Html::a("Add", ['profile/create'], ['class' => 'btn btn-primary'])

    // ...
    <?php ActiveForm::end(); ?>
<?php Pjax::end(); ?>

// ...

Solution

  • After some closer examination I found the solution. For those who will also face the same issue, you need to initialize your widget (Select2 in my case) before the pjax response, e.g. in your Controller:

    class ProfileController extends Controller
    {
    // ...
        public function actionCreate()
        {   
            if (Yii::$app->request->isAjax) { 
                // some logic here ...
    
                // initialize the widget with an appropriate id
                $this->view->registerJs("$({$product->tmpId}).select2();"); 
    
                return $this->renderAjax('object/create', [
                    // ...
                ]);
            }
        }
    // ...
    
    }
    

    And somewhere in your View:

    Select2::widget([
        'id' => $productModel->tmpId, // set your unique id here
        'name' => $productModel->tmpId,
        'data' => ['1' => '1', '2' => '2'],
        // ...
    ]);