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

3
  • 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 Commented May 22, 2019 at 12:58
  • Maybe this.unity.floor contains a value in the beginning. If it has value, then validation may pass Commented May 22, 2019 at 13:05
  • It does not.. tried with floor: [{value: null, disabled: true}, Validators.required] as well and the problem remains. Commented May 22, 2019 at 13:18

5 Answers 5

7

Try readonly instead of disabled.

Sign up to request clarification or add additional context in comments.

Comments

4

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

Comments

2

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

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

1 Comment

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 stackoverflow.com/questions/54533202/…
1

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)

Comments

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.