Hi
I am examining Ionic 2 these days and just cant find a working example of forms with validation.
I use beta 11.
Can anyone point such an example or can post a working forms code for beta 11 here in the forum ?
Thanks a lot
Hi
I am examining Ionic 2 these days and just cant find a working example of forms with validation.
I use beta 11.
Can anyone point such an example or can post a working forms code for beta 11 here in the forum ?
Thanks a lot
Iām also using beta 11 and below is the user details form that I have. It has 3 fields: name, email and phone with validators
for each.
user-info.html
<ion-header>
<ion-toolbar>
<ion-title>User Details</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<ion-item>
<ion-label floating primary>Name</ion-label>
<ion-input [(ngModel)]="userInfo.name" formControlName="name" type="text"
id="name" spellcheck="false" autocapitalize="off">
</ion-input>
</ion-item>
<p *ngIf="!isValid('name')" danger padding-left>Invalid Name</p>
<ion-item>
<ion-label floating primary>Email</ion-label>
<ion-input [(ngModel)]="userInfo.email" formControlName="email"
type="text" id="email" spellcheck="false" autocapitalize="off">
</ion-input>
</ion-item>
<p *ngIf="!isValid('email')" danger padding-left>Invalid Email</p>
<ion-item>
<ion-label floating primary>Phone</ion-label>
<ion-input [(ngModel)]="userInfo.phone" formControlName="phone" type="text" id="phone">
</ion-input>
</ion-item>
<p *ngIf="!isValid('phone')" danger padding-left>Invalid Phone</p>
<button type="submit" block primary [disabled]="!myForm.valid">Submit</button>
</form>
</ion-list>
</ion-content>
user-info.ts
import {OnInit, Component} from "@angular/core";
import {FormGroup, FormBuilder, FormControl, Validators} from "@angular/forms";
@Component({
templateUrl: 'build/pages/user-info/user-info.html'
})
export class UserInfoComponent implements OnInit {
myForm: FormGroup;
userInfo: {name: string, email: string, phone: string} = {name: '', email: '', phone: ''};
constructor(public formBuilder: FormBuilder) {
}
ngOnInit(): any {
this.myForm = this.formBuilder.group({
'name': ['', [Validators.required, Validators.minLength(3), this.nameValidator.bind(this)]],
'phone': ['', this.phoneValidator.bind(this)],
'email': ['', [Validators.required, this.emailValidator.bind(this)]]
});
}
onSubmit() {
console.log('submitting form');
}
isValid(field: string) {
let formField = this.myForm.find(field);
return formField.valid || formField.pristine;
}
nameValidator(control: FormControl): {[s: string]: boolean} {
if (!control.value.match("^[a-zA-Z ,.'-]+$")) {
return {invalidName: true};
}
}
phoneValidator(control: FormControl): {[s: string]: boolean} {
if (control.value !== '') {
if (!control.value.match('\\(?\\d{3}\\)?-? *\\d{3}-? *-?\\d{4}')) {
return {invalidPhone: true};
}
}
}
emailValidator(control: FormControl): {[s: string]: boolean} {
if (!(control.value.toLowerCase().match('^[a-zA-Z]\\w*@gmail\\.com$') || control.value.toLowerCase().match('^[a-zA-Z]\\w*@yahoo\\.com$'))) {
return {invalidEmail: true};
}
}
}
Hi
I will try it
Thanks a lot.
Is it possible to work with FormsModule or ReactiveFormsModule from @angular/forms in Ionic ?
Thanks
The given example is an implementation of ReactiveFormsModule. formControlName
is used is ReactiveForms
Thanks.
I was confused because I couldnāt find an import {ReactiveFormsModule} from '@angular/forms'
statement.
That brings me to the question: Where it is done ?
Where is @NgModule in an Ionic app ? And how ReactiveFormsModule is imported to it using the āimports:ā property ?
Thanks again.
There is no NgModule in ionic 2 yet, may be coming in beta 12
Follow these links to get knowledge of Forms in Angular2. And implement in Ionic2 with little modifications as per your requirement.
TEMPLATE-DRIVEN FORMS IN ANGULAR 2
Template Driven vs Model Driven or Reactive Forms - Angular University blog
Thanks a lot for the great links.
Since ankushagg93 made it clear that ReactiveFormsModule is available in 11 beta I tried to modify angular2 cookbook on form validation from:
https://angular.io/docs/ts/latest/cookbook/form-validation.html.
Basically it works. But there are 2 problems:
html
<ion-item>
<ion-label floating>Email</ion-label>
<ion-input type="text" formControlName="email" required></ion-input>
</ion-item>
<div *ngIf="formErrors.email" class="alert alert-danger">
{{ formErrors.email }}
</div>
<ion-item>
<ion-label floating>Password</ion-label>
<ion-input type="password" formControlName="password" required></ion-input>
</ion-item>
<div *ngIf="formErrors.password" class="alert alert-danger">
{{ formErrors.password }}
</div>
<ion-item>
<ion-label floating>Retype Password</ion-label>
<ion-input type="password" formControlName="passwordMatch" required></ion-input>
</ion-item>
<div *ngIf="formErrors.passwordMatch" class="alert alert-danger">
{{ formErrors.passwordMatch }}
</div>
<button block outline large type="submit" [disabled]="!registerForm.valid">Register</button>
{{ registerForm.valid }}
</form>
TS
import { Component, OnInit } from ā@angular/coreā;
import { NavController } from āionic-angularā;
import {FormGroup, FormBuilder, Validators} from ā@angular/formsā;
@Component({
templateUrl: 'build/pages/register/register.html'
})
export class Register implements OnInit {
registerInfo = {
email: '',
password: ''
}
constructor(private navController: NavController, private fb: FormBuilder) { }
active: Boolean;
registerForm: FormGroup;
ngOnInit(): void {
this.active = true;
this.buildForm();
}
buildForm(): void {
this.registerForm = this.fb.group({
'email': [this.registerInfo.email, [
Validators.required
]
],
'password': [this.registerInfo.password, [
Validators.required
]
],
'passwordMatch': [this.registerInfo.password, [
Validators.required
]
]
});
this.registerForm.valueChanges.subscribe(data => this.onValueChanged(data));
this.onValueChanged();
}
onSubmit() {
this.registerInfo = this.registerForm.value;
}
onValueChanged(data?: any) {
if (!this.registerForm) {
return;
}
const form = this.registerForm;
if (form.pristine) {
return;
}
if (!form.dirty) {
return;
}
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[field] = '';
const control = form.controls[field];
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
formErrors = {
'email': '',
'password': '',
'passwordMatch': ''
};
validationMessages = {
'email': {
'required': 'Email is required.',
'emailPattern': 'Email is not valid'
},
'password': {
'required': 'Password is required.'
},
'passwordMatch': {
'required': 'Retype password',
'match':'Passwords do not match'
}
};
}
Result
I donāt understand this function especially {[s: string]: boolean}
section.
Would you declare it?
Itās just regex matching that I want for my name validator. This regex only allows one or more of following characters a-zA-Z ,.'-
Regarding {[s: string]: boolean}
, itās just return type for TypeScript. You can remove it if you want. It means the validator will return an object with key value pair where key is string and value is boolean. Actually Iām returning wrong, key should be string return {'invalidName': true};
Again, itās just developer choice.
For angular, any non-null return value means validation failed.
How can I know my angular version inside ionic?
I think you can do ionic info
to see Ionic Framework Version
and then look in package.json to find out angular version.
Does this work in RC1 when building Android?
When I use the following, I get an error ( see beneath ) when running Android:
formInfo = {
name: '',
slogan: '',
category: ''
}
this.myForm = formBuilder.group({
'name': [this.formInfo.name, Validators.required]
'slogan': '',
'category': [this.formInfo.category, Validators.required]
})
Errors:
Property ānameā does not exist on type '{ key string] :AbstractControl
Property ācategoryā does not exist on type '{ key string] :AbstractControl
No error for slogan as is not required.
My ionic info:
Cordova CLI: 6.3.1
Gulp version: CLI version 3.9.0
Gulp local:
Ionic Framework Version: 2.0.0-rc.1
Ionic CLI Version: 2.1.1
Ionic App Lib Version: 2.1.1
Ionic App Scripts Version: 0.0.36
OS:
Node Version: v6.8.0
Thanks @ankushagg93! This is awesome
@Ankush ,I did same as you but changed little bit code to render different messages at interface a/c to Preformatted text
error.
every time i was stopped with an issue like
TypeError: Cannot read property āfirstnameā of undefined TypeError: Cannot read property āfirstnameā of undefined at Object.View_RegisterPage_0.co [as updateDirectives]
Here is my code
`
Register.ts
import { OnInit, Component} from ā@angular/coreā;
import { NavController } from āionic-angularā;
//import { LoginPage } from āā¦/ā¦/pages/login/loginā;
import { FormGroup, FormBuilder, FormControl, Validators, FORM_DIRECTIVES } from ā@angular/formsā;
@Component({
selector: 'page-registration',
templateUrl: 'registration.html',
})
export class RegisterPage implements OnInit {
myForm: FormGroup;
userInfo: { firstname: string } = { firstname: '' };
constructor(public navCtrl: NavController, public formBuilder: FormBuilder) {
}
ngOnInit(): any {
this.myForm = this.formBuilder.group({
'firstname': ['', Validators.compose([Validators.required, Validators.minLength(3), Validators.maxLength(15), this.firstnameValidator.bind(this)])]
});
}
onSubmit() {
console.log('submitting form');
}
isValid(field: string) {
let formField = this.myForm.get(field);
return formField.valid || formField.pristine;
}
firstnameValidator(control) {
const regExp = new RegExp(/^[a-zA-Z0-9]+$/);
if (regExp.test(control.value)) {
return null; // Return as valid username
} else {
return { 'validatefirstname': true }
}
}
goBack() {
this.navCtrl.pop();
}
}
.`
register.html
<ion-item>
<ion-label floating primary>FirstName</ion-label>
<div [ngClass]="{'has-error': (myForm.control.firstname.errors && myForm.control.firstname.dirty), 'has-success': !myForm.control.firstname.errors}">
<ion-input [(ngModel)]="userInfo.firstname" formControlName="firstname" type="text"
id="firstname" spellcheck="false" autocapitalize="off">
</ion-input>
</div>
<p *ngIf="form.control.firstname.errors?.required && form.control.firstname.dirty">This field is required</p>
Minimum characters: 3, Maximum characters: 15
firstnamemust not have any special characters
<div padding>
<button ion-button color="primary" class="submit-btn" full type="submit"
[disabled]="!myForm.valid" block>
Register
</button>
</div>
</ion-col>
Login
Please help me to get out of this.
Thanks men, helped me a lot!!!
Anybody coming across this thread, donāt emulate this. Dot access to controls
will break in production mode. Use get()
instead.