OnsenUI | Form Handling And Validation

Written by on April 9, 2015

OnsenUI | Form Handling And Validation

I would like to use this article to talk about OnsenUI form handling and validation. I will demonstrate it by building a simple login application, it’s simply one of an easiest examples of form manipulations.

Form handling in OnsenUI is straightforward as it gets; I will talk about it briefly. On the other hand, form validation is a completely different story. Simple out of the box solution didn’t exist before AngularJS 1.3.0. Before that time, you could have used countless custom angular directives, but each solution had its set of rules and problems.

Angular 1.3.0 came and gave us a ngMessages module. This module provides enhanced support for displaying messages within templates (typically within forms or when rendering message objects that return key/value data). Instead of relying on JavaScript code and/or complex ng-if statements within your form template to show and hide error messages specific to the state of an input field, the ngMessages and ngMessage directives are designed to handle the complexity, inheritance and priority sequencing based on the order of how the messages are defined in the template.

Note: If this tutorial was helpful, you need further clarification, something is not working or you have a request for another Ionic post? Furthermore, leave me a comment below if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com. Thanks and have a nice day!

Table of Contents

[spoiler title=” Click here if you want to see other tutorials, this is the 10th tutorial out of 12 total.”]

[/spoiler]

Example

Just like in my previous articles I will start with working example. Below you’ll find a direct link to working Plnkr example, or you can play with it directly in an embedded application.

Demo

Embedded working example

OnsenUI form handling and validation example

HTML:

<html>

<head>
  <script src="https://code.angularjs.org/1.3.0/angular.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular-messages.min.js"></script>    
  <script src="http://onsenui.io/OnsenUI/build/js/onsenui.js"></script>
  <script src="script.js"></script>
  <link rel="stylesheet" href="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.2.2/build/css/onsenui.css" />
  <link rel="stylesheet" href="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.2.2/build/css/onsen-css-components.css" />
  <link rel="stylesheet" href="style.css" />
</head>

<body ng-controller="ListCtrl">

  <ons-navigator animation="slide" var="app.navi">
    <ons-page>
      <ons-toolbar class="toolbar-black">
        <div class="center">First Page</div>
      </ons-toolbar>
      <h2 style="text-align: center;">Form handling and validation example</h2><br/>

      <form name="authorizationForm" novalidate="" ng-submit="signIn(authorizationForm)"> 

        <ul class="list">
          <li class="list__header">Enter an Email Adress</li>
        </ul>
        <input type="text" 
               name="email" 
               value="" 
               ng-model="authorization.email" 
               ng-minlength="5" 
               ng-maxlength="40" 
               ng-pattern="/^[_a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/" 
               required 
               ng-class="{ 'has-errors' : authorizationForm.email.$invalid, 'no-errors' : authorizationForm.email.$valid}" 
               ng-messages-include="error-list.html" 
               placeholder="Enter an Email Adress" 
               class="text-input text-input--underbar" 
               style="width: 96%; margin: 2%;">
  
        <div class="error-container" ng-show="authorizationForm.email.$error" ng-messages="authorizationForm.email.$error" ng-messages-include="error-list.html">
        
        </div>     
  
        <ons-row class="profile-wrapper" style="padding: 10px;">
          <button class="button button--large--cta" type="submit">Retrieve Password</button>
        </ons-row>    

      </form>     
     
    </ons-page>   
  </ons-navigator>    
   
  <ons-template id="view.html">
    <ons-page ng-controller="ViewCtrl">
      <ons-toolbar>
        <div class="left" style="line-height: 44px">
          <ons-back-button>Back</ons-back-button>
        </div>        
        <div class="center">Second Page</div>
      </ons-toolbar>

      <h3 style="padding: 10px;">You have sucesfully validated application form</h3>

    </ons-page>
  </ons-template>
  
  <ons-template id="error-list.html">  
    <div class="error" ng-message="required">
      <i class="ion-information-circled"></i> 
      This field is required!
    </div>
    <div class="error" ng-message="minlength">
      <i class="ion-information-circled"></i> 
      Minimum length of this field is 5 characters!
    </div>
    <div class="error" ng-message="maxlength">
      <i class="ion-information-circled"></i> 
      Maximum length of this field is 40 characters!
    </div>
    <div class="error" ng-message="pattern">
      <i class="ion-information-circled"></i> 
      Wrong email pattern!
    </div>  
  </ons-template>    
  
</body>
</html>

JavaScript:

var module = ons.bootstrap('my-app', ['onsen', 'ngMessages']);

module.controller('ListCtrl', function($scope) {

  $scope.authorization = {
    email: ''
  };  
  
  $scope.signIn = function(form) {
    if(form.$valid) {
      app.navi.pushPage("view.html", { animation: "lift"});
    }
  }; 
  
});

module.controller('ViewCtrl', function($scope) {
  
});

CSS:

.error-container {
  margin: 5px 0;
}

.error {
  padding: 10px 16px;
  font-family: "Arial Black", Gadget, sans-serif;
  font-size: 11px;
  text-transform: uppercase;
  color: #555;
  vertical-align: middle;
}

.error i {
  font-size: 24px;
  color: #B83E2C;  
  vertical-align: middle;
}

.has-errors {
  border-bottom: 3px solid #B83E2C !important;
}

.no-errors {
  border-bottom: 3px solid green !important;
}

Before form is submitted

Before we can do anything we need to inject ngMessages module into our application (don’t forget to initialize angular-messages.js file before):

var module = ons.bootstrap('my-app', ['onsen', 'ngMessages']);

An application will have one input field (email) and one submit button. When form loads, application will automatically validate an email field while click on a submit button will initiate a manual form validation process.

Let’s see what’s happening in email field (it will be validated after application is successfully initialized):

<form name="authorizationForm" novalidate="" ng-submit="signIn(authorizationForm)"> 

	<ul class="list">
		<li class="list__header">Enter an Email Adress</li>
	</ul>
	<input type="text" name="email" value="" ng-model="authorization.email" ng-minlength="5" ng-maxlength="40" ng-pattern="/^[_a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/" required ng-class="{ 'has-errors' : authorizationForm.email.$invalid, 'no-errors' : authorizationForm.email.$valid}" ng-messages-include="error-list.html" placeholder="Enter an Email Adress" class="text-input text-input--underbar" style="width: 96%; margin: 2%;">

	<div class="error-container" ng-show="authorizationForm.email.$error" ng-messages="authorizationForm.email.$error" ng-messages-include="error-list.html">

	</div>     

	<ons-row class="profile-wrapper" style="padding: 10px;">
		<button class="button button--large--cta" type="submit">Retrieve Password</button>
	</ons-row>    

</form> 

Form must have a name attribute. It should also have a function that will be called during a form submit event:

<form name="authorizationForm" novalidate="" ng-submit="signIn(authorizationForm)"> 

Every field will need to be set manually depending on application needs. This article example will cover four checks:

  1. requirement
  2. min length
  3. max length
  4. correct email pattern

They should look like this:

<input type="text" 
       name="email" 
	   value="" 
	   ng-model="authorization.email" 
	   ng-minlength="5" 
	   ng-maxlength="40" 
	   ng-pattern="/^[_a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/" 
	   required 
	   ng-class="{ 'has-errors' : authorizationForm.email.$invalid, 'no-errors' : authorizationForm.email.$valid}" 
	   ng-messages-include="error-list.html" 
	   placeholder="Enter an Email Adress" 
	   class="text-input text-input--underbar" 
	   style="width: 96%; margin: 2%;">

Separate template will hold our error messages. There will be four of them, one per field check:

<ons-template id="error-list.html">  
	<div class="error" ng-message="required">
		<i class="ion-information-circled"></i> 
		This field is required!
	</div>
	<div class="error" ng-message="minlength">
		<i class="ion-information-circled"></i> 
		Minimum length of this field is 5 characters!
	</div>
	<div class="error" ng-message="maxlength">
		<i class="ion-information-circled"></i> 
		Maximum length of this field is 40 characters!
	</div>
	<div class="error" ng-message="pattern">
		<i class="ion-information-circled"></i> 
		Wrong email pattern!
	</div>  
</ons-template> 

By default, ngMessages will only display one error at a time. However, if you wish to display all messages then the ng-messages-multiple attribute flag can be used on the element containing the ngMessages directive to make this happen.

Continue Reading

Categories

Leave a Reply