4

I am using AngularJS 1.5, ui-router for state management and ngMessages for validation and ngMaterial for UI. I have one main view contained in myformView.html and I load inside it two states (firstPartView.html and secondPartView.html).

I followed this tutorial to create multi-step form.

myformView.html:

   <form name="vm.myForm" ng-submit="vm.submit()">

       <div data-ui-view></div>

   </form>

firstPartView.html:

  <md-input-container class="md-block" flex-gt-sm>
   <label>First name (required)</label>
   <input name="firstName" ng-model="vm.user.firstName" ng-pattern="/^[a-zA-Z0-9]*$/" required>
   <div ng-messages="vm.myForm.firstName.$error" ng-show="vm.myForm.firstName.$touched">
  div ng-message="required">Your first name is required!</div>
div ng-message="pattern">Your first name should only contains valid characters!</div>
 </div>

secondPartView.html:

<md-button type="submit" ng-disabled="vm.myForm.$invalid" class="md-primary md-raised">Sign up</md-button>
<md-button type="reset" ng-click="vm.resetForm()" class="md-primary">Reset</md-button>

State Handling:

 .state("registration", {
                      url: "/register",
                      templateUrl: "app/register/myformView.html",
                      controller: "myformController as vm"
                  })
                      .state("registration.first", {
                          url: "/first",
                          templateUrl: "app/register/firstPartView.html.html"
                      })
                      .state("register.second", {
                          url: "/second",
                          templateUrl: "app/register/secondPartView.html"
                      })

Now the validation is not applied correctly and I don't know if this is due to multi-step form or not? For example, if the user didn't input anything in the first name input, the submit button should be disabled due to

ng-disabled="vm.myForm.$invalid"

but this is not happening, any help?

Update:

I want to mention that the example I wrote above is too lightweight of an example for my real code, so I tried to do that below:

 <div data-ui-view></div>

 <pre ng-bind="vm.myForm | json"></pre>

Typing this generated too large of a JSON object for the first view.


THE OUTPUT:


First View:

    {
  "$error": {
    "required": [
      {
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [
          null
        ],
        "$formatters": [
          null,
          null
        ],
        "$viewChangeListeners": [],
        "$untouched": true,
        "$touched": false,
        "$pristine": true,
        "$dirty": false,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "required": true
        },
        "$name": "firstName",
        "$options": null
      },
      {
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [
          null
        ],
        "$formatters": [
          null,
          null
        ],
        "$viewChangeListeners": [],
        "$untouched": true,
        "$touched": false,
        "$pristine": true,
        "$dirty": false,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "required": true
        },
        "$name": "lastName",
        "$options": null
      },
      {
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [
          null
        ],
        "$formatters": [
          null,
          null
        ],
        "$viewChangeListeners": [],
        "$untouched": true,
        "$touched": false,
        "$pristine": true,
        "$dirty": false,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "required": true
        },
        "$name": "email",
        "$options": null
      }
    ]
  },
  "$name": "vm.myForm",
  "$dirty": false,
  "$pristine": true,
  "$valid": false,
  "$invalid": true,
  "$submitted": false,
  "profilePicture": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [
      null
    ],
    "$formatters": [
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": true,
    "$invalid": false,
    "$error": {},
    "$name": "profilePicture",
    "$options": null
  },
  "firstName": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [
      null
    ],
    "$formatters": [
      null,
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": false,
    "$invalid": true,
    "$error": {
      "required": true
    },
    "$name": "firstName",
    "$options": null
  },
  "lastName": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [
      null
    ],
    "$formatters": [
      null,
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": false,
    "$invalid": true,
    "$error": {
      "required": true
    },
    "$name": "lastName",
    "$options": null
  },
  "email": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [
      null
    ],
    "$formatters": [
      null,
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": false,
    "$invalid": true,
    "$error": {
      "required": true
    },
    "$name": "email",
    "$options": null
  },
  "phoneNumber": {
    "$validators": {},
    "$asyncValidators": {},
    "$parsers": [
      null
    ],
    "$formatters": [
      null,
      null
    ],
    "$viewChangeListeners": [],
    "$untouched": true,
    "$touched": false,
    "$pristine": true,
    "$dirty": false,
    "$valid": true,
    "$invalid": false,
    "$error": {},
    "$name": "phoneNumber",
    "$options": null
  }
}

Second View:

{
  "$error": {},
  "$name": "vm.myForm",
  "$dirty": false,
  "$pristine": true,
  "$valid": true,
  "$invalid": false,
  "$submitted": false
}
fragilewindows
  • 1,394
  • 1
  • 15
  • 26
Marzouk
  • 2,650
  • 3
  • 25
  • 56
  • 1
    Do the following in your HTML and see what prints: `
    `.
    – developer033 Aug 07 '16 at 01:19
  • @developer033 i updated the question with the result please check .. – Marzouk Aug 07 '16 at 01:30
  • 1
    Maybe it could be useful: http://stackoverflow.com/questions/33702682/ui-router-nested-views-how-to-validate-a-shared-form // http://stackoverflow.com/questions/32765974/angularjs-multi-step-form-validation – developer033 Aug 07 '16 at 01:37

1 Answers1

0

You are missing the ng-form directive on the form element. It links all form elements even if they are not nested under the same form element by form name. Kind of confusing to explain. Check out the documentation for it for all the details. https://docs.angularjs.org/api/ng/directive/ngForm

great article with good examples

Doug Chamberlain
  • 11,192
  • 9
  • 51
  • 91