Suppose I have the following set up for my LoginForm rules:
public function rules()
{
return [
// username and password are both required
[['username', 'password'], 'required'],
// username should be a number and of 8 digits
['username', 'is8NumbersOnly'],
// password is validated by validatePassword()
['password', 'validatePassword'],
];
}
public function is8NumbersOnly($attribute)
{
if (!preg_match('/^[0-9]{8}$/', $this->$attribute)) {
$this->addError($attribute, 'Must contain exactly 8 digits.');
}
}
// The following is default stuff in Yii2
public function validatePassword($attribute, $params)
{
if (!$this->hasErrors()) {
$user = $this->getUser();
if (!$user || !$user->validatePassword($this->password)) {
$this->addError($attribute, 'Incorrect username or password.');
}
}
}
Note that pretty much the only thing I changed compared to the original advanced/backend template is adding the new custom validator [font="Courier New"]is8NumbersOnly[/font].
My problem is that when I try to submit the login form, it simply ignores whatever I put into the [font="Courier New"]username[/font] field, except of course that it has to have a value (controlled by [font="Courier New"]required[/font]).
I tried using [font=“Courier New”]skipOnEmpty = false[/font], but that didn’t change anything. Implementing a scenario however made it work, but only if the only field included in the scenario was the [font=“Courier New”]username[/font] field. Once I added the [font=“Courier New”]password[/font] field too, the new custom validator [font=“Courier New”]is8NumbersOnly[/font] stopped working (no validation has been made against it anymore, ie. anything passed).
I now understand that this is because customValidators set up this way will not trigger on client-side unless a separate custom Validator class is created.
Sample code:
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()],
];
}
// ...