2

I have an input which will be populated when the user clicks on a dialog. So for this I had to make it disabled, because I don't want the user to manually input the value. The only problem is that this input must be required, and I couldn't make it so far.

I have tried to add 'required' directive in the input and also tried adding Validator.required on the form creation, but none of these made the field required for the form.

createUnityForm(): FormGroup {
    return this._formBuilder.group({
        id      : [this.unity.id],
        description: [this.unity.description],
        floor: [{value: this.unity.floor, disabled: true}, Validators.required]
    });
}

<mat-form-field appearance="outline" floatLabel="always" class="mr-16" fxFlex>
    <mat-label>{{'UNITY.FLOOR' | translate}}</mat-label>
    <input matInput placeholder="{{'UNITY.SELECT-FLOOR' | translate}}"
        name="floor"
        formControlName="floor"
        required>
</mat-form-field>

<button *ngIf="action === 'edit'"
    mat-button
    class="save-button"
    (click)="matDialogRef.close(['save',unityForm])"
    [disabled]="unityForm.invalid"
    aria-label="save">
        {{'GENERAL.SAVE' | translate}}
</button>

unityForm is valid even when there's nothing in the input

  • When I try to add [disabled] = true in the input, angular shows in the console: It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true when you set up this control in your component class, the disabled attribute will actually be set in the DOM for you. We recommend using this approach to avoid 'changed after checked' errors. Example: form = new FormGroup({ first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), }); Which is exactly what I coded. Doesn't work – Marcos Bertuol May 22 '19 at 12:58
  • Maybe `this.unity.floor` contains a value in the beginning. If it has value, then validation may pass – Dilan Tharaka May 22 '19 at 13:05
  • It does not.. tried with floor: [{value: null, disabled: true}, Validators.required] as well and the problem remains. – Marcos Bertuol May 22 '19 at 13:18

5 Answers5

5

Try readonly instead of disabled.

2

If you set a FormControl to disabled its validators will be ignored.

More info: https://angular.io/api/forms/AbstractControl#disabled

Ritchie
  • 502
  • 4
  • 13
  • This isn't right, you can't set a formControl dynamically using the disabled property, it's read only! You'll probably want Validation rules then use a readonly property to disable it https://stackoverflow.com/questions/54533202/add-validation-to-angular-material-disabled-field – Ben Petersen May 06 '21 at 19:35
1

When it sets the disabled attribute, the validators will be ignored.

Disabled controls are exempt from validation checks and are not included in the aggregate value of their ancestor controls.

See: https://angular.io/api/forms/AbstractControl#disabled

If you want to make it disabled with the required or consider the validation, you have to make it readonly.

this._formBuilder.group({
    ...
    name: ['Your value here', Validators.required]
});
<input formControlName="name" readonly/>
0

Radoslaw has it. Try readonly in the HTML instead of disabled in the model. This provides a similar UI to a disabling a control in the model but the validation remains operative. This can be useful (for example pulling in records from elsewhere to commit to another db, not allowing any user changes, but only committing if original data are valid)

0

You can't, reactive forms don't use validators on disabled fields. I think it's a good way to do like this:

-HTML

<input
type="text"
formControlName="controlName"
[ngClass]="{ 'is-invalid': 
(c.controlName.errors || c.controlName.disabled) 
&& submited }"/>

-TypeScript

submited = false;

form: FormGroup = this.formBuilder.group({
    controlName: [{ value: '', disabled: true }, Validators.required]
});

get c(): { [key: string]: AbstractControl } {
    return this.form.controls;
}

save(): void {
    this.submited = true;    
    if (this.form.invalid
       || this.formControl.controlname.value === '') {
     return;
}

-CSS

.is-invalid {
  border: 1px solid #dc3545;
}

When you click on button for SAVE, required field will get red border if there is no value

S. Jovan
  • 29
  • 1
  • 5