1

I want to validate a group of inputs on my form. I don't need individual names, so I tried to use form.name.$valid to check all.

I pushed a number to a array to increment the number of inputs. The problem is when I remove an input the validity of the inputs become wrong.

Here is a fiddle showing this issue.

http://jsfiddle.net/n0w0cz4b/2/

To reproduce the problem, fill the first input. Inputs valid, form valid. Add an input and fill it too. Both valid again. Remove the last input, inputs invalid, form valid.

How can I validate using this type of dynamic form? I will need to use ng-form with individual messages even I want just one error message for all inputs?

3 Answers 3

1

Here is (a simlified version of) what is going on:

  1. When adding an input to the form, it "registers" itself as a form's control (which means it is taken into account when determining the form's validity).

  2. Additionally, it becomes available under formsName.inputsName. (Note, (2) is totally independent from (1), meaning that a control will still play a role in form's validity even if not accessible under formsName.inputsName.)

As a result of the above (and the fact that all inputs have the same name), only the last added input will be available under formsName.inputsName, but all inputs will be taken into account when determining the form's validity. Now, when the last input is removed, formsName.inputsName is "unset", thus formsName.inputsName.$valid/$invalid will always evaluate to a falsy value.


Summing up:

  • formsName.$valid/$invalid will always be accurate and reflect the actual validity state of the form (based on the currently present inputs).

  • formsName.inputsName.$valid/$invalid will either refer to the last input's validity state or be undefined (depending on which action was most recenty performed: adding an input vs removing an input).


BTW, it is always a good idea to use formsName.$error and/or formsName.inputsName.$error when debugging forms, since they are more informative than $valid/$invalid.
Optionally, combine with <pre> and the json filter for premium form-debugging experience ;)

E.g.: <pre>form.$error: {{ form.$error | json }}</pre>

Sign up to request clarification or add additional context in comments.

Comments

1

No idea why, but using !$invalid instead of $valid seems to work.

<p style="color : green" ng-show="!form.box.$invalid">Inputs are valid.</p>
<p style="color : red" ng-show="form.box.$invalid">Inputs are invalid.</p>
<p style="color : green" ng-show="!form.$invalid">Form is valid.</p>
<p style="color : red" ng-show="form.$invalid">Form is invalid.</p>

Who can explain how ($valid) != (!$invalid)?

3 Comments

Wow! This is weird. I will wait for answers, but it sounds like a bug to me.
There is another problem and even $invalid won't address it. Add two inputs. Fill the first and the last one. Inputs valid, form invalid.
@Rotem: As you said, it only seems to work. Hopefully my answer sheds some more light on what's going on :)
0

Problem is probably related to the fact that your generating multiple fields with the same name and then trying to address them all at once with that name.


form.$invalid

Should be used when checking the whole form while

form.aFieldName.$invalid

Should be used when addressing a specific field, and their for you should not give multiple field the same name.

I have created a updated version of your jsfiddle, that uses dynamicly generated names which allows you to address individual fields: http://jsfiddle.net/jenrikforlife/Lu4gwxww/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.