问题描述
登录表单:
公共函数规则(){返回 [//用户名和密码都需要[['用户名', '密码'], '必填'],//用户名应该是一个数字和 8 位数字[['username'], 'number', 'message'=>'{attribute} 必须是数字'],[['用户名'], '字符串', '长度' =>8],//密码由validatePassword() 验证['密码','验证密码'],];}/*** 验证密码.* 此方法用作密码的内联验证.** @param string $attribute 当前正在验证的属性* @param array $params 规则中给出的附加名称-值对*/公共函数validatePassword($attribute, $params){如果 (!$this->hasErrors()) {$user = $this->getUser();if (!$user || !$user->validatePassword($this->password)) {$this->addError($attribute, '用户名或密码不正确.');}}}
我为上面看到的同一个字段设置了 2 条规则:
[['username'], 'number', 'message'=>'{attribute} 必须是数字'],[['用户名'], '字符串', '长度' =>8],
我希望表单针对以下 3 个情况显示不同的错误消息:
- 提供的值既不是数字,也不是 8 个字符(数字).
- 提供的值是一个数字,但不是 8 个字符(数字).
- 提供的值不是数字,而是 8 个字符(数字).
我的问题是 2 折:
A.有没有办法以任何标准,Yii2
方式组合这些规则.
B. 在我之前的问题中,我尝试设置自定义验证器(解决此问题的显而易见的方法),但它很简单地被忽略了.我可以使其验证的唯一方法是将 username
字段添加到场景中.但是,一旦我也添加了 password
,它又被忽略了.你能想到的任何原因吗? situations:
- The provided value is neither a number, nor 8 characters (digits).
- The provided value is a number, but is not of 8 characters (digits).
- The provided value is not a number, but is of 8 characters (digits).
My question is 2 fold:
A. Is there a way to combine these rules in any standard, Yii2
way.
B. In my previous question I have tried to set up a custom validator (the obvious way to solve this), but it was very simply ignored. The only way I could make it validate was if I added the username
field to a scenario. However, once I added password
too, it was again ignored. Any reason's for this that you can think of? EDIT: skipOnError = false
changed nothing at all in this behaviour.
So please, when you answer, make sure you test it preferably in yii2/advanced
; I barely touched the default set up, so it should be easy to test.
EDIT: for clarity, I would like to only allow numbers that are of 8 characters (digits), so they can potentially have a leading 0
, eg. 00000001
, or 00000000
for that matter. This is why it has to be a numeric string.
The best way to combine rules and display custom error messages for different situations is to create a custom validator. Now if you want that to work on client-side too (it was one of my problems detailed in question B above, thanks to @Beowulfenator for the lead on this), you have to create an actual custom validator class extended from the yii2 native validator class.
Here is an example:
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:ActiveForm:在一个字段上组合规则/多重验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!