Issue
I'm working in Angular 17 with Material. Lets say I have an example of Reactive Form with 2 inputs of time type inside it.
[minHour, maxHour] should be an intervall range of Hours, let's say [09:00 , 13:00].
HTML [my-time.component.html]
<form [formGroup]="timeFormGroup" (ngSubmit)="save()">
<div style="display:flex">
<mat-form-field style="width: 100px;" appearance="outline">
<mat-label>Min Hour</mat-label>
<input type="time" matInput formControlName="minHour">
</mat-form-field>
<mat-form-field style="width: 100px;" appearance="outline">
<mat-label>Max Hour</mat-label>
<input type="time" matInput formControlName="maxHour">
</mat-form-field>
</div>
...
<div>
...
<button mat-flat-button color="accent" type="submit">Save</button>
</div>
</form>
[TS] my-time.component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, FormControl, ReactiveFormsModule } from '@angular/forms';
import { MatInputModule } from '@angular/material/input'
import { FormBuilder, Validators } from '@angular/forms';
....
@Component({
selector: 'app-my-time',
templateUrl: './my-time.component.html',
styleUrl: './my-time.component.scss'
})
export class MyTimeComponent implements OnInit {
constructor(private fb: FormBuilder){}
timeFormGroup = this.fb.group({
minTime: ['', Validators.required],
maxTime: ['', Validators.required]
});
ngOnInit(): void {
}
save() {
console.log(this.timeFormGroup.value)
}
}
I need to check that this range is respected when validating the input. I also need to display an error message when the input is different from the range 09:00 - 13:00.
Thanks to anyone who will help me, expecially with some code example
Solution
I may have needed more information, but I'll try out with what I have.
Custom validator
I would construct a specific validator for this purpose.
timeFormGroup = this.fb.group({
minTime: ['', [Validators.required, this._minTimeValidator('09:00')]],
maxTime: ['', Validators.required]
});
private _minTimeValidator(minTime: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const inputTime = control.value as string
if (!inputTime) {
return null // If the control is empty, don't perform validation
}
const minTimeObj = new Date(`1970-01-01T${minTime}`)
const inputTimeObj = new Date(`1970-01-01T${inputTime}`)
return inputTimeObj >= minTimeObj ? null : { minTime: true }
}
}
That way, minTime
will be wrong if the user select less than 09:00
.
you can do the same with the maxTime
.
Set validator on the fly
If you need to set the min (or the max) validators base on the min (or the max) time. you could subscribe to the formControl change
With an unsubscribe "proTip" logic
protected _unsubscribe$: Subject<void> = new Subject()
ngOnInit(): void {
this.timeFormGroup.valueChanges
.pipe(
filter((event) => (event ? true : false)),
takeUntil(this._unsubscribe$),
)
.subscribe((value) => {
const minTime = value.minTime.split(':') // Could be useful
const maxTime = value.maxTime.split(':') // Could be useful
const minTimeControl = this.timeFormGroup.get('minTime')
if (
// Your logic : If true
) {
const customTime = '09:00' // Whatever you like, use minTime or maxTime if you wish
minTimeControl.setValidators(this._minTimeValidator(customTime))
} else if (minTimeControl.validator) { // If we have validator
minTimeControl.setValidators(null)
minTimeControl.updateValueAndValidity()
}
})
}
ngOnDestroy(): void {
this._unsubscribe$.next()
this._unsubscribe$.complete()
}
Answered By - Raphaël Balet
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.