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

时间:2015-07-08 07:27:57

标签: php dynamic yii2 yii2-advanced-app

我在下拉列表中添加动态表单字段。两种类型的字段都来自不同的模型,并在不同的表中转到数据库。我已经在模型中定义了验证规则。

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

型号:

<?php

namespace common\models;

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 \yii\db\ActiveRecord
{
    /**
     * @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 \yii\db\ActiveQuery
     */
    public function getMembershipFeaturesValues()
    {
        return $this->hasMany(MembershipFeaturesValue::className(), ['feature_id' => 'id']);
    }
}

控制器:

<?php

namespace backend\controllers;

use Yii;
use common\models\MembershipFeatures;
use backend\models\MembershipFeaturesSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\Response;
use common\models\MembershipFeaturesValue;
use common\components\Helper;
/**
 * 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 = \common\models\MembershipPlan::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 \yii\widgets\ActiveForm::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 = \common\models\MembershipPlan::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 \yii\widgets\ActiveForm::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.');
        }
    }
}

表格:

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\widgets\Pjax;
use yii\helpers\Url;
/* @var $this yii\web\View */
/* @var $model common\models\MembershipFeatures */
/* @var $form yii\widgets\ActiveForm */
?>

<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>

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

3 个答案:

答案 0 :(得分:8)

它已经过了一个月,所以猜测这个问题已经解决了,但是对于像我这样的人来说,寻找同样的东西以及为了节省必须通过框架找到答案的参考或者尝试类似的东西:

...
use yii\helpers\Json;
...

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

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

对于clientValidation进行了测试而没有上述问题,所以已经破解了我的解决方案,希望能够回答上述问题。

答案 1 :(得分:2)

简单

你应该试试这个

<?php
    $this->registerJs('



            jQuery("#w0").yiiActiveForm("add",{
                "id": "customer-name",
                "name": "name",
                "container": ".field-customer-name",
                "input": "#customer-name",
                "error": ".help-block.help-block-error",
                "validate": function(attribute, value, messages, deferred, $form) {

                    yii.validation.required(value, messages, {
                        "message": "Name be blank bug."
                    });

                    yii.validation.string(value, messages, {
                        "message": "Name must be a string.",
                        "max": 255,
                        "tooLong": "Name should contain at most 255 characters.",
                        "skipOnEmpty": 1
                    });
                }
        });


    ');
 ?>

更改

  • w0 加入您的表单ID

  • “id”:“customer-name”到您的输入字段ID中

  • “容器”:“。field-customer-name”进入输入字段div容器 类

答案 2 :(得分:1)

这对我来说没有用,我必须为我的js添加这些addrow和deleterow函数。我ajax off每次都得到一个新行,然后在最后一行之后将它注入DOM。

//为所述元素添加验证(没有这个val.validate但我有一个验证而不是表达式错误)data是来自我的ajax控制器动作的db模型的json对象。

$.each(data.attributes, function(key, val) {                
val = $.parseJSON(val);         
// The validate method is kept in expression so turn it back into a closure. 
val.validate = eval("var f = function(){ return "+val.validate.expression+";}; f() ;") ;
$('#dal-add-form').yiiActiveForm('add', val);
});

然后删除验证:

$.each($(this).parents('.dal-row').find('input, textarea, select'), function() {            
$('#form').yiiActiveForm('remove', $(this).attr('id'));
});