Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 reactive forms field enable/disable

I am trying to create a simple angular 2 reactive forms with email and phone number. Below is my code . I am facing two problems here.

  1. Initially verify button should be disable. It should be enabled , only when email field is entered.

  2. Second issue is I want to have only one field enabled at time. If user starts typing in email, then phone number should be disabled and vice versa. Save button will be enabled either if email OR phone no is entered

How do I achieve this?

<form [formGroup]="personalDtlsForm">
  <div class="form-group" [ngClass]="displayFieldCss('inputValue')">
    <div class="row">
      <div class="col">
        <label for="inputValue" class="control-label required">Email</label>
      </div>
    </div>
    <div class="row">
      <div class="col-9">
        <input type="text" id="email" class="form-control" formControlName="inputValue">
      </div>
      <div class="col-3">
        <button type="button" id="verifyBtn" class="btn btn-primary btn-large" (click)="verify()">Verify</button>
      </div>
    </div>

  </div>

  <div class="form-group row" [ngClass]="displayFieldCss('phoneNo')">
    <div class="col paddingTop">
      <label for="phoneNo" class="userID control-label textColor">Phone
      </label>
      <input type="number" class="form-control" id="phoneNo" formControlName="phoneNo">
    </div>
  </div>
  <div class="viewdetailbtn">
    <button type="button" [disabled]="!personalDtlsForm.valid" class="btn btn-primary btn-large btnwidth marginBottom" (click)="savePersonalDtls()">Save</button>
  </div>
</form>


this.personalDtlsForm = this.formBuilder.group({
  inputValue: [null, [Validators.required, Validators.email]],
      phoneNo: [null, Validators.required]
});
like image 434
Nancy Avatar asked Dec 04 '22 20:12

Nancy


2 Answers

You can enable/disable the control with:

this.personalDtlsForm.controls['phoneNo'].enable()

this.personalDtlsForm.controls['phoneNo'].disable()

So to disable a field you have to subscribe on the valueChanges of the other field and disable the other field if value !== '' or something like that.

Example:

this.personalDtlsForm.controls['phoneNo'].valueChanges.subscribe(
    value => {
        if(value !== ''){
            this.personalDtlsForm.controls['inputValue'].disable();
        } else {
            this.personalDtlsForm.controls['inputValue'].enable();
        }
    }
);

And ofcourse the same kind of subscribe on the inputValue formControl

For your second question, you can set a variable isFormValid in the if-statement when value !== '' which means at least one of them is entered.

Final check to enable the button could be something like:

isFormValid && personalDtlsForm.valid

like image 96
Venomy Avatar answered Dec 14 '22 22:12

Venomy


Initially verify button should be disable. It should be enabled , only when email field is entered.

You can simply bind disabled with valid status of email field. Mention that when input's status is disabled, it won't be valid or invalid.

<button type="button" [disabled]="personalDtlsForm.get('inputValue').invalid">Verify</button>

Second issue is I want to have only one field enabled at time. If user starts typing in email, then phone number should be disabled and vice versa.

In order to disable all other form controls in the form, first we will need to access all of them, we can do this via formGroupDirective.directives.
I have created a custom directive to achieve what you want.

@Directive({
  selector: '[disableAllOthers]'
})
export class DisableAllOthers {
  constructor(
    private elem: ElementRef, 
    private control: NgControl,
    private renderer: Renderer2
  ) {
    this.elem.nativeElement.addEventListener('mouseover', () => {
      (this.control as FormControlName).formDirective.directives.forEach(elem => {
        if (elem === this.control) {
          elem.control.enable();
        } else {
          elem.control.disable();
        }
      });
    });
  }
}

For click/focus event won't fire when input is disabled, here I changed disable/enable via mouse over event, see demo.

like image 32
Pengyy Avatar answered Dec 14 '22 22:12

Pengyy