3

The simplified scenario is whereby on my form I have two fields - A and B.

Field A is required and enabled. Field B is also required but disabled and only populated (dynamically) as a result of data keyed in field A, ad as it happens in certain cases B may be resolved as NULL.

The user should not be able to submit the form unless both fields are populated, therefore I need to add required validation to field B (disabled/dynamically populated).

While the required validation works fine for enabled fields it seems ignored for the fields that are disabled.

<mat-form-field>
  <input name="FieldA" matInput formControlName="FieldA" placeholder="Field A" [maxLength]="6">
  <mat-error *ngIf="formErrors.FieldA">{{ formErrors.FieldA }}</mat-error>
</mat-form-field>

<mat-form-field>
  <input name="FieldB" matInput formControlName="FieldB" placeholder="Field B">
  <mat-error *ngIf="formErrors.FieldB">{{ formErrors.FieldB }}</mat-error>
</mat-form-field>


buildForm() {
  this.form = this.form.group({
      FieldA: ['', [Validators.required]],
      FieldB: [{ value: '', disabled: true }, [Validators.required]],
  });

Is there any way I can add validation to FieldB in HTML without enabling it?

tom33pr
  • 853
  • 2
  • 12
  • 30
  • https://stackoverflow.com/questions/54522845/angular-5-validating-disabled-fields?noredirect=1#comment95849776_54522845 ? – Eliseo Feb 05 '19 at 11:38

2 Answers2

9

Instead of disabled use readonly. The difference between these two attributes are that disabled fields are ignored on form submit and readonly fields are included on submit. Unfortunatelly angular does not support readonly option while using Reactive Forms Approach, but you can easily do it using property binding:

<input type="text" formContolName="FieldB" [readonly]="isReadonly">

Another option is to enable this field programmatically on submitting function (before the submit call).

EDIT: You can also get values which are marked as a disabled controls by calling this.form.getRawValue();

From the source code comment:

/**
* The aggregate value of the FormGroup, including any disabled controls.
*
* If you'd like to include all values regardless of disabled status, use this method.
* Otherwise, the value property is the best way to get the value of the group.
*/

getRawValue(): any;

XardasLord
  • 1,764
  • 2
  • 20
  • 45
  • 1
    [readonly] = "true" always triggers validation, even if the field has been populated with data... – tom33pr Feb 05 '19 at 11:45
  • If you will add `[readonly]="true"` and the fieldB will have `Validation.Required` it will validate the field on form submit as you expect – XardasLord Feb 05 '19 at 12:01
  • Problem is that with the following setup: ... FieldB: ['', [Validators.required]], ... {{ formErrors.FieldB }} ...the validation is ALWAYS triggered and showing field required, even if the field is populated... Is this a bug? – tom33pr Feb 05 '19 at 12:07
  • What is `formErrors`? This is your own class? How do you check if the FieldB is valid? I mean how do you assign a value to `formErrors.FieldB`? – XardasLord Feb 05 '19 at 12:12
  • formErrors = { FieldA: '', FieldB: '' }; this.form.valueChanges.subscribe((data) => { this.formErrors = this.formValidationService.validateForm(this.form, this.formErrors, true); }); [value]="address" comes is assigned in typescript as a result of the webAPI called when fieldA is populated. – tom33pr Feb 05 '19 at 12:21
  • And are you sure that this webAPI call returns correct value for FieldB ? – XardasLord Feb 05 '19 at 12:25
  • Absolutely. I see the field being populated with a value. It is read only so that's good, except it is showing in red and validation error is thrown and I cannot proceed.Thanks for looking in this BTW! – tom33pr Feb 05 '19 at 12:27
  • Is is really strange, because disabled inputs are considered as invalid inputs but readonly inputs are not. `formErrors.FieldB` should be false... – XardasLord Feb 05 '19 at 12:33
  • 1
    Got this working. Went for [readonly] = "true" as you suggested but then had to additionally set the field's value programmatically: this.form.get('FieldB').setValue(this.result); rather than just binding it in html to a string from the code behind: [value]="address" It works now, thanks – tom33pr Feb 05 '19 at 13:18
  • Please fix wrong "formContolName" (missing "r") to be "formControlName". Edit queue was full, so I couldn't do that myself. – Janos Vinceller Dec 01 '20 at 22:01
0

Plase use And make custom css

<mat-hint class="deep-red" *ngIf="form.submitted && *ngIf="formErrors.FieldB">This field is required</mat-hint>