J'utilise Angular Material 2's mat-datepicker
et souhaite que l'élément d'entrée soit désactivé afin que l'utilisateur ne puisse pas modifier la valeur à l'aide de la saisie de texte.
Il y a instructions détaillées dans le Angular Material 2 docs sur la façon de désactiver différentes parties du mat-datepicker
cependant, ceux-ci ne semblent pas expliquer comment désactiver la saisie de texte lorsqu'elle fait partie d'un formulaire réactif.
Les documents Angular Material suggèrent de désactiver la saisie de texte de la manière suivante:
<mat-form-field>
// Add the disabled attribute to the input element ======
<input disabled
matInput
[matDatepicker]="dateJoined"
placeholder="Date joined"
formControlName="dateJoined">
<mat-datepicker-toggle matSuffix [for]="dateJoined"></mat-datepicker-toggle>
// Add [disabled]=false to the mat-datepicker =======
<mat-datepicker [disabled]="false"
startView="year"
#dateJoined></mat-datepicker>
</mat-form-field>
Cependant, si votre sélecteur de date fait partie d'une forme réactive, l'élément de texte reste actif et vous obtenez le message suivant d'Angular:
Il semble que vous utilisiez l'attribut désactivé avec une directive de formulaire réactif. Si vous définissez désactivé sur true lorsque vous configurez ce contrôle dans votre classe de composants, l'attribut désactivé sera réellement défini dans le DOM pour vous. Nous vous recommandons d'utiliser cette approche pour éviter les erreurs "modifié après vérification". Exemple: form = new FormGroup ({first: new FormControl ({value: 'Nancy', disabled: true})});
J'ai mis à jour le FormGroup
dans le composant pour désactiver le FormControl
, ce qui a pour effet souhaité de désactiver l'entrée, cependant, si vous obtenez ensuite la valeur du FormGroup
en utilisant this.form.value
le contrôle de formulaire désactivé n'est plus présent.
Existe-t-il un moyen de contourner ce problème qui n'implique pas d'avoir un formulaire géré par modèle distinct en utilisant ngModel
uniquement pour le ou les sélecteurs mat-date?
Pour créer un FormControl
désactivé, c'est vraiment simple.
1 - N'utilisez pas d'attribut désactivé dans votre modèle;
2 - Instanciez votre FormGroup
comme ceci:
this.formGroup = this.formBuilder.group({
dateJoined: { disabled: true, value: '' }
// ...
});
Cela étant dit, bien que vous vouliez empêcher les utilisateurs de taper quelque chose dans l'entrée, vous voulez quand même leur permettre de sélectionner une date en cliquant sur le bouton (plus précisément dans matSuffix
), non?
Si c'est correct, disable
ne fonctionne pas dans ce cas, car cela désactivera toutes les entrées (y compris le bouton dans matSuffix
).
Pour résoudre votre cas, vous pouvez utiliser readonly
. Instanciez le FormGroup
normalement puis dans le modèle:
<input
matInput
readonly <- HERE
[matDatepicker]="dateJoined"
placeholder="Date joined"
formControlName="dateJoined">
Pour développer la réponse de developer0 , pour basculer dynamiquement l'état readonly
de input
, modifiez la propriété readonly
à l'aide d'une variable de composant.
Voir Stackblitz Demo.
<input matInput
[readonly]="inputReadonly" <!-- Update `readonly` property using variable -->
[matDatepicker]="dateJoined"
placeholder="Date joined"
formControlName="dateJoined">
import {Component} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {VERSION} from '@angular/material';
@Component({
selector: 'material-app',
templateUrl: 'app.component.html'
})
export class AppComponent {
formGroup: FormGroup;
inputReadonly = true;
version = VERSION;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.formGroup = this.formBuilder.group({
dateJoined: ''
});
}
public toggleInputReadonly() {
this.inputReadonly = !this.inputReadonly;
}
}