17

Is there a way to disable and make all fields non editable (input / mat-select / textfield / option/input/mat-checkbox etc) inside a Form

by telling only the parent div name in Angular / Angular-material ? (cannot editing them)

@Component({
  templateUrl: './leaseholder.component.html'
})
export class LeaseholderComponent implements OnInit, IFormDirtyWarningComponent {

  leaseholderForm: FormGroup;

  constructor(private router: Router, private formBuilder: FormBuilder) {
    this.createLeaseholderForm();
  }

  createLeaseholderForm() {
    this.leaseholderForm = this.formBuilder.group({
      civility: [this.identityModel.civility],
      firstName: [this.identityModel.firstName, Validators.compose([Validators.pattern("[^\\d]+")])],
      lastName: [this.identityModel.lastName, Validators.compose([Validators.pattern("[^\\d]+")])],
      birthName: [this.identityModel.birthName, Validators.compose([Validators.pattern("[^\\d]+")])],
      birthDate: [this.identityModel.birthDate],
      birthPlace: [this.identityModel.birthPlace, Validators.compose([Validators.pattern("[^\\d]+")])],
      nationality: ['FR', this.identityModel.nationality],
      endOfStay: [this.identityModel.endOfStay]
    });
  }

    <form [formGroup]="leaseholderForm" (ngSubmit)="onSubmit()">
                <div class="mat-radio-group-inverted">
                    <mat-radio-group formControlName="civility">
                        <mat-radio-button color="primary" value="MR">M.</mat-radio-button>
                        <mat-radio-button color="primary" value="MME">MME.</mat-radio-button>
                    </mat-radio-group>
                </div>
                <mat-form-field>
                    <input matInput upperCaseInput placeholder="Nom d'usage" formControlName="lastName">
                </mat-form-field>
...........................
..........  example
    </form>
Anouar Mokhtari
  • 2,084
  • 4
  • 23
  • 23

7 Answers7

33

Disabled and not editable are not necessarily the same thing. A disabled input is of course also not editable, but it has a distinct appearance - greyed out and looks 'disabled'. A read-only input looks the same as a normal input, but is not editable. So you have to ask whether you want your controls actually disabled or just read-only.

If you just want read-only, you can simply use the readonly property of <input> and bind it to a variable in your controller. For example:

export class LeaseholderComponent implements OnInit, IFormDirtyWarningComponent {

    @Input() editable: boolean = false; // doesn't have to be an @Input
    ...
}

<form [formGroup]="leaseholderForm" (ngSubmit)="onSubmit()">
    <mat-form-field>
        <input matInput [readonly]="!editable" upperCaseInput placeholder="Nom d'usage" formControlName="lastName">
    </mat-form-field>
    ...
</form>

Note that the editable property doesn't need to be an @Input, but that could be useful if you are using the form as a reusable component and need to make the editable/read-only decision at the DOM level.

For other components like radio buttons, where no readonly property is available, you should probably rethink the layout. It might make more sense to use a different component to display the radio option in read-only mode, rather than the complete list of options. For example, use a label and value pair:

<div *ngIf="editable; else readonlyRadio" class="mat-radio-group-inverted">
    <mat-radio-group formControlName="civility">
        <mat-radio-button color="primary" value="MR">M.</mat-radio-button>
        <mat-radio-button color="primary" value="MME">MME.</mat-radio-button>
    </mat-radio-group>
</div>
<div #readonlyRadio>
    <label>Civility</label>
    <span>{{ leaseholderForm.controls['civility'].value }}</span>
</div>
G. Tranter
  • 16,766
  • 1
  • 48
  • 68
25

If you are using reactive form you can achieve this programmatically like this (one-by-one approach):

 this.formGroupName.controls[controlNmae].disable();

Eg: this.formGroupName.controls['lastName'].disable()

To disable all at once:

this.formGroupName.disable()

In your case do: this.leaseholderForm.disable()
And to turn it back do: this.leaseholderForm.enable()

What you can do is create a function like this and call it after you have called createLeaseholderForm():

disableForm() {
 this.leaseholderForm.disable()
}  

for more info read this.

BlackBeard
  • 10,246
  • 7
  • 52
  • 62
9

Since disabled attribute doesn't work on some components, what I did is - I set the pointer-events:none on the css to cover all the components inside the div content.

Here's my CSS code:

.disabledDiv {
      pointer-events: none;
      opacity: 0.4;   }

Here's my HTML:

<div class="content-area" [ngClass]="{disabledDiv: !isActiveDiv}"> 
    <!-- other components here (input/select/etc.) -->
<div> 

And on my TS:

editData() {
    this.isActiveDiv = true;
  }
KimCindy
  • 1,159
  • 1
  • 11
  • 15
1

Create a FormGroup as explained here:

https://angular.io/guide/reactive-forms#add-a-formgroup

Then, grab the formGroup instance programmatically and call .disable() on it, like this:

this.leaseholderForm.disable()

ggradnig
  • 13,119
  • 2
  • 37
  • 61
1

Use disable attribute in the html template.

           <mat-form-field>
                <input matInput upperCaseInput placeholder="Nom d'usage" formControlName="lastName" disable>
            </mat-form-field>
Aditya
  • 2,358
  • 6
  • 35
  • 61
  • 1
    The disabled property should not be used with input elements in Angular reactive forms. The form control should be disabled instead: `control = new FomrControl({'value', disabled: true}, [validators]);` – G. Tranter Jun 25 '18 at 18:40
1

enter image description here

Use readonly attribute in the HTML file inside the input tag.

ross
  • 2,684
  • 2
  • 13
  • 22
NaduniJ
  • 27
  • 4
  • 9
    Try not to use images of code to answer questions - code is text, why not post it as such? – ross Sep 12 '19 at 09:53
1
this.formGroupName.controls['lastName'].disable()

Did not work for me in Angular 8. So I made it work by adding a 'readonly' attribute inside the HTML and then change its value in .ts file.

inside .html file

 <input formControlName="email" matInput type="email" #email email="true" [readonly]="email_readonly" />

inside .ts file

email_readonly = false;

yourFunction()
{
  this.email_readonly = true;
}
Nishant Kohli
  • 445
  • 6
  • 6