Yii2: yii.activeForm.js and dinamically fields validation.

Created on 4 Dec 2013  Â·  28Comments  Â·  Source: yiisoft/yii2

AJAX validation work fine for static fields, but if we'll try to add some fields dinamically with Javascript, they will not be validated on client side. I mean that error classes, and error messages will not be added to the page because for yii.ActiveForm they just not exist.
The problem is here:

...
$.each(attributes, function (i) {
    attributes[i] = $.extend({value: getValue($form, this)}, attributeDefaults, this);
});
$form.data('yiiActiveForm', {
    settings: settings,
    attributes: attributes,
    submitting: false,
    validated: false
});
...
var errors = [];
$.each(data.attributes, function () {
    if (updateInput($form, this, messages)) {
        errors.push(this.input);
    }
});
...
docs

All 28 comments

It would be convenient if there were more available functions. For example:
-update or check status in one field
-update or check validation of all fields
-create or delete validation rules on the client side.
It would also be nice to add support for ajax submit form (sorry, if I could not find issues).
This will build dynamic forms with support of framework as client side.

I often had to make a form in which one field is dependent on another. For example, if checkbox is checked, then the text field can not be empty and must be filled in a certain format.

So overall:

  1. Need docs about how to use yii.activeForm.js w/o active form widget.
  2. Need to make sure it actually can be used like so.

Need doc for #1958.

-create or delete validation rules on the client side.

How to add validations to dynamically added fields, how to remove validations from specific fields, for example, for non-visible (display: none;) fields?

Looked a bit into code. A form get initialized here:

jQuery(document).ready(function () {
     // TODO: add 'use strict'; if YII_ENV_DEBUG
     jQuery('#w0').yiiActiveForm({
          "field0": { /* ... */ },
          "field1": { /* ... */ },
     });
});

I think It is wrong outdated concept, those attributes for fields should be taken from declarative HTML, for example,

<div class="form-group active-field field-object-field0" data-validate='{"validation": "number", "params": {"message": "Please enter a number."}}' data-validate-on-change="0" data-validate-on-type="0" data-validation-delay="200">

Dynamically adding/removing fields is supported with https://github.com/yiisoft/yii2/commit/ae13b0593f9532f4ab6f8b02f7374422f5a71239.

What's left? Docs?

Yes, to be done in Getting Data from Users.

After last composer update yii activeform before submit saying
Unknown Property – yii\base\UnknownPropertyException

Setting unknown property: yii\widgets\ActiveForm::beforeSubmit

Please check the last few lines of the latest UPGRADE. There's BC-breaking change.

One concern about dynamic adding and removing field in active form.

suppose i have dynamic field widget to copy a field and place multiple copy below this.
so after i copy i tried to add filed, but this gives me some error as active form still not initialized.

this is because activefield initialize after form finished so.

is there any work around on add and initialize method so that is not yes initialize then it will put it in queue, and while initializing it add into activeform

I had this problem and achieve it after modification.

in init method

after

$form.data('yiiActiveForm', {
                    settings: settings,
                    attributes: attributes,
                    submitting: false,
                    validated: false
                });

i placed.

if(typeof $form.data('yiiActiveFormPre') != 'undefined'){
                    $.each($form.data('yiiActiveFormPre').attributes, function (i) {
                        $form.data('yiiActiveForm').attributes.push(this);
                        watchAttribute($form, this);
                    });
                }

add method:

var $form = $(this);
            attribute = $.extend({value: getValue($form, attribute)}, attributeDefaults, attribute);            
            try{
                $form.data('yiiActiveForm').attributes.push(attribute);
                watchAttribute($form, attribute);
            }catch(er){                
                if(typeof $form.data('yiiActiveFormPre') == 'undefined'){                    
                    var attributes = [];
                    attributes.push(attribute);
                    $form.data('yiiActiveFormPre', {
                        attributes: attributes,
                    });                    
                }else{
                    $form.data('yiiActiveFormPre').attributes.push(attribute);
                }
            }

regards
Mithun Mandal

@samdark @qiangxue @6pblcb @vova07 what is the correct method to validate dynamically added form fields of another model .I search all arround but i am not finding please help me out .what i use in js and correct method. http://stackoverflow.com/questions/31286133/yii2-add-dynamic-form-fields-and-their-validations

@samdark Thanks for the reply ,but do you have any doc how to use in my form
what i use in js and correct method. http://stackoverflow.com/questions/31286133/yii2-add-dynamic-form-fields-and-their-validations

Not yet.

@samdark Ok ,so do you provide me the solution i am stuck in this situation that how i validate my dynamic fields added . for example :i have form in which fields are dependent on dropdown change then the newly dynamic fields added are not validate properly .

I guess in this case you have to come up with custom validation coded in JS.

@samdark will you please provide me a simple example so that i can use it properly .
I am stuck in this situation . http://stackoverflow.com/questions/31286133/yii2-add-dynamic-form-fields-and-their-validations

@samdark i already did with custom js on many of my project but i am still finding the correct and best method for validate dynamically added fields in form.

@samdark can you please translate this http://habrahabr.ru/post/239147/ blog in English i am stuck in the same situation.

It's a big article. Will take time to translate it...

@gauravparashar12 use Chrome and google translate for http://habrahabr.ru/post/239147/ . It is decent translation

@gauravparashar12 and whoever else is looking for reason why and a simple solution for ajax added fields not triggering validation.

In your view or as per answer at http://stackoverflow.com/questions/31286133/yii2-add-dynamic-form-fields-and-their-validations do something like:

foreach ($form->attributes as $attribute) {
    $attribute = Json::htmlEncode($attribute);
    $this->registerJs("jQuery('form').yiiActiveForm('add', $attribute);");
}

The validation data is stored in the form and not the field. Therefore if you dynamically add fields and not the form you need to get the validation out of the ActiveForm on the server ($form->attributes) and add it into the form in the client.

@samdark, further to my last comment above re the commented problem described by @gauravparashar12 (not sure if the original issue was raised regarding fields created in javascript or added via ajax so could be a new issue).

Rather than documenting a solution (like my comment above), could it be worth considering altering ActiveField and ActiveForm suitably such that the 'attribute' validation object is stored with the field rather than in array within the form.

I haven't looked too deeply into the inner workings of ActiveForm and ActiveField but it would seem that perhaps the magic might happen by ActiveForm handling bubbled events raised on the fields (blur and change) and then using the array of attribute validation objects attached to a data element in the form to handle the event. Would it not be better to store the validation 'attribute' object with each field rather than in an array in the form?

If done this way then @gauravparashar12 and anybody else using ajax (pjax etc) to retrieve fields dynamically wouldn't need to do anything special (like above) - client validation would just work.

Closing since cookbook is now linked from validation guide.

@samdark @qiangxue
I use the $('$#w0').yiiActiveForm('add', 'xxx') and $('$#w0').yiiActiveForm('remove, 'xxx') , they did work and I can see the object changed in attributes, but there is no change on webpage, did I miss something or this function was not designed for dynamically add form field?

No. It is for adding validation only. No the field itself.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kminooie picture kminooie  Â·  3Comments

SamMousa picture SamMousa  Â·  3Comments

chaintng picture chaintng  Â·  3Comments

Kolyunya picture Kolyunya  Â·  3Comments

schmunk42 picture schmunk42  Â·  3Comments