AJAX validation does not work for array element fields within attributes if no "each" rule has been specified.
What steps will reproduce the problem?
Create a model that utilizes an array for input, and put a form that references the first key of this array. Add a custom validation rule that loops through and does your own validation. (This was necessary for me as the rule was concerned with the sum of all the values.) Enable AjaxValidation on the ActiveForm using the standard procedure.
What is the expected result?
When changing or selecting the field, the client should attempt to validate the input with the server.
What do you get instead?
The client does not attempt to validate the value.
Additional info
| Q | A |
|---|---|
| Yii version | 2.0.6 |
| PHP version | 7.0.33 |
| Operating system | Ubuntu 16.04.16 |
Would you please provide some code to reproduce it?
Would you please provide some code to reproduce it?
create a model class with the following code contained:
public $this_is_an_array = [];
public function rules()
{
return [
["this_is_an_array", "my_array_validator"]
];
}
public function my_array_validator()
{
$total = 0;
foreach ($this->this_is_an_array as $oneElement)
{
$total += $oneElement;
}
if ($total > 10)
{
$this->addError("this_is_an_array", "The total is too high!");
}
}
then, in the view, put multiple inputs within the form:
$form = ActiveForm::begin([
"enableAjaxValidation" => true,
"enableClientValidation" => false, // always do this...
"validationUrl" => ["controller/myaction"],
]);
echo $form->field($model, "this_is_an_array[0]");
echo $form->field($model, "this_is_an_array[1]");
echo Html::submitButton();
ActiveForm::end();
Alright. Looks like a bug. What you expect sounds like correct behavior.
Any idea about the fix?
Alright. Looks like a bug. What you expect sounds like correct behavior.
Any idea about the fix?
Well, I'm not intimately familiar with the "under the hood" of Yii2's validation, particularly when we talk about javascript, but it seems like a pretty easy fix.
In particular, if you inspect these fields in the inspector, no javascript event has been tied to them. This would suggest that yii2 only applies validation events to array inputs if there is an "each" rule. Sounds like this condition should be changed to if the attribute is an array or not.
For now, my fix in the app was add ["this_is_an_array", "each", "rule" => ["safe"]].