I currently have an text control input component that acts as the input field for my form. I am reusing this for each piece of input data I need e.g. Name, Email, Password etc.
I have setup the component to take required, minLength and maxLength (which currently don't display an error and is part of my problem), and would also like them to use the inbuilt Angular directives for validation: pristine, dirty, touched etc which will then display the validation message in the parent form component.
I cannot work out how to apply these directives to the instance of the child component as it doesn't seem to reach the input field itself and I need to apply different directives to the different instances E.g. I need Name not to contain a number, but I do need Password to contain a number, therefore using different directives.
text-control.component.html
<input #textControlInput readonly="{{getReadOnly()}}" className="{{getCSSClasses()}}" [id]="id" [name]="name"
[value]="modelValueDisplay" [type]="type" [minLength]="minLength" [maxLength]="maxLength" [size]="size"
[placeholder]="placeholder" [required]="required" (input)="onChange()" (change)="onChange()" />
text-control.component.ts
import {
Component,
EventEmitter,
Input,
Output,
ViewChild,
ElementRef,
} from '@angular/core';
@Component({
selector: 'app-text-control',
templateUrl: './text-control.component.html',
styleUrls: ['./text-control.component.scss'],
})
export class TextControlComponent {
@Input() className: string;
@Input() disabled = false;
@Input() form: string;
@Input() id: string;
@Input() minLength: number;
@Input() maxLength: number;
@Input() name: string;
@Input() pattern: string;
@Input() placeholder: string;
@Input() suffix: string;
@Input() size = 25;
@Input() type = 'text';
@Input() value: string;
@Input() public required = false;
@ViewChild('textControlInput') textControlInput: ElementRef;
public label: string;
touched = false;
constructor() {}
ngOnInit() {}
ngAfterViewInit() {}
getCSSClasses() {
return 'TextControl' + (this.className ? ' ' + this.className : '')
+ (this.multiLine ? ' multiLine' : '') + (this.disabled ? ' disabled' : '') ;
}
}
parent.component.html
<app-text-control id="{{idPrefix}}firstName" name="{{idPrefix}firstName" [type]="'text'" [readOnly]="readOnly"
className="g-mb-1" [size]="15" [(ngModel)]="loginDetails.firstName" [placeholder]="'First Name'"
required="true" minLength="3" maxLength="100" #firstName=ngModel>
</app-text-control>
parent.component.ts
import {
Component,
OnInit,
Input,
Output,
EventEmitter,
ViewChild,
} from '@angular/core';
@Component({
selector: 'app-form-login-details',
templateUrl: './form-login-details.component.html',
styleUrls: ['./form-login-details.component.scss'],
})
export class FormLoginDetailsComponent implements OnInit {
@Input() readOnly: boolean;
@Input() idPrefix = '';
@Input() loginDetails = new LoginDetails();
@Output() loginDetailsChange = new EventEmitter<LoginDetails>();
@Output() selectChange = new EventEmitter<any>();
constructor() {}
ngOnInit() {}