Angular2 Forms

In my last post we already created a form for our email form to be sent via a PHP backend. This form is created based on this explanations: https://angular.io/docs/ts/latest/guide/forms.html.

This post will show also a different way of working with forms, when you need a little bit more flexibility.

To start quickly from the beginning, we have in simple ways this html form:

<div class="container">
<h1>Test Form</h1>
<form (submit)="doLogin()">
<input [(ngModel)]="model.email" ngControl="email" type="email" placeholder="Your email" #email="ngForm" required>
<input [(ngModel)]="model.password" ngControl="password" type="password" placeholder="Your password" required>
<button type="submit">Log in</button>
<br>
<div [hidden]="email.valid" class="alert alert-danger">
Mail is not valid
</div>
</form>
</div>

We have here two inputs for email and password and a login button. In the form we specified the submit event to be executed by the doLogin method. Both input have the ngControl tag and are bind to a property of the model object. the email input has also the local variable email which is set by ngForm to be able show or hide a div depending if the input is valid or not.

And here is the component:

import {Component} from 'angular2/core';
import {NgForm} from 'angular2/common';

@Component({
selector: 'my-app',
providers: [],
templateUrl: 'src/app.html',
styleUrls: ['style.css']
directives: []
})
export class App {
public model= {email: "test@test.com", password: "myPass"};

constructor() {
}

doLogin() {
console.log(this.model);
}

}

Here is the working plunk of this simple example: http://plnkr.co/edit/WpIi64?p=preview

So, before going to the next step. Let’s extend this example a little bit. We will hide the form and show a message that the login was successful. See here this working plunk: http://plnkr.co/edit/HLoOkr?p=preview

So now, lets extend our example with a different approach. We will control the controls & validators from our component, not from the html.

//our root app component
import {Component} from 'angular2/core';
import {NgForm, FormBuilder, Validators, Control} from 'angular2/common';

@Component({
selector: 'my-app',
providers: [],
templateUrl: 'src/app.html',
styleUrls: ['style.css']
directives: []
})
export class App {
public loginForm;
public model= {email: "myMail@someMail.com", password: "myPass"};

submitted = false;
active = true;

constructor(fb: FormBuilder) {
this.loginForm = fb.group({
email: [this.model.email, Validators.compose([Validators.required, this.containsMagicWord]) ],
password: [this.model.password, Validators.required]
});
}

doLogin() {
console.log(this.model);

this.submitted = true;
console.log('submitted now in doLogin');

this.active = false;
setTimeout(()=> this.active=true, 0);
}

containsMagicWord(c: Control) {
if(c.value.indexOf('magic') >= 0) {
return {
noMagic: true
}
}
// Null means valid, believe it or not
return null
}
}

We will need to inject FormBuilder, Validators & Control from angular2/common. Then in our constructor we create with the FormBuilder our two controls (email & password), assigning a default value and our validators. Password has just the required validator, but in the email, we created our own, which checks if there is a word called magic, if so, then it is invalid, otherwise valid. It is not much different than before huh? but this gives us more flexibility with our validators and showing some messages on the screen. Check out the html:

<h1 class="container">Test Form</h1>

<div class="container" [hidden]="submitted">
<form [ngFormModel]="loginForm" (submit)="doLogin($event)">
<input [(ngModel)]="model.email" ngControl="email" type="email" placeholder="Your email" #email="ngForm" >
<input [(ngModel)]="model.password" ngControl="password" type="password" placeholder="Your password">
<button type="submit">Log in</button>
<div [hidden]="email.valid || email.pristine" class="alert alert-danger">
Mail is not valid
</div>

<div [hidden]="email.control.hasError('noMagic')" class="alert alert-success">
Has no Magic in it
</div>

<div [hidden]="!email.control.hasError('noMagic')" class="alert alert-danger">
Has some Magic in it
</div>

</form>
</div>

<div class="container" [hidden]="!submitted">
<div class="alert alert-success">
Mail sent successfully
</div>
</div>

The first div, we are using it as before. But the second two div’s are using now our own validator, to show a message when it is valid or not. Pretty cool huh?

Here is the working plunk: http://plnkr.co/edit/dYaGJt?p=preview


Originally published at Damir Kusar.

Show your support

Clapping shows how much you appreciated Damir Kusar’s story.