处理表格输入

时间:2017-07-12 11:46:44

标签: php jquery ajax yii2 yii2-advanced-app

希望你们都做得很好。

方案

我有一个联合模型 resumeSkills ,它使用简历的id和不同表格中的技能ID以及另一个字段“熟练程度”来确定该特定技能的专业知识。

Unique Key Violation for skill 我在我的页面中加载了这个模型的多个实例,基于“Add New”按钮单击(它触发了一个Jquery AJAX回调,它实例化,根据给定的索引计数器创建一个模型)。 每个模型实例都是根据定义的模型规则进行验证的,如果我为每个创建的实例选择了不同的值,它就可以正常工作。

:定位
现在,我想以一种方式添加技能如果我在我的视图中的任何模型实例中选择“php”要么我无法在任何新生成的模型实例中选择“php”,要么我没有看到有相应的下拉/标签。

问题

现在,如果我为多个实例选择相同的值(上图),则对于第二个或更晚的记录,验证失败,因为我规定技能不能与简历重复。

这是我需要社区帮助的地方。

这是我的控制器操作方法,用于在视图中添加新模型实例(记录)(附加内容容器)

public function actionAddNewRecord($idresume, $index)
{
    $model = new OresumeResumeSkill();
    $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);
}

以下是我的主要部分文件的代码: 的 _edit_file.php

<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_skill_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($skills); ?>" />
            <?php echo Html::a(T::t('main', 'Add New'), ['/oresume/resume-skill/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_skills").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_skill_multiple").yiiActiveForm('add', attributes[i]);
            }
        });
    </script>


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

以下是我的sub_partial文件的代码(添加新模型实例): 的 _add_new_form.php

$title = T::t('main', 'Add New Record');

$skills = OresumeSkill::listSkills();
$proficiencyLevels = OresumeResumeSkill::listProficiencyLevels();

$form = ActiveForm::begin();
?>

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

    <div class="row single_value_row">
        <div class="col-xs-6">
            <?php echo $form->field($model, "[$i]idskill")->dropDownList($skills, ['style'=>['width'=>'100%'], 'class'=>'resume_skills', '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="btnRemoveResumeSkill-<?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_skill_multiple").yiiActiveForm('add', 'OresumeResumeSkill[<?php echo $i; ?>]');

            $(".resume_skills").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_skill_multiple").yiiActiveForm('add', attributes[i]);
            }
        });
    </script>
</div>


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

以下是我的操作代码,用于处理动态生成的模型并将其保存在db。

Public function actionGetResumeSkills($idresume)
    {
        $model_resume = OresumeResume::findOne($idresume);
        $models = OresumeResumeSkill::getResumeSkills($model_resume->idresume);

        $response = [];

        $postedArray = \Yii::$app->request->post('OresumeResumeSkill');
        //         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 OresumeResumeSkill();
                    $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(OresumeResumeSkill::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 on deletion

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

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

                $response['status'] = true;
                $response['content'] = $this->renderPartial('_partials/_edit_form', ['model_resume' => $model_resume, 'skills' => $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, 'skills' => $models]);
        }

        return Json::encode($response);
    }

感谢任何帮助。 谢谢你提前。

1 个答案:

答案 0 :(得分:0)

我正在通过手机阅读此内容,因此您的代码中有一些部分我不确定我是否完全得到了,我将无法输入太多内容。但是,根据我的理解,您不希望已经选择的技能出现在下一个下拉列表中。

您可以使用隐藏字段来保留所选技能的ID(以逗号分隔),并将其作为参数传递给listSkills方法。意味着你的listSkills方法会改变一点来接受一个参数。

在listSkills方法中,您必须使用where子句,该子句说明来自隐藏字段的ID列表中的技能ID。意味着您将仅选择之前未选择的技能进入阵列中以进行下拉。

抱歉,我正在打电话,我无法添加代码示例。