YII2:添加动态表单字段及其验证

2022-01-07 00:00:00 dynamic php yii2 yii2-advanced-app

我正在添加动态表单域 onChange of dropdown.这两种类型的字段都来自不同的模型,并在不同的表中进入数据库.我已经在模型中定义了验证规则.

但验证工作不正常.我的代码如下:

型号:

['整数']],['值', '每个', '规则' =>['必需的']],[['is_new', 'status', 'value','is_deleted'], 'integer'],[['created_date', 'modified_date'], 'safe'],[['title', 'type'], 'string', 'max' =>[255]];}/*** @inheritdoc*/公共函数attributeLabels(){返回 ['id' =>Yii::t('app', 'ID'),'标题' =>Yii::t('app', 'Title'),'类型' =>Yii::t('app', 'is boolean or value'),'is_new' =>Yii::t('app', '是新的'),'状态' =>Yii::t('app', '状态'),'is_deleted' =>Yii::t('app', '被删除'),'created_date' =>Yii::t('app', '创建日期'),'修改日期' =>Yii::t('app', '修改日期'),];}/*** @return yiidbActiveQuery*/公共函数 getMembershipFeaturesValues(){返回 $this->hasMany(MembershipFeaturesValue::className(), ['feature_id' => 'id']);}}

控制器:

['类' =>VerbFilter::className(),'动作' =>['删除' =>['邮政'],],],];}/*** 列出所有 MembershipFeatures 模型.* @return 混合*/公共函数 actionIndex(){$searchModel = new MembershipFeaturesSearch();$dataProvider = $searchModel->search(Yii::$app->request->queryParams);返回 $this->render('index', ['搜索模型' =>$搜索模型,'数据提供者' =>$数据提供者,]);}/*** 显示单个 MembershipFeatures 模型.* @param 整数 $id* @return 混合*/公共函数 actionView($id){返回 $this->render('view', ['模型' =>$this->findModel($id),]);}/*** 创建一个新的 MembershipFeatures 模型.* 如果创建成功,浏览器将被重定向到查看"页面.* @return 混合*/公共函数 actionCreate(){$model = new MembershipFeatures();$membershipPlan = commonmodelsMembershipPlan::allPlans();if(isset($_GET['type'])){$model->type =$_GET['type'];}if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {Yii::$app->response->format = Response::FORMAT_JSON;返回 yiiwidgetsActiveForm::validate($model);}if ($model->load(Yii::$app->request->post()) ) {if($model->save()){foreach ($membershipPlan as $key=>$value) {$feature = new MembershipFeaturesValue();$feature->feature_id = $model->id;$feature->plan_id = $key;$feature->value =$model->value[$key];$feature->save();}}返回 $this->redirect(['index']);}返回 $this->render('create', ['模型' =>$模型,'membershipPlan'=>$membershipPlan,]);}/*** 更新现有的 MembershipFeatures 模型.* 如果更新成功,浏览器将被重定向到查看"页面.* @param 整数 $id* @return 混合*/公共函数 actionUpdate($id){$membershipPlan = commonmodelsMembershipPlan::allPlans();$model = $this->findModel($id);$selected = MembershipFeaturesValue::find()->where(['feature_id'=>$model->id])->all();foreach ($selected as $key => $value) {$model->value[$value->plan_id]=$value->value;}if(isset($_GET['type'])){$model->type =$_GET['type'];}if(Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {Yii::$app->response->format = Response::FORMAT_JSON;返回 yiiwidgetsActiveForm::validate($model);}if ($model->load(Yii::$app->request->post()) ) {if($model->save()){foreach ($membershipPlan as $key=>$value) {$feature = MembershipFeaturesValue::find()->where(['feature_id'=>$model->id,'plan_id'=>$key])->one();$feature->value =$model->value[$key];$feature->save();}}返回 $this->redirect(['index']);}返回 $this->render('更新', ['模型' =>$模型,'membershipPlan'=>$membershipPlan,]);}/*** 删除现有的 MembershipFeatures 模型.* 如果删除成功,浏览器将被重定向到索引"页面.* @param 整数 $id* @return 混合*/公共函数 actionDelete($id){Helper::partialDelete('MembershipFeatures',$id);返回 $this->redirect(['index']);}/*** 根据主键值查找 MembershipFeatures 模型.* 如果找不到模型,会抛出 404 HTTP 异常.* @param 整数 $id* @return MembershipFeatures 加载的模型* @throws NotFoundHttpException 如果找不到模型*/受保护的函数 findModel($id){if (($model = MembershipFeatures::findOne($id)) !== null) {返回 $model;} 别的 {throw new NotFoundHttpException('请求的页面不存在');}}}

形式:

<div class="membership-features-form"><?php $form = ActiveForm::begin(['enableAjaxValidation' =>真的,'enableClientValidation'=>真,'validateOnSubmit'=>真,'选项' =>['data-pjax'=>true]]);?><?= $form->errorSummary($model);?><?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?><?= $form->field($model, 'type')->dropDownList(['boolean'=>'Boolean','value'=>'Value'],['onchange'=>'$.pjax.reload({url: "'.Url::to(['create']).'?type="+$(this).val(),容器:#pjax-memfeature-form",超时:1000,});','class'='form-control','提示' =>'选择价值类型']) ?><?php Pjax::begin(['id'=>'pjax-memfeature-form','enablePushState'=>false]);?><?phpif($model->type==='boolean'){foreach ($membershipPlan as $key => $value) {echo $form->field($model, "value[$key]")->checkbox(array('标签'=>"$value",'labelOptions'=>array('style'=>'padding:5px;'),));}}if($model->type==='value'){foreach ($membershipPlan as $key => $value) {echo $form->field($model, "value[$key]")->textInput()->label("$value");}}?><?php Pjax::end();?><?= $form->field($model, 'is_new')->dropDownList(['0'=>'No','1'=>'Yes']) ?><?= $form->field($model, 'status')->dropDownList(['1'=>'Active','0'=>'Inactive']) ?><div class="form-group"><?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?><?= Html::a(Yii::t('app', 'Cancel'), ['/membership-features/'], ['class' => 'btn btn-danger']) ?>

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

我想验证我的 value 字段,该字段是在我使用 Pjax 更改类型下拉列表时动态添加的.请指导我验证动态添加的表单字段的正确方法.

解决方案

已经一个月了,所以猜测这个问题已经解决了,但供像我这样正在寻找相同问题的其他人参考,并省去通过框架来找到回答也许尝试类似的东西:

<代码>...使用 yiihelpersJson;...<?php foreach ($form->attributes as $attribute) {$attribute = Json::htmlEncode($attribute);$this->registerJs("jQuery('form').yiiActiveForm('add', $attribute);");?><?php Pjax::end();?>...

已针对 clientValidation 进行测试,而不是针对上述问题进行测试,因此我破解了我的解决方案,希望能回答上述问题.

I am adding dynamic form fields onChange of dropdown. Both types of fields are coming from different models and go to the database in different tables. I have already defined validation rules in models.

But validation are not working properly. My code is as follows:

Model :

<?php

namespace commonmodels;

use Yii;

/**
 * This is the model class for table "{{%membership_features}}".
 *
 * @property integer $id
 * @property string $title
 * @property string $type
 * @property integer $is_new
 * @property integer $status
 * @property integer $is_deleted
 * @property string $created_date
 * @property string $modified_date
 *
 * @property MembershipFeaturesValue[] $membershipFeaturesValues
 */
class MembershipFeatures extends yiidbActiveRecord
{
    /**
     * @inheritdoc
     */

    public $value=[];
    public static function tableName()
    {
        return '{{%membership_features}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['title', 'type', 'value','is_new', 'status'], 'required'],
            ['value', 'each', 'rule' => ['integer']],
            ['value', 'each', 'rule' => ['required']],
            [['is_new', 'status', 'value','is_deleted'], 'integer'],
            [['created_date', 'modified_date'], 'safe'],
            [['title', 'type'], 'string', 'max' => 255]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('app', 'ID'),
            'title' => Yii::t('app', 'Title'),
            'type' => Yii::t('app', 'is boolean or value'),
            'is_new' => Yii::t('app', 'Is New'),
            'status' => Yii::t('app', 'Status'),
            'is_deleted' => Yii::t('app', 'Is Deleted'),
            'created_date' => Yii::t('app', 'Created Date'),
            'modified_date' => Yii::t('app', 'Modified Date'),
        ];
    }

    /**
     * @return yiidbActiveQuery
     */
    public function getMembershipFeaturesValues()
    {
        return $this->hasMany(MembershipFeaturesValue::className(), ['feature_id' => 'id']);
    }
}

Controller :

<?php

namespace backendcontrollers;

use Yii;
use commonmodelsMembershipFeatures;
use backendmodelsMembershipFeaturesSearch;
use yiiwebController;
use yiiwebNotFoundHttpException;
use yiifiltersVerbFilter;
use yiiwebResponse;
use commonmodelsMembershipFeaturesValue;
use commoncomponentsHelper;
/**
 * MembershipFeaturesController implements the CRUD actions for MembershipFeatures model.
 */
class MembershipFeaturesController extends Controller
{
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['post'],
                ],
            ],
        ];
    }

    /**
     * Lists all MembershipFeatures models.
     * @return mixed
     */
    public function actionIndex()
    {
        $searchModel = new MembershipFeaturesSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }

    /**
     * Displays a single MembershipFeatures model.
     * @param integer $id
     * @return mixed
     */
    public function actionView($id)
    {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }

    /**
     * Creates a new MembershipFeatures model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $model = new MembershipFeatures();
        $membershipPlan = commonmodelsMembershipPlan::allPlans();

        if(isset($_GET['type'])){
            $model->type =$_GET['type'];
        }
        if (Yii::$app->request->isAjax  && $model->load(Yii::$app->request->post())) {

            Yii::$app->response->format = Response::FORMAT_JSON;
            return yiiwidgetsActiveForm::validate($model);
        }

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

            if( $model->save()){   
                foreach ($membershipPlan as $key=>$value) {
                    $feature = new MembershipFeaturesValue();
                    $feature->feature_id = $model->id;
                    $feature->plan_id = $key;
                    $feature->value =$model->value[$key];
                    $feature->save();
                }
            }



            return $this->redirect(['index']);
        } 
            return $this->render('create', [
                'model' => $model,
                'membershipPlan'=>$membershipPlan,

            ]);

    }

    /**
     * Updates an existing MembershipFeatures model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {    
        $membershipPlan = commonmodelsMembershipPlan::allPlans();    
        $model = $this->findModel($id);

        $selected = MembershipFeaturesValue::find()->where(['feature_id'=>$model->id])->all();
        foreach ($selected as $key => $value) {
                $model->value[$value->plan_id]=$value->value;
        }    

        if(isset($_GET['type'])){
            $model->type =$_GET['type'];
        }
        if(Yii::$app->request->isAjax  && $model->load(Yii::$app->request->post())) {

            Yii::$app->response->format = Response::FORMAT_JSON;
            return yiiwidgetsActiveForm::validate($model);
        }

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

            if( $model->save()){  

                foreach ($membershipPlan as $key=>$value) {
                    $feature = MembershipFeaturesValue::find()->where(['feature_id'=>$model->id,'plan_id'=>$key])->one();
                    $feature->value =$model->value[$key];
                    $feature->save();
                }
            }



            return $this->redirect(['index']);
        }  

        return $this->render('update', [
                'model' => $model,
                'membershipPlan'=>$membershipPlan,

            ]);

    }

    /**
     * Deletes an existing MembershipFeatures model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($id)
    {
        Helper::partialDelete('MembershipFeatures',$id);

        return $this->redirect(['index']);
    }

    /**
     * Finds the MembershipFeatures model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return MembershipFeatures the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = MembershipFeatures::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
}

Form :

<?php

use yiihelpersHtml;
use yiiwidgetsActiveForm;
use yiiwidgetsPjax;
use yiihelpersUrl;
/* @var $this yiiwebView */
/* @var $model commonmodelsMembershipFeatures */
/* @var $form yiiwidgetsActiveForm */
?>

<div class="membership-features-form">

    <?php $form = ActiveForm::begin([   
    'enableAjaxValidation' => true,
    'enableClientValidation'=>true,
    'validateOnSubmit'=>true,   
    'options' => ['data-pjax'=>true]]); ?>
    <?= $form->errorSummary($model); ?>
    <?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'type')->dropDownList(['boolean'=>'Boolean','value'=>'Value'],
        [
        'onchange'=>'
            $.pjax.reload({
            url: "'.Url::to(['create']).'?type="+$(this).val(),
            container: "#pjax-memfeature-form",
            timeout: 1000,
            });
        ',

        'class'=>'form-control',
        'prompt' => 'Select Type Of Value'
        ]) ?>

        <?php  Pjax::begin(['id'=>'pjax-memfeature-form','enablePushState'=>false]);     ?> 
        <?php 
            if($model->type==='boolean'){
                foreach ($membershipPlan as $key => $value) {
                    echo $form->field($model, "value[$key]")->checkbox(array(
                                'label'=>"$value",
                                'labelOptions'=>array('style'=>'padding:5px;'),

                                )); 
                }    
            }
            if($model->type==='value'){
                foreach ($membershipPlan as $key => $value) {
                  echo $form->field($model, "value[$key]")->textInput()->label("$value"); 
                }
            }
        ?>

         <?php Pjax::end(); ?>        
    <?= $form->field($model, 'is_new')->dropDownList(['0'=>'No','1'=>'Yes']) ?>

    <?= $form->field($model, 'status')->dropDownList(['1'=>'Active','0'=>'Inactive']) ?>

    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
         <?= Html::a(Yii::t('app', 'Cancel'), ['/membership-features/'], ['class' => 'btn btn-danger']) ?>
    </div>

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

</div>

I want to validate my value field which is dynamically added when I change the type dropdown using Pjax. Please guide me a correct method for validating dynamically added form fields.

解决方案

Its been a month so guessing this has been solved but for reference for others like me looking for the same and to save having to step thru the framework to find the answer perhaps try something like:

...
use yiihelpersJson;
...

<?php foreach ($form->attributes as $attribute) {
    $attribute = Json::htmlEncode($attribute);
    $this->registerJs("jQuery('form').yiiActiveForm('add', $attribute);");
} ?>

<?php Pjax::end(); ?>
...

Tested with regards to clientValidation and not with above question so have hacked my solution to hopefully answer above question.

相关文章