webentwicklung-frage-antwort-db.com.de

Deaktivieren Sie die Texteingabe in mat-datepicker, wenn Sie ein reaktives Formular verwenden

Ich verwende Angular Material 2's mat-datepicker] Und möchte, dass das Eingabeelement deaktiviert wird, damit der Benutzer den Wert nicht über die Texteingabe bearbeiten kann.

Es gibt ausführliche Anweisungen in den Angular Material 2-Dokumenten Anleitungen zum Deaktivieren verschiedener Teile des mat-datepicker, Diese scheinen jedoch keine Anleitung zu enthalten Deaktivieren Sie die Texteingabe, wenn sie Teil eines reaktiven Formulars ist.

In den Dokumenten zu Angular Material wird empfohlen, die Texteingabe wie folgt zu deaktivieren:

<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>

Wenn Ihr Datepicker jedoch Teil eines reaktiven Formulars ist, bleibt das Textelement aktiv und Sie erhalten die folgende Nachricht von Angular:

Anscheinend verwenden Sie das Attribut disabled mit einer Direktive für reaktive Formulare. Wenn Sie disabled beim Einrichten dieses Steuerelements in Ihrer Komponentenklasse auf true setzen, wird das Attribut disabled im DOM tatsächlich für Sie festgelegt. Wir empfehlen, diesen Ansatz zu verwenden, um Fehler zu vermeiden, die nach dem Überprüfen geändert wurden. Beispiel: form = new FormGroup ({first: new FormControl ({value: 'Nancy', disabled: true})});

Ich habe das FormGroup in der Komponente aktualisiert, um das FormControl zu deaktivieren. Dies hat den gewünschten Effekt, dass die Eingabe deaktiviert wird, wenn Sie dann den Wert des FormGroup mit this.form.value Das deaktivierte Formularsteuerelement ist nicht mehr vorhanden.

Gibt es eine Lösung für dieses Problem, bei der keine separate vorlagengesteuerte Form mit ngModel nur für die Matten-Datumsauswahl (en) verwendet wird?

15
nclarx

Ein deaktiviertes FormControl zu erstellen ist wirklich einfach.

1 - Verwenden Sie in Ihrer Vorlage kein deaktiviertes Attribut.

2 - Instanziiere dein FormGroup wie folgt:

this.formGroup = this.formBuilder.group({
  dateJoined: { disabled: true, value: '' }
  // ...
});

Das heißt, obwohl Sie verhindern möchten, dass Benutzer etwas in die Eingabe eingeben, möchten Sie sie dennoch ein Datum auswählen lassen, indem Sie auf die Schaltfläche klicken (genauer gesagt in matSuffix), richtig?

Wenn es korrekt ist, funktioniert disable in diesem Fall nicht, da alle Eingaben deaktiviert werden (einschließlich der Schaltfläche in matSuffix).

Um Ihren Fall zu lösen, können Sie readonly verwenden. Instanziiere das FormGroup normal und dann in der Vorlage:

<input                          
  matInput 
  readonly <- HERE
  [matDatepicker]="dateJoined" 
  placeholder="Date joined" 
  formControlName="dateJoined">

DEMO

42
developer033

Um die Antwort von developer0 zu erweitern und den readonly -Status von input dynamisch umzuschalten, ändern Sie die readonly -Eigenschaft mithilfe einer Komponentenvariablen.

Readonly dynamisch umschalten

Sehen Stackblitz Demo.

app.component.html

<input matInput 
  [readonly]="inputReadonly"   <!-- Update `readonly` property using variable -->
  [matDatepicker]="dateJoined" 
  placeholder="Date joined" 
  formControlName="dateJoined">

app.component.ts

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;
  }
}
1