Yii2 custom validator does not work as a guide.
I've searched here for a while today, but I can't figure out why my validators are not working in my model.
I have a module with a Page model in my code below.
I have 2 attributes that I need to use to validate the model. These are hero_link and hero_linked. If hero_linked is true I want to have a hero_link.
In the manual here , they explain the correct syntax for this validator
I have used this syntax in my model, but it is not validated as I expected. I added a whenClient property so I can use client side validation here.
my corresponding code is below:
// Page model
namespace common\modules\page\models;
use Yii;
class Page extends \yii\db\ActiveRecord
{
public function rules()
{
return [
[['hero_linked',], 'boolean'],
[['hero_linked',], 'required'],
[['hero_link',], 'string', 'max' => 255],
[
'hero_link',
'required',
'when' => function($model) {
return $model->hero_linked == true;
},
'whenClient' => "function (attribute, value) {
return $('#page-hero_linked').val() == '1';
}",
],
];
}
}
// _form view
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'hero_linked')->checkbox() ?>
<?= $form->field($model, 'hero_link')->textInput(['maxlength' => 255]) ?>
<?php ActiveForm::end(); ?>
The required validator is being applied correctly, but it seems to ignore the when property and requires it even if my checkbox is not checked. Is my syntax incorrect or am I missing the requirement? Any help is appreciated, thanks in advance!
source to share
I think this is what you want. First use the "checked" property on the whenClient from the input field to get if the checkbox is checked or not.
The hidden checkbox field is not a problem.
Checking the hero_link (textinput) field when changing the checkbox uses the whenClient parameter in hero_linked (checkbox). So, you can immediately see if hero_link (textinput) is required or not.
You don't need any extra js code in your form if you use these rules.
But as you can also see that because of the full name "page-something" this is really only fixed for the "page" model, and I think it also depends on the form name. Therefore you have to use some other fixed "id" for both fields in form.php, so this will also work if you add your page model to a different class.
[
'hero_linked', 'required',
'whenClient' => "function (attribute, value) {
$('form').yiiActiveForm('validateAttribute', 'page-hero_link');
return true;
}",
],
[['hero_link',], 'string', 'max' => 255],
[
'hero_link', 'required', 'when' => function ($model) {
return $model->hero_linked == true;
},
'whenClient' => "function (attribute, value) {
return $('#page-hero_linked').prop('checked');
}",
],
source to share
I found out how to make this work. If you are using a checkbox, you cannot use only server or client side validation. I had to use both when and whenClient. I needed to register a script in my view for the checked attribute to update the checkbox.
$('label > #page-hero_linked').click(function(event) {
var checked = $(this).attr('checked');
if (checked) {
$(this).removeAttr('checked');
}else{
$(this).attr('checked', '');
};
});
and below is my check rule.
[['hero_link'],
'required',
'when' => function($model) {
return $model->hero_linked == true;
},
'whenClient' => "function (attribute, value) {
return $('#page-hero_linked').attr('checked');
}",],
All in all, pretty simple code to get it to work, but not obvious to me that this is required from the docs.
source to share