J'ai une application angular4 avec un formulaire. Dans celui-ci, j'ai une entrée pour entrer un pourcentage. Donc, je veux bloquer l'entrée avec une valeur comprise entre 0 et 100. J'ai essayé d'ajouter min="0"
et max="100"
mais je peux encore saisir un nombre supérieur à 100 ou inférieur à 0.
modèle
<md-input-container>
<input type="number"
maxlength="3"
min="0"
max="100"
required
mdInput
placeholder="Charge"
[(ngModel)]="rateInput"
name="rateInput">
<md-error>Required field</md-error>
</md-input-container>
Savez-vous comment je peux faire ça?
J'ai réussi en utilisant un contrôle de formulaire. Voici mon code html:
<md-input-container>
<input type="number" min="0" max="100" required mdInput placeholder="Charge" [(ngModel)]="rateInput" name="rateInput" [formControl]="rateControl">
<md-error>Please enter a value between 0 and 100</md-error>
</md-input-container>
Et dans mon code TypeScript, j'ai:
this.rateControl = new FormControl("", [Validators.max(100), Validators.min(0)])
Donc, si nous entrons une valeur supérieure à 100 ou inférieure à 0, l'entrée de conception de matériau devient rouge et le champ n'est pas validé. Donc après, si la valeur n'est pas bonne, je n'enregistre pas lorsque je clique sur le bouton Enregistrer.
En fait, lorsque vous utilisez type = "number", votre contrôle d'entrée est rempli avec flèche haut/bas pour incrémenter/décrémenter la valeur numérique, donc lorsque vous mettez à jour la valeur de la zone de texte avec ces boutons, il ne dépassera pas la limite de 100 , mais lorsque vous manuellement donner une entrée comme 120/130 et ainsi de suite, il ne validera pas la limite maximale , vous devez donc le valider par code.
Vous pouvez désactiver la saisie manuelle OR vous devez écrire du code lors de l'événement valueChange/textChange/key *.
Voici la solution:
C'est une sorte de piratage, mais cela fonctionnera
<input type="number"
placeholder="Charge"
[(ngModel)]="rateInput"
name="rateInput"
pattern="^$|^([0-9]|[1-9][0-9]|[1][0][0])?"
required
#rateInput2 = "ngModel">
<div *ngIf="rateInput2.errors && (rateInput2.dirty || rateInput2.touched)"
<div [hidden]="!rateInput2.errors.pattern">
Number should be between 0 and 100
</div>
</div>
Voici le lien vers le plunker , veuillez jeter un œil.
Vous pouvez écrire une directive pour écouter l'événement change sur l'entrée et réinitialiser la valeur à la valeur min si elle est trop faible. StackBlitz
@HostListener('change') onChange() {
const min = +this.elementRef.nativeElement.getAttribute('min');
if (this.valueIsLessThanMin(min, +this.elementRef.nativeElement.value)) {
this.renderer2.setProperty(
this.elementRef.nativeElement,
'value',
min + ''
);
}
}
Écoutez également l'événement ngModelChange pour faire de même lorsque la valeur du formulaire est définie.
@HostListener('ngModelChange', ['$event'])
onModelChange(value: number) {
const min = +this.elementRef.nativeElement.getAttribute('min');
if (this.valueIsLessThanMin(min, value)) {
const formControl = this.formControlName
? this.formControlName.control
: this.formControlDirective.control;
if (formControl) {
if (formControl.updateOn === 'change') {
console.warn(
`minValueDirective: form control ${this.formControlName.name} is set to update on change
this can cause issues with min update values.`
);
}
formControl.reset(min);
}
}
}
Code complet:
import {
Directive,
ElementRef,
HostListener,
Optional,
Renderer2,
Self
} from "@angular/core";
import { FormControlDirective, FormControlName } from "@angular/forms";
@Directive({
// tslint:disable-next-line: directive-selector
selector: "input[minValue][min][type=number]"
})
export class MinValueDirective {
@HostListener("change") onChange() {
const min = +this.elementRef.nativeElement.getAttribute("min");
if (this.valueIsLessThanMin(min, +this.elementRef.nativeElement.value)) {
this.renderer2.setProperty(
this.elementRef.nativeElement,
"value",
min + ""
);
}
}
// if input is a form control validate on model change
@HostListener("ngModelChange", ["$event"])
onModelChange(value: number) {
const min = +this.elementRef.nativeElement.getAttribute("min");
if (this.valueIsLessThanMin(min, value)) {
const formControl = this.formControlName
? this.formControlName.control
: this.formControlDirective.control;
if (formControl) {
if (formControl.updateOn === "change") {
console.warn(
`minValueDirective: form control ${
this.formControlName.name
} is set to update on change
this can cause issues with min update values.`
);
}
formControl.reset(min);
}
}
}
constructor(
private elementRef: ElementRef<HTMLInputElement>,
private renderer2: Renderer2,
@Optional() @Self() private formControlName: FormControlName,
@Optional() @Self() private formControlDirective: FormControlDirective
) {}
private valueIsLessThanMin(min: any, value: number): boolean {
return typeof min === "number" && value && value < min;
}
}
Assurez-vous de l'utiliser avec le contrôle de formulaire défini sur updateOn flou ou l'utilisateur ne pourra pas entrer un numéro à +1 chiffre si le premier chiffre est inférieur à la valeur min.
this.formGroup = this.formBuilder.group({
test: [
null,
{
updateOn: 'blur',
validators: [Validators.min(5)]
}
]
});
Faites simplement ceci dans angular2 + en ajoutant (onkeypress)
<input type="number"
maxlength="3"
min="0"
max="100"
required
mdInput
placeholder="Charge"
[(ngModel)]="rateInput"
(onkeypress)="return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57"
name="rateInput">
Testé sur Angular 7