1

I have this

HTML

<div [formGroup]="frmStepTwo" fxLayout="column">
    <sfc-account-selector formControlName="account">
    </sfc-account-selector>
</div>

TS (view)

 this.frmStepTwo = this._formBuilder.group({
        procedure: ["", Validators.required],
        account: ["", Validators.required]
 });

sfc-account-selector.html

<div class="sfc-account-selector" [formGroup]="ctrlGroup">
    <mat-radio-group
            fxLayout="column"
            (change)="inputChange($event)"
            formControlName="account">
        <mat-radio-button [value]="account" *ngFor="let account of accounts">
            <div>
                <img class="sfc-as-option-icon" [src]="imgBase + account.iconPath"/>
                <div class="sfc-as-label">
                    <span class="sfc-as-name">{{account.serviceName}}</span>
                    <span class="sfc-as-desc">{{account.serviceDescription}}</span>
                </div>
            </div>
        </mat-radio-button>
    </mat-radio-group>

    <small *ngIf="required">REQUIRED</small>
</div>

sfc-account-selector is a custom form control. The problem I'm facing is that if I use the required attribute on the <sfc-account-selector> the getter and the setter will trigger. If I wrap my control in another form control, the require won't trigger.

Is there a way to update the "required" when wrapping in a required formControl?

1 Answer 1

1

It's bit tricky. But I got it working by doing this.

custom-comp.component.ts

    const isParentControlRequired = function (control: FormControl) {
        if (control.validator !== null) {
            const validator = control.validator({}as AbstractControl);
            return validator && validator.required;
        }
        return false;
    };

    export class someComponent {
          ....

        @Input()
        get required() {
            return this._required;
        }

       set required(req) {
           this._required = coerceBooleanProperty(req);
           this._updateValidators();
           //Emit stateChange to update value in mat-groupCtrl-field
          this.stateChanges.next();
       }

       @Input()
       get disabled() {
           return this._disabled;
       }

       set disabled(dis) {
           this._disabled = coerceBooleanProperty(dis);
           this._disabled ? this.parts.disable() : this.parts.enable();
           this._updateValidators();
           //Emit stateChange to update value in mat-groupCtrl-field
           this.stateChanges.next();
       }

       @Input() formControlName: string;

       private _containerControl: FormControl;

       constructor(private _elRef: ElementRef,
                private _formBuilder: FormBuilder,
                private _focusMonitor: FocusMonitor,
                @Optional() @Host() @SkipSelf()
                private controlContainer: ControlContainer) {

                    this.parts = _formBuilder.group({
                       "pwd": ["", this._baseValidators],
                       "pwdRepeat": ["", this._baseValidators],
                 },
                 {validator: valuesMatchValidation(["pwd", "pwdRepeat"])}
                );

                _focusMonitor.monitor(_elRef.nativeElement, true)
                       .subscribe(origin => {
                            this.focused = !!origin;
                            this.stateChanges.next();
                });
         }


         ngOnInit(): void {

               if (!!this.formControlName && this.controlContainer) {
                     this._containerControl = <FormControl>this.controlContainer.control.get(this.formControlName);
                     this.required = isParentControlRequired(this._containerControl);
        }


        ngDoCheck(): void {
              if (!!this._containerControl) {
                    let parentCtrlDisabled = this._containerControl.disabled;

              if (this.disabled !== parentCtrlDisabled) {
                    this.disabled = parentCtrlDisabled;
              }

             let parentCtrlRequired = isParentControlRequired(this._containerControl) && !parentCtrlDisabled;

            if (this.required !== parentCtrlRequired) {
                 this.required = parentCtrlRequired;
            }
    }

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.