所有动态项目的相同索引 - 嵌套动态表单 Yii2

Posted

技术标签:

【中文标题】所有动态项目的相同索引 - 嵌套动态表单 Yii2【英文标题】:Same index for all dynamic items - Nested dynamic form Yii2 【发布时间】:2016-05-25 08:58:03 【问题描述】:

我得到所有新项目的相同索引(0)而不是递增索引。我不知道我的代码有什么问题和哪里有问题。我正在通过参考此演示 Nested Dynamic Form - Yii2 来解决此问题。对不起我的英语不好。

我的控制器

这是我的控制器。

public function actionUpdateperkara($id)

    $model = $this->findModel($id);
    $modelsPerkaraSatu = $model->tblMinitperkaras;
    $modelsPerkaraDua = [];
    $oldPerkaraDuas = [];

    if (!empty($modelsPerkaraSatu)) 
        foreach ($modelsPerkaraSatu as $indexPerkaraSatu => $modelPerkaraSatu) 
            $perkaraduas = $modelPerkaraSatu->tblMinitperkara2s;
            $modelsPerkaraDua[$indexPerkaraSatu] = $perkaraduas;
            $oldPerkaraDuas = ArrayHelper::merge(ArrayHelper::index($perkaraduas, 'per_id'), $oldPerkaraDuas);
        
    

    if ($model->load(Yii::$app->request->post())) 

        // reset
        $modelsPerkaraDua = [];

        $oldPerkaraSatuIDs = ArrayHelper::map($modelsPerkaraSatu, 'perkara_id', 'perkara_id');
        $modelsPerkaraSatu = ModelPerkara::createMultiple(TblMinitperkara::classname(), $modelsPerkaraSatu);
        ModelPerkara::loadMultiple($modelsPerkaraSatu, Yii::$app->request->post());
        $deletedPerkaraSatuIDs = array_diff($oldPerkaraSatuIDs, array_filter(ArrayHelper::map($modelsPerkaraSatu, 'perkara_id', 'perkara_id')));

        // validate model and tblMinitperkaras models
        $valid = $model->validate();
        $valid = ModelPerkara::validateMultiple($modelsPerkaraSatu) && $valid;

        $perkaraDuasIDs = [];
        if (isset($_POST['TblMinitperkara2'][0][0])) 
            foreach ($_POST['TblMinitperkara2'] as $indexPerkaraSatu => $perkaraduas) 
                $perkaraDuasIDs = ArrayHelper::merge($perkaraDuasIDs, array_filter(ArrayHelper::getColumn($perkaraduas, 'per_id')));
                foreach ($perkaraduas as $indexPerkaraDua => $perkaradua) 
                    $data['TblMinitperkara2'] = $perkaradua;
                    $modelPerkaraDua = (isset($perkaradua['per_id']) && isset($oldPerkaraDuas[$perkaradua['per_id']])) ? $oldPerkaraDuas[$perkaradua['per_id']] : new TblMinitperkara2;
                    $modelPerkaraDua->load($data);
                    $modelsPerkaraDua[$indexPerkaraSatu][$indexPerkaraDua] = $modelPerkaraDua;
                    $valid = $modelPerkaraDua->validate();
                
            
        

        $oldPerkaraDuasIDs = ArrayHelper::getColumn($oldPerkaraDuas, 'per_id');
        $deletedPerkaraDuasIDs = array_diff($oldPerkaraDuasIDs, $perkaraDuasIDs);

        if ($valid) 
            $transaction = Yii::$app->db->beginTransaction();
            try 
                if ($flag = $model->save(false)) 

                    if (! empty($deletedPerkaraDuasIDs)) 
                        TblMinitperkara2::deleteAll(['per_id' => $deletedPerkaraDuasIDs]);
                    

                    if (! empty($deletedPerkaraSatuIDs)) 
                        TblMinitperkara::deleteAll(['perkara_id' => $deletedPerkaraSatuIDs]);
                    

                    foreach ($modelsPerkaraSatu as $indexPerkaraSatu => $modelPerkaraSatu) 

                        if ($flag === false) 
                            break;
                        

                        $modelPerkaraSatu->butir_id = $model->butir_id;

                        if (!($flag = $modelPerkaraSatu->save(false))) 
                            break;
                        

                        if (isset($modelsPerkaraDua[$indexPerkaraSatu]) && is_array($modelsPerkaraDua[$indexPerkaraSatu])) 
                            foreach ($modelsPerkaraDua[$indexPerkaraSatu] as $indexPerkaraDua => $modelPerkaraDua) 
                                $modelPerkaraDua->perkara_id = $modelPerkaraSatu->perkara_id;
                                if (!($flag = $modelPerkaraDua->save(false))) 
                                    break;
                                
                            
                        
                    
                

                if ($flag) 
                    $transaction->commit();
                    return $this->redirect(['view', 'id' => $model->butir_id]);
                 
                else 
                    $transaction->rollBack();
                
             
            catch (Exception $e) 
                $transaction->rollBack();
            
        
    

    return $this->render('_form_perkara', [
        'model' => $model,
        'modelsPerkaraSatu' => (empty($modelsPerkaraSatu)) ? [new TblMinitperkara] : $modelsPerkaraSatu,
        'modelsPerkaraDua' => (empty($modelsPerkaraDua)) ? [[new TblMinitperkara2]] : $modelsPerkaraDua
    ]);

_form_perkara

这是我的表格。

<?php

use yii\helpers\html;
use yii\helpers\ArrayHelper;

use yii\helpers\Url;
use yii\widgets\ActiveForm;
use wbraganca\dynamicform\DynamicFormWidget;
use yii\jui\JuiAsset;
use yii\web\Response;
use yii\web\JsExpression;
use kartik\file\FileInput;

use kartik\date\DatePicker;
use kartik\time\TimePicker;

/* @var $this yii\web\View */
/* @var $model frontend\models\TblMinitbutiran */
/* @var $form yii\widgets\ActiveForm */

$this->title = 'Minit Mesyuarat : ' . $model->butir_id;
$this->params['breadcrumbs'][] = ['label' => 'Senarai Minit Mesyuarat', 'url' => ['index']];
$this->params['breadcrumbs'][] = ['label' => 'Minit Mesyuarat : ' .         $model->butir_id, 'url' => ['view', 'id' => $model->butir_id]];
$this->params['breadcrumbs'][] = 'Butiran Perkara';
?>

<div>

<?php $form = ActiveForm::begin(['id' => 'dynamic-form']); ?>

<div class="panel panel-primary">
    <div class="panel-heading"><b>Butiran Mesyuarat</b></div>
    <div class="panel-body">

        <div class="col-sm-3 ">

            <?= $form->field($model, 'butir_bil')->textInput(['maxlength' => true]) ?>

        </div>

        <div class="col-sm-4 ">

            <?= $form->field($model, 'butir_tarikh')->widget(DatePicker::classname(), [
                'options' => ['placeholder' => 'pilih tarikh mesyuarat'],
                'pluginOptions' => [
                    'format' => 'yyyy-mm-dd',
                    'endDate' => '+0d',
                    'autoclose'=>true
                ]
            ]); ?>

            <?= $form->field($model, 'butir_masa')->widget(TimePicker::classname(), [
                'pluginOptions' => [
                    'showMeridian'=>false
                ]
            ]); ?>

        </div>

        <div class="col-sm-5">

            <?= $form->field($model, 'butir_tempat')->textarea(['rows' => 4]) ?>

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

<div class="panel panel-primary">
    <div class="panel-heading"><b>Perkara</b></div>
    <div class="panel-body">
        <?php DynamicFormWidget::begin([
            'widgetContainer' => 'dynamicform_wrapper',
            'widgetBody' => '.container-items',
            'widgetItem' => '.house-item',
            'min' => 1,
            'insertButton' => '.add-house',
            'deleteButton' => '.remove-house',
            'model' => $modelsPerkaraSatu[0],
            'formId' => 'dynamic-form',
            'formFields' => [
                'perkara_bil',
                'perkara_perkara',
            ],
        ]); ?>
        <div>
            <div>
                <div style="overflow:hidden; height:30px;">
                    <div class="col-md-1 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:left"><b>BIL</b></div>
                    <div class="col-md-9 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:left"><b>PERKARA</b></div>
                    <div class="col-md-2 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:left"><b>TINDAKAN / MAKLUMAN</b></div>
                </div>
            </div>
            <div class="container-items">
            <?php foreach ($modelsPerkaraSatu as $indexPerkaraSatu => $modelPerkaraSatu): ?>
            <div class="house-item">
                <div class="col-md-1 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:center">
                    <?php
                        // necessary for update action.
                        if (! $modelPerkaraSatu->isNewRecord) 
                            echo Html::activeHiddenInput($modelPerkaraSatu, "[$indexPerkaraSatu]perkara_id");
                        
                    ?>
                    <?= $form->field($modelPerkaraSatu, "[$indexPerkaraSatu]perkara_bil")->label(false)->textInput(['maxlength' => true]) ?>
                </div>
                <div class="col-md-9 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:center">
                    <?= $form->field($modelPerkaraSatu, "[$indexPerkaraSatu]perkara_perkara")->label(false)->textInput(['maxlength' => true]) ?>

                </div>
                <div class="col-md-2 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:center">
                    <button type="button" class="add-house btn btn-success btn-xs"><span class="glyphicon glyphicon-plus"></span></button>
                    <button type="button" class="remove-house btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus"></span></button>
                </div>
                <?= $this->render('_form_perkara2', [
                    'form' => $form,
                    'indexPerkaraSatu' => $indexPerkaraSatu,
                    'modelsPerkaraDua' => $modelsPerkaraDua[$indexPerkaraSatu],
                ]) ?>
            </div>
            <?php endforeach; ?>
            </div>
        </div>
        <?php DynamicFormWidget::end(); ?>
    </div>
</div>

<div class="form-group">
    <?= Html::submitButton($model->isNewRecord ? 'Hantar' : 'Hantar', ['class' => 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>
</div>

<script type="text/javascript">
$(".dynamicform_wrapper").on("beforeInsert", function(e, item) 
    console.log("beforeInsert");
);

$(".dynamicform_wrapper").on("afterInsert", function(e, item) 
    console.log("afterInsert");
);

$(".dynamicform_wrapper").on("beforeDelete", function(e, item) 
    if (! confirm("Are you sure you want to delete this item?")) 
        return false;
    
    return true;
);

$(".dynamicform_wrapper").on("afterDelete", function(e) 
    console.log("Deleted item!");
);

$(".dynamicform_wrapper").on("limitReached", function(e, item) 
    alert("Limit reached");
);
</script>

_form_perkara2

<?php

use yii\helpers\Html;
use wbraganca\dynamicform\DynamicFormWidget;

?>

<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_inner',
'widgetBody' => '.container-rooms',
'widgetItem' => '.room-item',
'min' => 1,
'insertButton' => '.add-room',
'deleteButton' => '.remove-room',
'model' => $modelsPerkaraDua[0],
'formId' => 'dynamic-form',
'formFields' => [
    'per_no',
    'per_butiran',
    'per_maklumat'
],
]); ?>
<div class="container-rooms" style="align:center">
<?php foreach ($modelsPerkaraDua as $indexPerkaraDua => $modelPerkaraDua): ?>
<div class="room-item">            
    <div class="col-md-1 alert alert-danger" role="alert" style="padding:5px; height:50px; text-align:center">
        <button type="button" class="add-room btn btn-primary btn-xs"><span class="glyphicon glyphicon-plus"></span></button>
        <button type="button" class="remove-room btn btn-warning btn-xs"><span class="glyphicon glyphicon-minus"></span></button>
    </div>
    <div class="col-md-1 alert alert-danger" role="alert" style="padding:5px; height:50px; text-align:center">
        <?php
            // necessary for update action.
            if (! $modelPerkaraDua->isNewRecord) 
                echo Html::activeHiddenInput($modelPerkaraDua, "[$indexPerkaraSatu][$indexPerkaraDua]per_id");
            
        ?>
        <?= $form->field($modelPerkaraDua, "[$indexPerkaraSatu][$indexPerkaraDua]per_no")->label(false)->textInput(['maxlength' => true]) ?>
    </div>
    <div class="col-md-8 alert alert-danger" role="alert" style="padding:5px; height:50px; text-align:center">
        <?= $form->field($modelPerkaraDua, "[$indexPerkaraSatu][$indexPerkaraDua]per_butiran")->label(false)->textInput(['maxlength' => true]) ?>
    </div>
    <div class="col-md-2 alert alert-danger" role="alert" style="padding:5px; height:50px; text-align:center">
        <?= $form->field($modelPerkaraDua, "[$indexPerkaraSatu][$indexPerkaraDua]per_maklumat")->label(false)->textInput(['maxlength' => true]) ?>
    </div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>

ModelPerkara 类

<?php

namespace frontend\models;

use Yii;
use yii\helpers\ArrayHelper;

class ModelPerkara extends \yii\base\Model

/**
 * Creates and populates a set of models.
 *
 * @param string $modelClass
 * @param array $multipleModels
 * @return array
 */
public static function createMultiple($modelClass, $multipleModels = [])

    $model    = new $modelClass;
    $formName = $model->formName();
    $post     = Yii::$app->request->post($formName);
    $models   = [];

    if (! empty($multipleModels)) 
        $keys = array_keys(ArrayHelper::map($multipleModels, 'perkara_id', 'perkara_id'));
        $multipleModels = array_combine($keys, $multipleModels);
    

    if ($post && is_array($post)) 
        foreach ($post as $indexPerkaraSatu => $item) 
            if (isset($item['perkara_id']) && !empty($item['perkara_id']) && isset($multipleModels[$item['perkara_id']])) 
                $models[] = $multipleModels[$item['perkara_id']];
             else 
                $models[] = new $modelClass;
            
        
    

    unset($model, $formName, $post);

    return $models;


检查员截图

input id in second div of "house-item" is same with the first one. This show that the index is not increments

【问题讨论】:

屏幕截图的链接已过期。请更新。 【参考方案1】:

您需要在视图文件中添加 javascript 事件。

$js = '
jQuery(".dynamicform_wrapper").on("afterInsert", function(e, item) 
    jQuery(".dynamicform_wrapper .panel-title-address").each(function(index) 
        jQuery(this).html("Address: " + (index + 1))
    );
);

jQuery(".dynamicform_wrapper").on("afterDelete", function(e) 
    jQuery(".dynamicform_wrapper .panel-title-address").each(function(index) 
        jQuery(this).html("Address: " + (index + 1))
    );
);
';

$this->registerJs($js);

【讨论】:

很抱歉提出这个问题。我是 yii 的新手。还在学习过程中。在哪里添加javascript事件?在 标记或 中。感谢您的回复 您必须在视图文件中添加标签

以上是关于所有动态项目的相同索引 - 嵌套动态表单 Yii2的主要内容,如果未能解决你的问题,请参考以下文章

嵌套光标上的动态重建索引

Yii2动态表格wbraganca复制值到克隆字段[重复]

动态嵌套表单总是创建一个额外的空白条目 - 使用 formtastic_coocoon

react实现动态表单中嵌套动态表单

Rails 4 - 根据嵌套形式的第一个选择菜单中的选择动态填充第二个选择菜单

角度动态表单嵌套字段