使用不正确的索引收集表格输入

时间:2017-07-12 07:37:52

标签: php yii2 yii2-advanced-app

希望你们都做得很好。

流量 每次我点击Add New按钮时,都会向服务器发送一个AJAX请求,并将更新的索引计数器发送给控制器。现在,控制器在给定的索引处创建一个新模型,使用局部视图开发容器行,然后将其转换为Json并将其返回以显示使用子容器或行扩展当前主容器的新记录。

enter image description here问题 只要我们遵循正常的索引流程,一切正常。但是当我通过添加/删除记录(索引)来更改正常流程然后提交它(如上图所示 - 索引不在正常流程中,第二个索引被删除)时,我得到指向模型值的验证错误(所需的)不能留空。

:定位
我想添加要添加到我的数据库中的模型实例,如果它们有效,无论它们的索引号如何。无论它们属于哪个索引,我都希望它们像序列中的模型数组一样被提交和处理。

以下是我的主要部分文件中的代码: 的 _partials / _edit_form

<div class="row">
    <!-- container that has form and its operations in it -->
    <div class="col-xs-12">

<?php

    $form = ActiveForm::begin([
        'id' => 'form_edit_resume_lang_multiple',
        'options' => [
            'enctype' => 'multipart/form-data',
            'class' => 'section_form',
        ],
    ]);

?>
    <div id="add_new_record_container">
    <!--
        Add new Item related item_container will be placed in here dynamically in parallel
        This loaded content is based on _add_new_form partial view
        Content is added via AJAX request caused by btn_add_new_record
    -->
    </div>

    <div class="row form_controls">
        <div class="col-xs-12 text-right">
            <input type="hidden" name="hdnCounter" id="hdnCounter" value="<?php echo count($languages); ?>" />
            <?php echo Html::a(T::t('main', 'Add New'), ['/oresume/resume-language/add-new-record', 'idresume'=>$model_resume->idresume], ['id'=>'btn_add_new_record', 'class'=>'btn btn-primary' ]); ?>
        </div>
        <div class="col-xs-12 text-right">
            <?php echo Html::a(T::t('main', 'Cancel'), ['/oresume/attachment/discard-all-drafts'], ['class'=>'btn btn-default', 'id'=>'btnDiscardChanges', 'data'=>['confirm_message'=>T::t('main', 'Discard Changes?'), ] ]);?>
            <?php echo Html::submitButton(T::t('main', 'Save Changes'), ['class' => 'btn btn-success']); ?>
        </div>
    </div>

    <?php $attributes = Json::htmlEncode($form->attributes);?>
    <script type="text/javascript">
        jQuery(document).ready(function($){
            <?php 
                $options = Json::htmlEncode($form->options);
                $attributes = Json::htmlEncode($form->attributes);          
            ?>

            $("#<?php echo $form->options['id'];?>").yiiActiveForm(<?php echo $attributes;?>, <?php echo $options;?>);

            $(".resume_languages").select2({
                tags: true,
                multiple: true,
                maximumSelectionLength: 1,
                language: "<?php echo \Yii::$app->language; ?>",
                allowClear: true,
                placeholder: {
                    idskill: "",
                    placeholder: "<?php echo T::t('main', 'Please select'); ?>"
                },
            });

            var attributes = <?php echo $attributes;?>; 
            for(var i = 0; i < attributes.length; i++) {
                $("#form_edit_resume_lang_multiple").yiiActiveForm('add', attributes[i]);
            }
        });
    </script>


<?php ActiveForm::end(); ?>
    </div>
    <!-- //container that has form and its operations in it -->
</div>

注意: hdnCounter inout字段具有计数器值。初始计数器为0.当我点击“添加新”按钮时,AJAX请求会引入一个具有正确外观和感觉的新模型实例作为响应,并将其附加到主表单容器。在该计数器增加1之后。

以下是我的partial_view的代码,该代码用作创建新的基本模板 的 _partials / _add_new_form.php

<div class="col-xs-12 item_container">

    <div class="row single_value_row">
        <div class="col-xs-6">
            <?php echo $form->field($model, "[$i]idlanguage")->dropDownList($languages, ['style'=>['width'=>'100%'], 'class'=>'resume_languages', 'placeholder'=>T::t('main', 'Please select')]); ?>
        </div>
        <div class="col-xs-5">
            <?php echo $form->field($model, "[$i]level")->dropDownList($proficiencyLevels, ['prompt' => T::t('main', 'Please Select')]); ?>
        </div>
        <div class="col-xs-1 text-left">
            <button class="btn btn-danger pull-right btn_remove_record" id="btnRemoveResumeLanguage-<?php echo $i;?>"><?php echo T::t('main', '<i class="fa fa-times"></i>'); ?></button>
            <?php echo $form->field($model, "[$i]isDeleted")->hiddenInput(['class'=>'isDeleted_input'])->label(false); ?>
            <?php echo $form->field($model, "[$i]isFromDb")->hiddenInput(['class'=>'isFromDb_input'])->label(false); ?>
        </div>
    </div>

    <script type="text/javascript">
        jQuery(document).ready(function($){
            $("#form_edit_resume_lang_multiple").yiiActiveForm('add', 'OresumeResumeLang[<?php echo $i; ?>]');

            $(".resume_languages").select2({
                tags: true,
                multiple: true,
                maximumSelectionLength: 1,
                language: "<?php echo \Yii::$app->language; ?>",
                allowClear: true,
                placeholder: {
                    idskill: "",
                    placeholder: "<?php echo T::t('main', 'Please select'); ?>"
                },
            });

            <?php $attributes = Json::htmlEncode($form->attributes);?>
            var attributes = <?php echo $attributes; ?>;
            for(var i = 0; i < attributes.length; i++) {
                $("#form_edit_resume_lang_multiple").yiiActiveForm('add', attributes[i]);
            }
        });
    </script>
</div>

现在这是我的控制器方法的代码,它在给定索引上创建一个新模型 的 actionAddNewRecord

public function actionAddNewRecord($idresume, $index)
{
    $model = new OresumeResumeLang();
    $model->idresume = $idresume;
    $model->isDeleted = 0;
    $model->isFromDb = 0;

    $response = [];

    $response['content'] = $this->renderPartial('_partials/_add_new_form', [
        'model' => $model, 'i'=>$index
    ]);

    return Json::encode($response);
}

以下是添加/删除多个实例的代码 - (管理表格输入) 的 actionGetResumeLanguages

    public function actionGetResumeLanguages($idresume)
    {
        $model_resume = OresumeResume::findOne($idresume);
        $models = OresumeResumeLang::getResumeLanguages($model_resume->idresume);

        $response = [];

        $postedArray = \Yii::$app->request->post('OresumeResumeLang');
        //         print_r($postedArray);

        if( count($postedArray) )  //case: Its a postback and we have some models in it
        {
            if(count($models) < count($postedArray) )//case: postback has more number of models as compared to in db
            {
                //  Generate empty models array to be filled by loadMultiple() method of model class
                //  create emoty models and add in models array counter so that
                //  we've equal number of sent / recieved models for processing
                for ($i=count($models); $i< count($postedArray); $i++ )
                {
                    $model = new OresumeResumeLang();
                    $model->idresume = $idresume;
                    $models[] = $model;
                }
            }
        }

        if( count($models) == 0) //  we need to check if this array has something to process
        {
            $response['status'] = false;
            $response['message'] = T::t('main', 'No records found to process');
        }

        //  if we have postback and if we have more models in it than
        //  in our database, and since we have created empty models
        //  to be filled-up now we can load posted models in our array
        if(OresumeResumeLang::loadMultiple($models, \Yii::$app->request->post())) //  load multiple models of models array
        {
            $status = true;

            foreach ($models as $model)
            {
                //  Delete models that are flaged to do so
                //  execute continue; statement after deletion

                //  Validate and save models that are to be saved/updated
                $model->idlanguage = OresumeResumeLang::getLanguageId($model->idlanguage);
                $model->level = ($model->level != null)? $model->level : OresumeResumeLang::LEVEL_BEGINNER;
                if( $model->validate() )    //  Case: Model data is valid
                {
                    //  Save Model in database
                    $status &= $model->save();
                }
                else
                {
                    $status = false;
//                     print_r($model->errors['idlanguage'][0]);
                    $response['message'] = T::t("main", "Storing of record \"{$model->idlanguage0->name}\" got some validation issues\n");
                }
            }

            if($status)
            {
                $model_resume = OresumeResume::findOne($model->idresume);
                $models = OresumeResumeLang::getResumeLanguages($model->idresume);

                $response['status'] = true;
                $response['content'] = $this->renderPartial('_partials/_edit_form', ['model_resume' => $model_resume, 'languages' => $models]);
                $response['counter'] = count($models);
                $response['message'] = T::t('main', 'Record(s) updated Successfully');
            }
            else
            {
                $response['status'] = false;
                //  $response['message'] = T::t('main', 'Records could not be updated.\n Something went wrong');
            }
        }
        else // case: page loads for the first time
        {
            $response['content'] = $this->renderPartial('_partials/_edit_form', ['model_resume'=>$model_resume, 'languages' => $models]);
        }

        return Json::encode($response);
    }

编辑: 我创建了index-2然后将其删除。 (导致表单针对index-2创建)。现在再一次,我点击Add New(导致一个新的表单针对index-3创建)我用值填充它然后将表单提交给服务器,我得到针对表单的验证错误,索引-2指向值不能留空。我无法解决这个问题。

1 个答案:

答案 0 :(得分:1)

每次要求插入新记录时,您都会根据对服务器的新请求创建新模型。但是当你删除它时,你没有删除模型索引中的那个索引。我想这可能是原因。

如果有帮助,请告诉我。