7

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]
});
3
  • I am facing some issue in pasting the code. It is not happening properly. I am trying to paste propely Commented Jun 4, 2018 at 6:27
  • Yes now my complete code is available Commented Jun 4, 2018 at 6:28
  • stackoverflow.com/questions/49205601/… Commented Jun 4, 2018 at 6:35

4 Answers 4

10

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

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

Comments

3

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.

2 Comments

All the fields should be enabled initially . Only when user enters email , phone No field should be disabled
@Nancy you can comment out this.form.disable(); in AppComponent.
2

If you are using a reactive form approach to take inputs from user and then you want to enable or disable the fields based on user action. So, you could do the following...

Suppose your FormGroup looks like this -->

// cityRef field will be automatically disabled intially, as property disabled: true is set

this.signUpFrom = new FormGroup({
      userData: new FormGroup({
        mobileNumber: new FormControl(null, [Validators.required, Validators.minLength(10), Validators.maxLength(10)]),
        password: new FormControl(null, [Validators.required]),
        userType: new FormControl('VENDOR')
      }),
      otherData: new FormGroup({
        cityRef: new FormControl({ value: null, disabled: true }, [Validators.required]),
        email: new FormControl(null, [Validators.required, Validators.email]),
        address: new FormControl(null, [Validators.required])
      }),
      name: new FormControl(null, [Validators.required]),
    });

Now if you want to disable / enable email, password, name etc, based on user actions. You can do this in just one step. (Example of accessing different fields)

this.signUpFrom.get('otherData.email').enable(); // To enable
this.signUpFrom.get('otherData.email').disable(); // To disable

this.signUpFrom.get('userData.password').enable(); // To enable
this.signUpFrom.get('userData.password').disable(); // To disable

this.signUpFrom.get('name').enable(); // To enable name field
this.signUpFrom.get('name').disable(); // To disable name field

You can put these codes in function that can be called in onClick or in onChanges etc.

Even you can get the current situation of fields weather it is disabled or enabled by using

this.signUpFrom.get('name').disabled; // return true if disabled
this.signUpFrom.get('name').enabled; // return true if enabled

May be late on answering this question, but since i found useful i thought to answer it as this may be helpful to you or somebody else!

Comments

1

You can use Angular FormContol properties like

  • dirty
  • touched
  • untouched
  • errors

to do this.

What you have to do is check the status of the formControl and disable the fields or the buttons based on your requirement.

2 Comments

the main problem in a reactive form to enable/disable a control is that you need use the method disable() or enable(). the properties dirty, touched, untouched are not enought to disable the control
I am not getting a proper answer for this .. Can you guys help me on this

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.