Я добавляю динамические поля формы onChange выпадающего списка. Оба типа полей поступают из разных моделей и идут в базу данных в разных таблицах. Я уже определил правила валидации в моделях.
Но проверка не работает должным образом. Мой код выглядит следующим образом:
Модель:
<?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. Пожалуйста, направляйте мне правильный метод проверки динамически добавленных полей формы.
Это был месяц, так что догадываться, что это было решено, но для справки для других, таких как я, ища то же самое и для того, чтобы избавиться от необходимости проходить через рамки, чтобы найти ответ, возможно, попробуйте что-то вроде:
... 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, а не с указанным выше вопросом, поэтому взломало мое решение, надеюсь, ответить на вышеуказанный вопрос.
Это не совсем сработало для меня, я должен был добавить эти функции addrow и deleterow для своих js. Я ajax, чтобы каждый раз получать новую строку, а затем вставлять ее в DOM после последней строки.
// Добавить проверку для указанных элементов (без этого val.validate, но у меня была проверка, а не ошибка выражения). Данные – это json-объект модели db, исходящий из моего действия контроллера ajax.
$.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')); });
просто
Вы должны попробовать это
<?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
«container»: «.field-customer-name» в поле контейнера полей ввода div