Closed SilverFire closed 4 years ago
+1
:+1:
:+1:
Any ideas, team?
Verified :)
Duplicated in https://github.com/yiisoft/yii2/issues/10230
Thanks @SilverFire for your assistance in #10230. Any idea on how to solve it?
Any ideas how to fix it? I thought before, that current client validation design may be enhanced. The main problem is that we are converting attribute names to IDs and get different problems:
I think that the most reliable option is to:
data-attribute
to each input <input name="User[0][id]" data-attribute="id" />
model-item
to disambiguate pointing on inputs.For example:
<form>
<div class="model-item" data-id="0" data-model="User">
<input name="User[0][login]" data-attribute="login" />
<input name="User[0][name]" data-attribute="name" />
</div>
<div class="model-item" data-id="1" data-model="User">
<input name="User[1][login]" data-attribute="login" />
<input name="User[1][name]" data-attribute="name" />
</div>
</form>
Then, for example, we can easily add the following rule:
[['name'], 'required', 'whenClient' => "function (value, attribute) {
return $(attribute).closest('.model-item').find('[data-attribute=login]').val().length > 0;
}"]
Of course, it will be easier to access login
attribute of the current model-item
with a proper support in yii.activeForm
. For example: attribute.model.getInput('name').val().length > 0
It's a draft. Your thoughts? @yiisoft/core-developers
That's good idea. For 2.1 I've planned to make all Yii JS static so no JS is dynamically added to the page and data-
attributes are used for everything.
@SilverFire, I've tried your solution but I can't get it to work.
My view:
<?php foreach($items as $i=>$item): ?>
<tr class="model-item" data-id="<?= $i ?>">
<td><?= $form->field($item,"[$i]quantity_start")->textInput(['data-attribute' => 'quantity_start'])->label(false); ?></td>
<td><?= $form->field($item,"[$i]quantity_end")->textInput(['data-attribute' => 'quantity_end'])->label(false); ?></td>
</tr>
<?php endforeach; ?>
My model's validation:
[['quantity_end'], 'compare', 'compareAttribute' => 'quantity_start', 'operator' => '<=', 'type' => 'number',
'whenClient' => "function (value, attribute) {
console.log($(attribute).closest('.model-item').find('[data-attribute=quantity_start]').val());
}"],
I get undefined
in my console.
What I'm doing wrong?
Not going to implement client validation itself in this package.
In case of using form fields with prefixed attributes, the ID of input will be
model-prefix-attribute
(for example bellowuser-0-password
). During the generation of client validation JS inCompareValidator
, thecompareAttribute
(which have to contain ID of target input) will be set tomodel-password
instead ofmodel-0-password
(seeCompareValidator.php:219
), so the JS will generate false errors during the validation.view.php:
model.php:
Workaround: set
enableClientValidation
tofalse
in model and use ajax validation withActiveForm::validateMultiple
And I don't know, how to pass full attribute with prefix form
ActiveForm
toCompareValidator