Я хочу сделать пользовательские функции проверки, такие как встроенная проверка 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
правило, если вы пытаетесь отправить пустое поле.
Хотя вы можете использовать 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;
}
}
Других решений пока нет …