1

インクリメントされたインデックスではなく、すべての新しいアイテムに対して同じインデックス ( 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(); ?>

モデルペルカラクラス

<?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;
}
}

インスペクタのスクリーンショット

「house-item」の 2 番目の div の入力 id は、最初のものと同じです。これは、インデックスが増分ではないことを示しています

4

1 に答える 1