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.

M.R.Safari
  • 1,857
  • 3
  • 30
  • 47
  • 2
    Please check out [this fiddle](https://jsfiddle.net/zrbjvxew/1/) 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). – Nikos Paraskevopoulos Jun 23 '16 at 21:29
  • 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. https://jsfiddle.net/HosnaSoft/90yf5tco/1/ – M.R.Safari Jun 25 '16 at 08:52

2 Answers2

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;
Sam
  • 1,725
  • 1
  • 17
  • 28
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>