Here i have try to display error messages in forms
in Ionic-3
.
Here is my email.html
file:
<form [formGroup]="form" (submit)="signIn()">
<ion-grid>
<ion-row>
<ion-col>
<ion-item>
<ion-label color="primary" floating>Email</ion-label>
<ion-input [formControl]="form.controls['email']"></ion-input>
</ion-item>
<p *ngIf="form.controls.email.errors && form.controls.email.dirty" class="danger" padding>Email is not valid.</p>
</ion-col>
</ion-row>
</ion-grid>
<ion-list padding>
<ion-item>
<button ion-button default item-end color="light" (click)="cancel()">CANCEL</button>
<button ion-button default item-end color="next" [disabled]="!form.valid" (click)="next()">NEXT</button>
</ion-item>
</ion-list>
</form>
In my email.ts
file i have:
export class EmailSignupPage {
form : FormGroup;
constructor(
private formBuilder: FormBuilder,
public navCtrl: NavController,
public navParams: NavParams,
) {
this.form = this.formBuilder.group({
email: ['', Validators.compose([Validators.required, Validators.email])]
});
}
ionViewDidLoad() {
}
next() {
this.navCtrl.push(CredentialPage);
}
cancel() {
this.navCtrl.popToRoot();
}
}
I think my code is fine in email.ts
file, but i don't know how to display errors in my form when it validate as i'm new to ionic and angular!
Is there any one who can help me with this?
Thanks!
I don't know how to display errors in my form when it validates
If you just want to display errors in some places, the *ngIf
directive is what you will want. Put error messages everywhere you want and add a *ngIf
to indicate in which cases the message should be shown.
The basic idea with <p *ngIf="emailIsCorrect">error message: incorrect email</p>
is to have a property in your class (in the .ts file) that you will update to reflect whether or not the message should appear. The main idea is to use methods in your ts file that will perform the checks/validation and update that emailIsCorrect
property.
As an example, you could use a (keypress)="performCheckOnKeyPress($event.keyCode)"
attribute in your <ion-input ...>
to call a validation method when the user presses a key.
See below for more explanations.
Performing custom checks and validation
I tried to display error messages in forms
in Ionic-3
.
There several choices:
Showing content/error messages conditionally:
The Angular2 *ngIf
directive will hide things based on the state of the variables in your .ts file.
*ngIf
works like a javascript if
: *ngIf="myVar"
<=> if (myVar){}
. An undefined or false myVar
will not show the content. Take a look at the examples in the doc for use cases.
Performing custom validation: you might choose to add extra properties and methods to your class in the .ts file and display content conditionally using *ngIf
.
You can also use javascript checks to:
- disable choices (as it is done in your code with
<button [disabled]=""...>
)
- set content like text or CSS classes using ternary checks
{{variable ? 'basic-class':'error-class' }}
. You can also use method calls like <p>{{ foo() }}</p>
, where foo(){ return "some text"; }
.
- perform custom checks when certain events happen, using attributes on tags (like you would do with the javascript
onclick
=> (click)=""
, onkeypress
=> (keypress)=""
, ...).
- if you store all the error messages in a single variable and want to show them in one place like
<span>Please correct the following fields **email** and **password**</span>
(when both email and password field do not pass validation), you might use <span>{{ errorMessagesVariable }}</span>
.
- you might also want to take a look at the angular2
ngModel
directive and the examples provided in the doc. In fact, there is a basic validation for email and other components when you use <form [formGroup] ...>
and the formGroup
will automatically update fields of the variable form: FormGroup;
you declared in your .ts file.
The aforementioned elements might not reflect best practices for some use cases. They are mentioned for your own knowledge of the ionic framework.
Examples:
For instance, the following ternary is good practice in ionic development:
<ion-label color="{{ form.controls.email.errors && form.controls.email.dirty ? 'danger' : 'primary' }}" floating> Email </ion-label>
Processing keypress events:
<ion-input [formControl]="form.controls['email']" (keypress)="performCheckOnKeyPress($event.keyCode)"></ion-input>.
Error in your code
HTML issue:
There is an error in your code that makes it get sent whether or not it is valid.
When you put a <button>
in a form, when pressed that button will trigger the form submission method you provided for the form (<form (submit)="signIn()" ...>
). In this case, pressing the CANCEL
button will also submit the form.
the fix: if you want to have the CANCEL and NEXT buttons next to each other, you might prefer moving both of them outside the <form>...</form>
tag.
Note that by moving the NEXT button outside the form, it will not submit the form anymore (it will only call your next()
method).
If you want your NEXT button to submit the form even outside the <form>
, you shall also call your signIn()
method when it is clicked. i.e. (click)="next(); signIn()"
.
Note: you can write pretty much plain javascript for the (click)="..."
and other angular directive attributes (works also for *ngIf="..."
). There are some limitations to that javascript though, but just try the JS code you would love to put there...
Note for ionic v1 developers
Ionic 1 used angular 1. Ionic v2/v3 use angular 2.
Changes introduced in angular 2:
(keypress)=""
, (click)=""
replaced ng-keypress=""
and ng-click=""
.
*ngIf
, *ngFor
replaced ng-if
and ng-for
I have fixed this problem with *ngIf
condition.
I have set below code and it's working for me:
<form [formGroup]="form" (submit)="signIn()">
<ion-grid>
<ion-row>
<ion-col>
<ion-item>
<ion-label color="primary" floating>Email</ion-label>
<ion-input [formControl]="form.controls['email']"></ion-input>
</ion-item>
<p *ngIf="form.controls['email'].errors && form.controls['email'].dirty" class="danger" padding>Email is not valid.</p>
</ion-col>
</ion-row>
</ion-grid>
<ion-list padding>
<ion-item>
<button ion-button default item-end color="light" (click)="cancel()">CANCEL</button>
<button ion-button default item-end color="next" [disabled]="!form.valid" (click)="next()">NEXT</button>
</ion-item>
</ion-list>
</form>
I need to use only:
<p *ngIf="form.controls['email'].errors && form.controls['email'].dirty" class="danger" padding>Email is not valid.</p>
Instead of
<p *ngIf="form.controls.email.errors && form.controls.email.dirty" class="danger" padding>Email is not valid.</p>
Which is showing simply errors if there is!
@JMM thanks for the best answer and you are genius! I need only this *ngIf="form.controls['email'].errors && form.controls['email'].dirty"
Thanks you all!