Hi All,
I am trying to get form validation working based on this.
My issue is, I have a selector called control-messages
, but I cannot seem to get it to display in the html.
I get the following error in controlMessages.ts
.
TypeError: this.control is undefined
That means I am probably doing some incorrect around @Input() control: FormControl;
.
Any suggestions appreciated.
Here is my code:
login.html
<form [formGroup]="loginForm" (ngSubmit)="submit()"> <ion-item> <ion-label stacked>Username</ion-label> <ion-input type="text" formControlName="username" id="username"></ion-input> </ion-item> <br> <control-messages [control]="loginForm.controls.username"></control-messages> <ion-item> <ion-label stacked>Password</ion-label> <ion-input type="password" formControlName="password" id="password"></ion-input> </ion-item> <ion-buttons> <button type="submit" [disabled]="!loginForm.valid" block round>Sign In</button> </ion-buttons> </form>
login.ts
import { Component, Input } from '@angular/core'; import { NavController } from 'ionic-angular'; import { Validators } from '@angular/common'; import { REACTIVE_FORM_DIRECTIVES, FormBuilder, FormControl, FormGroup } from '@angular/forms'; import { ControlMessages } from '../validation/controlMessages'; import { RegisterPage } from '../register/register'; import { EmployeeModel } from '../model/EmployeeModel';
@Component({ templateUrl: 'build/pages/login/login.html', directives: [REACTIVE_FORM_DIRECTIVES, ControlMessages] })
export class LoginPage {
private loginForm: FormGroup; errorMessage: string; @Input() control: FormControl;
constructor(private nav: NavController, private builder: FormBuilder) {
this.loginForm = builder.group({ 'username': [ '', // default value [Validators.required, Validators.minLength(5)] ], 'password': [ '', [Validators.required, Validators.minLength(5)] ] });
}
submit() { if (this.loginForm.dirty && this.loginForm.valid) { alert(`Name: ${this.loginForm.value.username} Password: ${this.loginForm.value.password}`); } } }
controlMessages.ts
import { Component, Input } from '@angular/core'; import { FormGroup, FormControl } from '@angular/forms'; import { ValidationService } from './validationService';
@Component({ selector: 'control-messages', template: `<div *ngIf="errorMessage !== null">{{errorMessage}}</div>` }) export class ControlMessages { //errorMessage: string; @Input() control: FormControl; constructor() { console.log('ControlMessages.constructor'); }
get errorMessage(): string { console.log('ControlMessages.errorMessage'); for (let propertyName in this.control.errors) { if (this.control.errors.hasOwnProperty(propertyName) && this.control.touched) { return ValidationService.getValidatorErrorMessage(propertyName, this.control.errors[propertyName]); } } return null; } }
*The console.logs: ControlMessages.errorMessage: undefined
validationService.ts
import { FormControl, FormGroup } from "@angular/forms";
interface ValidationResult { [key: string]: boolean; }
export class ValidationService {
static getValidatorErrorMessage(validatorName: string, validatorValue?: any) { let config = { 'required': 'Required', 'invalidCreditCard': 'Is invalid credit card number', 'invalidEmailAddress': 'Invalid email address', 'invalidPassword': 'Invalid password. Password must be at least 6 characters long, and contain a number.', 'minlength': `Minimum length ${validatorValue.requiredLength}` };
return config[validatorName]; }
static creditCardValidator(control) { // Visa, MasterCard, American Express, Diners Club, Discover, JCB if (control.value.match(/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/)) { return null; } else { return { 'invalidCreditCard': true }; } } }