validate nested forms without affecting the parent form
Asked Answered
M

2

6

There is a validation problem in the nested forms in angularjs 1.5 and there is an issue in github about it.

but 2 people in that topic offer the solution and one of them has open its way to the angularjs core which is ngFormTopLevel directive, and the other one offered by a user called isolate-form.

but neither of them can handle this situation and not working for me ... at least !

lets assume this structure:

<ng-form name="X1" novalidate>

    <ng-form name="X2" novalidate isolate-form>

        <input name="Input01" ng-model="input1" required />
        <p ng-show="X2.Input01.$touched && X2.Input01.$invalid">input is not valid</p>

        <input name="Input02" ng-model="input2" required />

        <input type="button" id="ButtonX2" value="Submit Nested Form" ng-disabled="X2.$invalid" />

    </ng-form>

<input name="Input03" ng-model="input3" required ng-minlength="5" />

<input type="button" id="ButtonX1" value="Submit Nested Form" ng-disabled="X1.$invalid" />

</ng-form> 

tl;dr : ButtonX1 is dependent on nested form validation and it shouldn't !


Test case 1:

Step 1: Fill input3 with any text and more than 5 character.

Expected: ButtonX1 should be enable.

Result: ButtonX1 still disabled.


Test case 2:

Step 1: Fill input1 with any text.

Step 2: Fill input2 with any text.

Expected: ButtonX2 should be enable.

Result: ButtonX2 is enabled.


Test case 3:

Step 1: Fill input3 with any text and more than 5 character.

Step 2: Fill input1 with any text.

Step 2: Fill input2 with any text.

Expected: ButtonX1 and ButtonX2 should be enable.

Result: ButtonX1 and ButtonX2 is enabled.


and the other problem is the P tag inside the nested form does not show when the Input01 is invalid. I tried both the isolateForm and the ngFormTopLevel but both of them have this problem.

Merril answered 21/6, 2016 at 7:51 Comment(2)
Please check out this fiddle with the code above + the isolate-form directive. Unless I did not understand the details of the question, it does behave as you expect! Also see docs for $touched: "True if control has lost focus." This means that when you first enter the Input01 and type something invalid (I added a ng-minlength="2" constraint) the error message will NOT show because the control has not yet lost focus, thus it is considered untouched (inconvenient implementation from Angular IMO, but definitely according to specs).Decency
Awesome! thank you for the fiddle. it fixed my problem. please update your answer and provide the fiddle in there too so i can mark it as an answer. also update your html too. by the way here is my fiddle too. jsfiddle.net/HosnaSoft/90yf5tco/1Merril
V
2

I think this is the solution as per your requirement.

<ng-form name="X1" novalidate>

        <ng-form name="X2" novalidate isolate-form>

            <input name="Input01" ng-model="input1" required />
            <p ng-show="X2.Input01.$invalid && X2.Input01.$touched">input is not valid</p>

            <input name="Input02" ng-model="input2" required />

            <input type="button" id="ButtonX2" value="Submit Nested Form" ng-disabled="X2.$invalid" />

        </ng-form>

        <input name="Input03" ng-model="input3" required ng-minlength="5" />

        <input type="button" id="ButtonX1" value="Submit Nested Form" ng-disabled="X1.Input03.$invalid" />

    </ng-form>
Vanscoy answered 23/6, 2016 at 11:30 Comment(2)
i see what you did there. but there might be a lot of inputs like Input03 in X1. consider that.Merril
isolate-form looks like not working. Also saw someone mentioning that in the github of the projectShaveling
M
3

It would seem the only thing needed is to call $removeControl on the parent form controller. This very simple directive has been working for me. Apply to your ng-form.

function isolateFormDirective () {
    return {
        restrict: 'A',
        require: ['form', '^form'],
        link: function(scope, element, attrs, forms) {
            forms[1].$removeControl(forms[0]);
        }
    }
}

export default isolateFormDirective;
Malvie answered 16/3, 2017 at 14:19 Comment(0)
V
2

I think this is the solution as per your requirement.

<ng-form name="X1" novalidate>

        <ng-form name="X2" novalidate isolate-form>

            <input name="Input01" ng-model="input1" required />
            <p ng-show="X2.Input01.$invalid && X2.Input01.$touched">input is not valid</p>

            <input name="Input02" ng-model="input2" required />

            <input type="button" id="ButtonX2" value="Submit Nested Form" ng-disabled="X2.$invalid" />

        </ng-form>

        <input name="Input03" ng-model="input3" required ng-minlength="5" />

        <input type="button" id="ButtonX1" value="Submit Nested Form" ng-disabled="X1.Input03.$invalid" />

    </ng-form>
Vanscoy answered 23/6, 2016 at 11:30 Comment(2)
i see what you did there. but there might be a lot of inputs like Input03 in X1. consider that.Merril
isolate-form looks like not working. Also saw someone mentioning that in the github of the projectShaveling

© 2022 - 2024 — McMap. All rights reserved.