angularangular-template-form

Notification upon Form Reset Event?


Is there a way to get notified when a form is reset via the formReset method?

I have a directive that injects the form and I can get notified when the form is submitted or reset via a reset button but I cannot figure out a way to get notified when formRest is called on ngForm.

@Directive({
  selector: '[appForm]'
})
export class FormDirective implements OnDestroy {
  private subscription: Subscription;

  constructor(form: NgForm) {
    this.subscription = form.ngSubmit.subscribe(() => {
      console.log('submitted');
    });
    form.onReset = () => {
      console.log('reset');
    };
  }

  ngOnDestroy() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
}

Using the directive like

<form appForm #form="ngForm">
  <button type="submit">Submit</button>
  <button type="reset">Reset</button>
  <button type="button" (click)="form.resetForm()">Angular reset</button>
</form>

Is there a way to notify my directive that the resetForm method has been called?

Demo at StackBlitz https://stackblitz.com/edit/angular-adymlf?file=src/app/form.directive.ts


Solution

  • Based on w3schools onReset event, "reset" event is only triggered when the <input type="reset">. This is probably a default behaviour in browsers.

    Angular's resetForm() and reset() doesn't actually trigger the reset event. It simply programatically revert the values of the form. resetForm() allows you to reset the submitted status of the angular form and also define intial values for the form to be reset to by passing in an object like this: resetForm({}).

    This can be proven by adding a @HostListener('reset') in your attribute directive to listen for reset events. When form.resetForm() and form.reset() is called (or rather, clicked), reset event is not triggered at all.


    Listening for clicks in Attribute Directives for buttons

    To work around this, you can simply use <button type="reset">? But if it doesn't suit your use case, and you need to use <button type="button"> and still detect a reset event then you can probably add another @HostListener to listen for click events for input type of buttons:

    @HostListener('click', ['$event.target']) onFormClick(btn: HTMLButtonElement){
      // console.log(btn)
      if(btn.type == "button"){
        console.log("detected click event on 'Angular reset' button, triggering reset event!");
        this.form.onReset();
      }
    }
    

    Detecting when NgForm's resetForm() is called (EDIT)

    
    //to store original resetForm()
    resetFormFunc;
    
    constructor(private form: NgForm, private elRef: ElementRef) {
    
       ...
    
       this.resetFormFunc = form.resetForm; //assigning resetForm function to "store" it.
    
       //"Override" resetForm(), and call original resetForm() in the middle
       form.resetForm = () => {
         console.log("detected calling of resetForm()!");
         this.resetFormFunc.apply(form, arguments); //actually call form.resetForm()
         console.log("my additional code");
       }
    }
    

    When "Angular Reset" is clicked: enter image description here

    #2 Forked Stackblitz ⚡

    Hope this helps!