LoginForm:
public function rules() { return [ // username and password are both required [['username', 'password'], 'required'], // username should be a number and of 8 digits [['username'], 'number', 'message'=>'{attribute} must be a number'], [['username'], 'string', 'length' => 8], // password is validated by validatePassword() ['password', 'validatePassword'], ]; } /** * Validates the password. * This method serves as the inline validation for password. * * @param string $attribute the attribute currently being validated * @param array $params the additional name-value pairs given in the rule */ public function validatePassword($attribute, $params) { if (!$this->hasErrors()) { $user = $this->getUser(); if (!$user || !$user->validatePassword($this->password)) { $this->addError($attribute, 'Incorrect username or password.'); } } }
Я установил 2 правила для того же поля, как вы можете видеть выше:
[['username'], 'number', 'message'=>'{attribute} must be a number'], [['username'], 'string', 'length' => 8],
Я хотел бы, чтобы форма отображала различные сообщения об ошибках для следующих трех сценариев :
Мой вопрос в 2 раза:
A. Есть ли способ объединить эти правила в любом стандарте, Yii2
.
B. В моем предыдущем вопросе я попытался настроить пользовательский валидатор (очевидный способ его решения), но его очень просто игнорировали. Единственный способ, которым я мог бы проверить это, – это добавить поле username
в сценарий. Однако, как только я добавил password
, он снова проигнорировался. Есть ли причина для этого, о которой вы можете думать? EDIT : skipOnError = false
в этом поведении ничего не изменилось.
Поэтому, пожалуйста, когда вы отвечаете, убедитесь, что вы тестируете его предпочтительно в yii2/advanced
; Я едва коснулся настройки по умолчанию, поэтому ее легко проверить.
EDIT : для ясности я хотел бы разрешить только числа, состоящие из 8 символов (цифр), поэтому они потенциально могут иметь ведущее 0
, например. 00000001
или 00000000
на то пошло. Вот почему это должна быть числовая строка.
Наконец вам нужно это:
Поэтому вы должны просто попробовать:
['username', 'required'], ['username', 'string', 'min' => 8, 'max' => 8], ['username', 'match', 'pattern' => '/^[0-9]{8}$/', 'message'=>'{attribute} must be a number'],
Лучший способ объединить правила и отображать собственные сообщения об ошибках для разных ситуаций – создать настраиваемый валидатор. Теперь, если вы хотите, чтобы это работало и на стороне клиента (это была одна из моих проблем, подробно описанная в вопросе B выше, благодаря @Beowulfenator для этого), вы должны создать фактический пользовательский класс проверки, расширенный из родства yii2 класс валидатора.
Вот пример:
CustomValidator.php
<?php namespace app\components\validators; use Yii; use yii\validators\Validator; class CustomValidator extends Validator { public function init() { parent::init(); } public function validateAttribute($model, $attribute) { $model->addError($attribute, $attribute.' message'); } public function clientValidateAttribute($model, $attribute, $view) { return <<<JS messages.push('$attribute message'); JS; } }
LoginForm.php
<?php namespace common\models; use Yii; use yii\base\Model; use app\components\validators\CustomValidator; /** * Login form */ class LoginForm extends Model { public $username; public $password; public $custom; private $_user; /** * @inheritdoc */ public function rules() { return [ // username and password are both required [['username', 'password'], 'required'], // username should be a number and of 8 digits [['username'], 'number', 'message'=>'{attribute} must be a number'], [['username'], 'string', 'length' => 8], // password is validated by validatePassword() ['password', 'validatePassword'], ['custom', CustomValidator::className()], ]; } // ...
login.php
<?php /* @var $this yii\web\View */ /* @var $form yii\bootstrap\ActiveForm */ /* @var $model \common\models\LoginForm */ use yii\helpers\Html; use yii\bootstrap\ActiveForm; $this->title = 'Login'; ?> <div class="site-login text-center"> <h1><?php echo Yii::$app->name; ?></h1> <?php $form = ActiveForm::begin([ 'id' => 'login-form', 'fieldConfig' => ['template' => "{label}\n{input}"], 'enableClientValidation' => true, 'validateOnSubmit' => true, ]); ?> <?= $form->errorSummary($model, ['header'=>'']) ?> <div class="row"> <div class="col-lg-4 col-lg-offset-4"> <div class="col-lg-10 col-lg-offset-1"> <div style="margin-top:40px"> <?= $form->field($model, 'username') ?> </div> <div> <?= $form->field($model, 'password')->passwordInput() ?> </div> <div> <?= $form->field($model, 'custom') ?> </div> <div class="form-group" style="margin-top:40px"> <?= Html::submitButton('Login', ['class' => 'btn btn-default', 'name' => 'login-button']) ?> </div> </div> </div> </div> <?php ActiveForm::end(); ?> </div>
Yii2 игнорирует ваши правила проверки, потому что вы дублируете не только атрибуты, но и типы. При проверке числа, я думаю, вы должны использовать параметр min / max для проверки длины номера.
Для этого случая:
'min'=>10000000,'max'=>99999999