Использование пользовательских валидаторов с ActiveForm в Yii2

Я хочу сделать пользовательские функции проверки, такие как встроенная проверка required, У меня есть пример кода здесь:

Модель:

use yii\base\Model;

class TestForm extends Model
{
public $age;
public function rules(){
return [
['age', 'my_validation']
];
}
public function my_validation(){
//some code here
}
}

Посмотреть:

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;$this->title = 'test';
?>
<div style="margin-top: 30px;">

<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'age')->label("age") ?>
<div class="form-group">
<?= Html::submitButton('submit', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>

</div>

контроллер:

use app\models\form\TestForm;
use yii\web\Controller;

class TestController extends Controller
{
public function actionIndex(){
$model = new TestForm();

if($model->load(\Yii::$app->request->post())){
return $this->render('test', array(
'model'=>$model,
'message'=>'success'
));
}
return $this->render('test', array('model'=>$model));
}
}

в этом примере у меня есть поле для возраста, и это my_validation Функция должна проверить, если возраст старше 18 лет, перед отправкой и выдать ошибку, если возраст меньше 18 лет. Эта проверка должна обрабатываться ajax, как и в случае required правило, если вы пытаетесь отправить пустое поле.

0

Решение

Хотя вы можете использовать Conditional Validators when а также whenClient тоже в вашем сценарии, но я бы порекомендовал использовать более сложный способ, который заключается в определении пользовательского валидатора, потому что в соответствии с документами

Чтобы создать валидатор, который поддерживает валидацию на стороне клиента, вы должны
реализовать yii\validators\Validator::clientValidateAttribute()
метод, который возвращает кусок кода JavaScript, который выполняет
проверка на стороне клиента. В коде JavaScript вы можете использовать
следующие предопределенные переменные:

attribute: имя проверяемого атрибута.

value: значение проверяется.

messages: массив, используемый для хранения сообщений об ошибках валидации для атрибута.

deferred: массив, в который могут быть помещены отложенные объекты (объяснение в следующем подразделе).

Итак, вам нужно создать валидатор и добавить его в ваши правила для поля, которое вы хотите.

Вы должны быть осторожны, копируя следующий код ЕСЛИ Вы не указали фактическое название модели и соответственно изменили имена полей.

1) Первое, что нужно сделать, это обновить ActiveForm виджет к следующему

$form = ActiveForm::begin([
'id' => 'my-form',
'enableClientValidation' => true,
'validateOnSubmit' => true,
]);

2) Измени свою модель rules() функция к следующему

public function rules()
{
return [
[['age'], 'required'],
[['age'], \app\components\AgeValidator::className(), 'skipOnEmpty' => false, 'skipOnError' => false],
];
}

3) Удалить пользовательскую функцию проверки my_validation() от вашей модели, я надеюсь, что вы проверяете возрастное ограничение в нем, чтобы быть 18+ мы переместим эту логику в валидатор.

Теперь создайте файл AgeValidator.php внутри components каталог, если вы используете basic-app добавить папку components внутри корневого каталога проекта, если он не существует, создайте новый и скопируйте в него следующий код.

НО

Я принял название модели, предоставленной вами выше, поэтому, если это не фактическое имя, вы должны обновить имя поля внутри javascript заявления в clientValidateAttribute функция, которую вы видите ниже в валидаторе, потому что id атрибут полей в ActiveForm генерируется в формате как #modelname-fieldname (все в небольшом случае), поэтому в соответствии с приведенной выше моделью, это будет #testform-age обновите его соответственно, иначе проверка не будет работать. И обновите пространство имен в валидаторе ниже и в модели rules() если вы планируете сохранить его в другом месте.

<?php

namespace app\components;

use yii\validators\Validator;

class AgeValidator extends Validator
{

public function init()
{
parent::init();
$this->message = 'You need to be above the required age 18+';
}

public function validateAttribute($model, $attribute)
{

if ($model->$attribute < 18) {
$model->addError($attribute, $this->message);
}
}

public function clientValidateAttribute($model, $attribute, $view)
{

$message = json_encode($this->message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
return <<<JS

if (parseInt($("#testform-age").val())<18) {
messages.push($message);
}
JS;
}

}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]