Sunday, February 12, 2017

Angular 2 - Forms

Description

In this chapter let us study how to create a form. We shall use the following classes and directives in our example.

  • The form-group, form-control and btn classes from Bootstrap.
  • The [(ngModel)] for data binding and NgControl directive to keep track of control state for us.
  • The NgControl is one among in NgForm directive family which is used for validation and tracking the form elements.
  • The ngSubmit directive is used for handling the submission of the form.

Example

The below example describes how to create a form in the Angular 2:
<html>
  <head>
    <title>Contact Form</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.6/angular2-polyfills.js"></script>
    <script src="https://code.angularjs.org/tools/system.js"></script>
    <script src="https://code.angularjs.org/tools/typescript.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.6/Rx.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.6/angular2.dev.js"></script>
    <script>
      System.config({
        transpiler: 'typescript',
        typescriptOptions: { emitDecoratorMetadata: true },
        packages: {'app': {defaultExtension: 'ts'}},
        map: { 'app': './app' }
      });
      System.import('app/form_main')
            .then(null, console.error.bind(console));
    </script>

  </head>
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>
The above code includes the following configuration options:
  • You can configure the index.html file using typescript version. The SystemJS transpile the TypeScript to JavaScript before running the application by using the transpiler option.
  • If you do not transpile to JavaScript before running the application, you could see the compiler warnings and errors which are hidden in the browser.
  • The TypeScript generates metadata for each and every class of the code when the emitDecoratorMetadata option is set. If you don't specify this option, large amount of unused metadata will be generated which affects the file size and impact on the application runtime.
  • Angular 2 includes the packages form the app folder where files will have the .ts extension.
  • Next it will load the main component file from the app folder. If there is no main component file found, then it will display the error in the console.
  • When Angular calls the bootstrap function in main.ts, it reads the Component metadata, finds the 'app' selector, locates an element tag named app, and loads the application between those tags.
To run the code, you need the following TypeScript(.ts) files which you need to save under the app folder.
form_main.ts
import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from "./forms_app.component";

bootstrap(AppComponent);
contact.ts
export class Contact {
  constructor(
    public firstname: string,
    public lastname: string,
    public country: string,
    public phone: number
  ) {  }
}
The Contact class contains firstname, lastname, country and phone which are used in our form.
forms_app.component.ts
import {Component} from 'angular2/core';
import {ContactComponent} from './contact-form.component'
@Component({
  selector: 'my-app',
  template: '',
  directives: [ContactComponent]
})
export class AppComponent { }
  • The @Component is a decorator which uses configuration object to create the component.
  • The selector creates an instance of the component where it finds <my-app> tag in parent HTML.
  • The template that tells Angular what to render as view.
  • The above app.component.ts will import the ContactComponent component and uses directives to include the component.
contact-form.component.ts
import {Component} from 'angular2/core';
import {NgForm}    from 'angular2/common';
import { Contact } from './contact';
@Component({
  selector: 'contact-form',
  templateUrl: 'app/contact-form.component.html'
})
export class ContactComponent {
  countries = ['India', 'Australia', 'England', 'South Africa', 'USA', 'Japan', 'Singapore'];
  contact = new Contact('Ravi', 'Shankar', this.countries[0], 6445874544);
  submitted = false;
  onSubmit() { this.submitted = true; }
  active = true;
  newContact() {
    this.contact = new Contact('', '');
    this.active = false;
    setTimeout(()=> this.active=true, 0);
  }
}
  • The NgForm is imported which provides CSS classes and Model states.
  • The templateUrl property provides the path to the contact-form.component.html file which contains our form elements.
  • The onSubmit() method will alter the submitted value to true once invoked and the newContact() will create new contact.
contact-form.component.html
<div class="container">
  <div [hidden]="submitted">
    <h2>Contact Form</h2>
    <form *ngIf="active" (ngSubmit)="onSubmit()" #contactForm="ngForm" novalidate>
      <div class="form-group">
        <label for="firstname">First Name</label>
        <input type="text" class="form-control" placeholder="Enter Your First Name" required
          [(ngModel)]="contact.firstname"
            ngControl="firstname"  #firstname="ngForm" >
        <div [hidden]="firstname.valid || firstname.pristine" class="alert alert-danger">
          firstname is required
        </div>
      </div>
      <div class="form-group">
        <label for="lastname">Last Name</label>
        <input type="text" class="form-control" placeholder="Enter Your Last Name"
          [(ngModel)]="contact.lastname"
            ngControl="lastname" >
      </div>
      <div class="form-group">
        <label for="country">Country</label>
        <select class="form-control" required
          [(ngModel)]="contact.country"
            ngControl="country" #country="ngForm" >
          <option value="" selected disabled>Select Your Country</option>
          <option *ngFor="#coun of countries" [value]="coun">{{coun}}</option>
        </select>
        <div [hidden]="country.valid || country.pristine" class="alert alert-danger">
          Country is required
        </div>
      </div>

      <div class="form-group">
         <label for="phone">Phone Number</label>
         <input type="number" class="form-control" placeholder="Enter Your Phone Number"
            [(ngModel)]="contact.phone"
            ngControl="phone"
         >
      </div>

      <button type="submit" class="btn btn-primary" [disabled]="!contactForm.form.valid">Submit</button>
      <button type="button" class="btn btn-primary" (click)="newContact()">New Contact</button>
    </form>
  </div>
  <div [hidden]="!submitted">
    <h2>Your contact details :</h2>
    <div class="well">
        <div class="row">
          <div class="col-xs-2">First Name</div>
          <div class="col-xs-10  pull-left">{{ contact.firstname }}</div>
        </div>
        <div class="row">
          <div class="col-xs-2">Last Name</div>
          <div class="col-xs-10 pull-left">{{ contact.lastname }}</div>
        </div>
        <div class="row">
          <div class="col-xs-2">Country</div>
          <div class="col-xs-10 pull-left">{{ contact.country }}</div>
        </div>
        <div class="row">
        <div class="col-xs-2">Phone Number</div>
        <div class="col-xs-10 pull-left">{{ contact.phone }}</div>
      </div>
        <br>
        <button class="btn btn-primary" (click)="submitted=false">Edit Contact</button>
    </div>
  </div>
</div>
  • The above code contains the form, on submitting the form the ngSubmit directive calls onSubmit() method.
  • The contact details are displayed when the submitted is set to false.
  • It uses pristine and valid for validating an form input element.
  • The ngIf directive checks whether the active is set to true for displaying the form.

Output

Let's carry out the following steps to see how above code works:
  • Save above HTML code as index.html file as how we created in environment chapter and use the above app folder which contains .ts files.
  • Open the terminal window and enter the below command:
    npm start
  • After few moments, a browser tab should open and displays the output as shown below.
OR you can run this file in another way:
  • Save above HTML code as angular2_forms.html file in your server root folder.
  • Open this HTML file as http://localhost/angular2_forms.html and output as below gets displayed.

No comments:

Post a Comment