簡體   English   中英

Yii2將Select2與yii2-formwizard的表格步驟一起使用

[英]Yii2 Using Select2 with tabular step of yii2-formwizard

我正在使用yii2-formwizard ,它是我的項目中使用kartik\\select2的便捷工具。 一切正常,除了當我按添加以獲取下一個組時,上一個組的select2下拉列表消失了。

當我按照上一篇文章中的說明修改控制器以從模型中捕獲數據時,就會發生這種情況,我在腳本方面錯過了一些東西,但是在jquery / JS等方面卻有點差勁,無論如何,除了保存數據和使小部件正常工作外

我的控制器

<?php

public function actionCreatemulti()
{
    $this->layout = 'layout2';
    $model = [new Todelete()];
    $sex = [['id' => 1, 'name' => 'male'], ['id' => 2, 'name' => 'female']];

    if (Yii::$app->request->isPost) {

        $count = count(Yii::$app->request->post('Todelete', []));
        //start the loop from 1 rather than 0 and use the $count for limit
        for ($i = 1; $i < $count; $i++) {
            $model[] = new Todelete();
        }

        if (Model::loadMultiple($model, Yii::$app->request->post()) && Model::validateMultiple($model)) {
            foreach ($model as $md) {
                $md->save(false);
            }
            return $this->render('index');
        }
    }

    return $this->render('create', [
        'model' => $model,
        'sex' => $sex
    ]);
}

我的觀點

echo FormWizard::widget(
    [
        'formOptions' => [
            'id' => 'my_form_tabular'
        ],
        'steps' => [
            [
                //should be a single model or array of Activerecord model objects but for a single model only see wiki on github
                'model' => $model,

                //set step type to tabular
                'type' => FormWizard::STEP_TYPE_TABULAR,

                'fieldConfig' => [
                    'sex' => [
                        'widget' => Select2::class,
                        'containerOptions' => [
                            'class' => 'form-group'
                        ],
                        'options' => [
                            'data' => $data,
                            'options' => [
                                'class' => 'form-control'
                            ],
                            'theme' => Select2::THEME_BOOTSTRAP,
                            'pluginOptions' => [
                                'allowClear' => true,
                                'placeholder' => 'Select sex'
                            ]
                        ],

                        //set tabular events for select2 fix which doesnot work correctly after cloning

                        'tabularEvents' => [

                            'beforeClone' => "function(event, params){
                                //fix for select2 destroy the plugin

                                let element = $(this);
                                element.select2('destroy');
                            }",
                            "afterClone" => "function(event, params){

                                //bind select2 again after clone

                                let element = $(this);
                                let elementId = $(this).attr('id');
                                let dataKrajee = eval(element.data('krajee-select2'));
                                let dataSelect2Options = element.data('s2-options');
                                $.when(element.select2(dataKrajee)).done(initS2Loading(elementId, dataSelect2Options));
                            }",
                            "afterInsert" => "function(event,params){
                                //initialize the options for the select2 after initializing
//changed according to my environment

                                let selectElement = $(this).find('.field-todelete-'+params.rowIndex+'-sex > select');
                                let dataKrajee = eval(selectElement.data('krajee-select2'));
                                selectElement.select2(dataKrajee);
                            }"
                        ]
                    ]
                ]
            ]

        ]
    ]
);

https://cdn1.imggmi.com/uploads/2019/8/31/158dc0f338e0d780747c5f72fa2ed6bb-full.png https://cdn1.imggmi.com/uploads/2019/8/31/4e394e87aa162d3f457c32af8d30373b-full.png

原因

您指出的問題確實存在,您對此是正確的。 但是此問題與kartik\\select2 @V2.1.4的最新更改有關。演示鏈接使用的select2 V2.1.3的較舊版本V2.1.3dataset屬性,因此可以正常工作。

窗口小部件不會集成所有這些更改,而是留給正在集成窗口小部件的用戶

原因是無法在插件內部正確控制它,因為可能會有用戶想要使用的任何小部件,而我會繼續投票給其他小部件添加代碼。 因此,更好的方法是為需要對元素進行預處理或后處理的特定操作提供事件觸發器,其中用戶可以根據需要調整其代碼

故障排除

現在關於這個問題,有一個新的數據集屬性data-select2-id ,它保存了select2綁定到的輸入的名稱,克隆新元素后,該屬性未更新為較新的元素id,這會導致您的舊選擇要消失的元素。

請參見下圖,它來自我自己的代碼,因此請忽略address-0-city字段名稱,因為它與您的代碼無關,僅用於理解

在此處輸入圖片說明

因此我們需要將afterInsert事件中的代碼更改為以下代碼

let selectElement = $(this).find('.field-todelete-'+params.rowIndex+'-sex > select');
let dataKrajee = eval(selectElement.data('krajee-select2'));

//update the dataset attribute to the
if (typeof selectElement[0].dataset.select2Id !== 'undefined') {

    //get the old dataset which has the old id of the input the select2 is bind to 
    let oldDataSelect2Id = selectElement[0].dataset.select2Id;

    //delete the old dataset
    delete selectElement[0].dataset.select2Id;

    //add the new dataselect pointing to the new id of the cloned element
    let newDataSelect2Id = oldDataSelect2Id.replace(
    /\-([\d]+)\-/,
    '-' + parseInt(params.rowIndex) + '-'
    );

    //add the new dataset with the new cloned input id 
    selectElement[0].dataset.select2Id= newDataSelect2Id;
}
selectElement.select2(dataKrajee);

在接下來的幾天中,我還將更新wiki文檔上的代碼以及示例代碼。

希望它可以幫助您。

當使用小部件的ID發生沖突時,通常會發生這種情況。 通過檢查HTML頁面來檢查是否不會發生這種情況。 特別是,請關注以下部分(此代碼僅是示例):

<Block1>
  <select id = "todelete-0-sex">
</Block1>
<Block2>
  <select id = "todelete-1-sex">
</Block2>

<Script>
  // ...
  $("# Todelete-0-sex").select2({...});
  // ...
  $("#Todelete-1-sex").select2({...});
  // ...
</Script>

我使用以下兩個組件在Yii2(2.0.25)的全新安裝中復制了您的代碼:

  • buttflattery / yii2-formwizard(1.4.6)
  • kartik-v / yii2-widget-select2(v2.1.3)

進行一些與使代碼正常工作無關的微小更改,一切似乎都很好。

屏幕截圖

概括

  1. 驗證創建兩個小部件時沒有沖突
  2. 檢查“ yii2-formwizard”和“ yii2-widget-select2”組件的版本

MyController.php(控制器)

...
    public function actionTest()
    {
        //$this->layout = 'layout2';
        $model = [new Todelete(['id' => 1, 'name' => 'a', 'sex' => 'male']), new Todelete(['id' => 2, 'name' => 'b', 'sex' => 'male']), new Todelete(['id' => 3, 'name' => 'c', 'sex' => 'female'])];
        $sex = [['id' => 1, 'name' => 'male'], ['id' => 2, 'name' => 'female']];

        if (Yii::$app->request->isPost) {

            $count = count(Yii::$app->request->post('Todelete', []));
            //start the loop from 1 rather than 0 and use the $count for limit
            for ($i = 1; $i < $count; $i++) {
                $model[] = new Todelete();
            }

            if (Model::loadMultiple($model, Yii::$app->request->post()) && Model::validateMultiple($model)) {
                foreach ($model as $md) {
                    $md->save(false);
                }
                return $this->render('index');
            }
        }

        return $this->render('test', [
            'model' => $model,
            'sex' => $sex
        ]);
    }
...

Todelete.php(模型)

...
use yii\base\Model; // NOTE: in your case your model will most likely extend ActiveRecord instead of Model class

class Todelete extends Model
{
    public $id;
    public $name;
    public $sex;

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            ['id', 'integer'],
            [['sex', 'name'], 'string'],
        ];
    }
}
...

create.php(查看)

use kartik\select2\Select2;
use \buttflattery\formwizard\FormWizard;

echo FormWizard::widget(
    [
        'formOptions' => [
            'id' => 'my_form_tabular'
        ],
        'steps' => [
            [
                //should be a single model or array of Activerecord model objects but for a single model only see wiki on github
                'model' => $model,

                //set step type to tabular
                'type' => FormWizard::STEP_TYPE_TABULAR,

                'fieldConfig' => [
                    'sex' => [
                        'widget' => Select2::class,
                        'containerOptions' => [
                            'class' => 'form-group'
                        ],
                        'options' => [
                            //'data' => $data,
                            'options' => [
                                'class' => 'form-control'
                            ],
                            'theme' => Select2::THEME_BOOTSTRAP,
                            'pluginOptions' => [
                                'allowClear' => true,
                                'placeholder' => 'Select sex'
                            ]
                        ],

                        //set tabular events for select2 fix which doesnot work correctly after cloning

                    ]
                ]
            ]

        ]
    ]
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM