希望你们都做得很好。
流量 每次我点击Add New按钮时,都会向服务器发送一个AJAX请求,并将更新的索引计数器发送给控制器。现在,控制器在给定的索引处创建一个新模型,使用局部视图开发容器行,然后将其转换为Json并将其返回以显示使用子容器或行扩展当前主容器的新记录。
的问题 只要我们遵循正常的索引流程,一切正常。但是当我通过添加/删除记录(索引)来更改正常流程然后提交它(如上图所示 - 索引不在正常流程中,第二个索引被删除)时,我得到指向模型值的验证错误(所需的)不能留空。
:定位
我想添加要添加到我的数据库中的模型实例,如果它们有效,无论它们的索引号如何。无论它们属于哪个索引,我都希望它们像序列中的模型数组一样被提交和处理。
以下是我的主要部分文件中的代码: 的 _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指向值不能留空。我无法解决这个问题。
答案 0 :(得分:1)
每次要求插入新记录时,您都会根据对服务器的新请求创建新模型。但是当你删除它时,你没有删除模型索引中的那个索引。我想这可能是原因。
如果有帮助,请告诉我。