20

I have a form with a lot of form controls and Validators for some of the controls, like:

title = new FormControl("", Validators.compose([
    Validators.required
]));
description = new FormControl("", [
    Validators.required,
    Validators.minLength(1),
    Validators.maxLength(2000)
]);

How do I add a save as draft button that does not validate the controls? Or remove them?

I have tried a lot of examples such as:

saveDraft() {
   this.addProjectForm.controls.title.clearValidators();
   this.addProjectForm.controls.title.setErrors(null);
   this.addProjectForm.controls.title.setValidators(null);
}

or

saveDraft() {
   this.addProjectForm.controls['title'].clearValidators();
   this.addProjectForm.controls['title'].setErrors(null);
   this.addProjectForm.controls['title'].setValidators(null);
}

but nothing works..

Mohammed
  • 447
  • 1
  • 7
  • 18

7 Answers7

39

Try this:

this.addProjectForm.get('title').setValidators([]); // or clearValidators()
this.addProjectForm.get('title').updateValueAndValidity();

If you want to add a validator then append array of validators:

this.addProjectForm.get('title').setValidators([Validators.required]);
this.addProjectForm.get('title').updateValueAndValidity();

Note: You have to use updateValueAndValidity() after each change

Admir
  • 2,876
  • 1
  • 19
  • 19
12

You can try following as another solution if you want to remove validator from your field:

public saveDraft(): void {
   this.addProjectForm.get('title').clearValidators();
   this.addProjectForm.get('title').updateValueAndValidity();
}
billyjov
  • 2,778
  • 19
  • 35
5

I have tried all of above, But for me following code has worked.

let formControl : FormControl = this.formGroup.get("mouldVendor") as FormControl;
formControl.clearValidators();
formControl.setValidators(null);
formControl.updateValueAndValidity();
Kapil Thakkar
  • 840
  • 10
  • 17
2

I have implemented quite a lot of forms with this Save As Draft functionality.

What I generally do is, just keep the Submit Button as disabled unless the form is valid. But keep the Save as a Draft button as always enabled.

What this allows me to do is, save the contents of the form without applying any validation in case the user clicks the Save as Draft button.

The user can not click the Save button anyway as the form is not valid.

All of this translates to code like this:

<div class="image-flip">
  <div class="mainflip">
    <div class="frontside">
      <div class="card">
        <div class="card-body add-generic-card">

          <form [formGroup]="addGameForm">
            ...

            <div class="draft-publish-button">
              <button 
                class="..." 
                type="button" 
                (click)="onFormSubmit('DRAFT')">
                  Save as Draft
              </button>

              <button 
                class="..." 
                type="button" 
                (click)="onFormSubmit('PUBLISHED')" 
                [disabled]="addGameForm.invalid">
                  Publish
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>
SiddAjmera
  • 38,129
  • 5
  • 72
  • 110
  • So basically the user has to fill out everything when using the submit button, but the save as draft will work because there is no validation on the controls - might work, will try it out – Mohammed Nov 27 '18 at 20:41
  • Can you show me an example? I have tried this, but because there is no validation the submit button is always active after typing in the first input field.. – Mohammed Nov 27 '18 at 22:50
1

This may help someone. I ended up adding validation as a result of another fields '.valuechanges' subscription, and when I went to clear them It would do, well, nothing.

The solution was to use the method .clearAsyncValidators() on the formcontrol, instead of the typical clearValidators().

You still have to updateValueAndValidity(), but this worked for me.

Happy Coding!

iamaword
  • 1,327
  • 8
  • 17
0

You can use: AbstractControl.removeValidators(ValidatorFn)

Not sure if it is possible in angular 6, but definately in Angular 12 and higher. It needs however, a reference to the exact same function. Just giving it Validators.required does not work. You need to create a unique reference to it:

requiredValidator = Validators.required;
   
this.form = this._fb.group({
    title: ['', [this.requiredValidator, Validators.minLength(3), Validators.maxLength(50)]],
    description: ['', [this.requiredValidator, Validators.minLength(3)]]
}); 

saveDraft() {
    this.title.removeValidator(this.requiredValidator); 
}

get title(): AbstractControl {
  return this.form.get('title');
}
Tombalabomba
  • 181
  • 1
  • 7
-1

I found that the best solution is not to have any validation on the input fields (form controls) and then add this code to allow the submit button to be pressed:

ngAfterViewInit() {
this.addProjectForm.valueChanges.subscribe(data => {
  //console.log(data)

  if(data.title.length != 0 &&
    data.description.length != 0 &&
    data.ddemployees.length != 0 &&
    data.competences.includes(true) &&
    data.methods.includes(true) &&
    data.enddate.length != 0 &&
    data.contactname.length != 0 &&
    data.contactemail.length != 0 &&
    data.contactphonenumber.length != 0 
    ) {
    //console.log(data.title.length)
    this.allowSubmit = true;
  } 
});

}

Mohammed
  • 447
  • 1
  • 7
  • 18
  • It will create not a good responsive design. user needs to know before hits submit that is a good pattern – MJ X Oct 29 '19 at 17:39