Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 Custom Component - mark as pristine and untouched

Tags:

I have a template driven form in Angular 2.1 containing many standard controls (<input>, <select> etc) and a custom control which itself contains multiple input elements.

I've implemented ControlValueAccessor on the custom control and it is propagating it's changed/touched/valid values correctly to the parent form.

However .. on the parent form I have a Save button, on which after saving I want to clear the dirty/touched state (as this affects the css applied) like this:

save(myForm: NgForm) {

    myForm.form.markAsPristine();
    myForm.form.markAsUntouched();

}

This is working ok for all the elements in the top level parent form and the custom control itself but the <input> fields within the custom control are still marked as touched/dirty (and this receiving the pre-saved styling).

Is there a way that the custom control can be notified when it's dirty/touched state is changed so that it can then clear it's child <input> elements to match? It seems that if the <input> elements are within a custom control they don't get updated by calls to markAsPristine/Untouched on the parent Form.

Thanks!

like image 496
Garth Mason Avatar asked Dec 22 '16 03:12

Garth Mason


People also ask

How do you set a form as pristine?

$setPristine(); Sets the form to its pristine state. This method sets the form's $pristine state to true, the $dirty state to false, removes the ng-dirty class and adds the ng-pristine class.

How do you set a pristine to a false form?

Using $setPristine will set the $pristine property of the form to true and $dirty to false. $setDirty will do the contrary.

What is mark as dirty?

markAsDirty() is to mark all controls as dirty in the form. For this to work correctly, you'd have to also wrap it in a Clarity form container (which we don't have a generic wrapper yet, see #2864).


2 Answers

The workaround with the active flag does the job but I also found another way.

On the parent form, I can access my custom child component as ViewChild.

i.e in the parent form:

@ViewChild(CustomChildComponent) child1: CustomChildComponent;

Then when I save in the parent form, call that child directly.

save(myForm: NgForm) {

   // clear anything at the parent form level
   myForm.form.markAsPristine();
   myForm.form.markAsUntouched();

   // tell the custom component to do the same
   this.child1.markAsPristineAndUntouched();
}

Where in CustomChildComponent I've defined ..

// get the input controls in the the child that we want to clear 
@ViewChild('surname') surnameField: NgModel;

markAsPristineAndUntouched() { 

   this.surnameField.control.markAsPristine();
   this.surnameField.control.markAsUntouched();
   // .. clear other controls .. 
}
like image 148
Garth Mason Avatar answered Sep 21 '22 12:09

Garth Mason


Try to add controls['nameOfControl'] like this

 myForm.form.controls['nameOfControl'].markAsPristine();

The code above will only work for form controls.

THe following seems to be a good work around:

  active = true;
  newModel() {
    this.model = new yourModel(2, '',true, '');
    this.active = false;
    setTimeout(() => this.active = true, 0);
  }

Reset the form with a new Model AND to restore the 'pristine' class state. by toggling the 'active' flag will cause the form to be removed/re-added in a tick via NgIf. Yes it is a small work around until they can can fix :)

hope that helps

like image 42
BendYourTaxes Avatar answered Sep 17 '22 12:09

BendYourTaxes