22

I have an angular reactive form

<form [formGroup]="form" (ngSubmit)="onSubmit()">

I have two buttons to submit. I need to perform a common operation when users press the button, that is submit the form, but also I need to differentiate between the buttons, because I need to redirect the user to different pages, depending on the button pressed. Here is my two buttons:

<button name="Previous" type="submit" [disabled]="form.invalid"> Previous</button>
<button name="Next" type="submit" [disabled]="form.invalid">Next</button>

How can I know in the OnSubmit event which button was pressed?

Anuradha Gunasekara
  • 6,553
  • 2
  • 27
  • 37
user1238784
  • 2,250
  • 3
  • 22
  • 41

10 Answers10

22

user1238784, you shouldn't use document directly in Angular, use ElementRef or Renderer2 instead. While this works, it's against best practices and it will break SSR if you decide to use Angular Universal at some point.

Direct DOM manipulation in Angular is big no no, you should always manipulate DOM using API provided by framework.

But you don't even need any of that, you can pass event as param like this:

<form [formGroup]="form" (ngSubmit)="onSubmit($event.submitter.id)">

and then in component you can use event to identify button that was clicked

this is how you can access the id of the input/button being used to submit the form

submitForm(event : MouseEvent) :void
  {
    console.log(event)
  }
Nikola Rožić
  • 319
  • 2
  • 7
20

You can try with this solution

component.html

  <form [formGroup]="form" (ngSubmit)="onSubmit(buttonType)">
        <button type="submit" (click)="onSubmit('Next')">Next</button>
        <button type="button" (click)="onSubmit('Previous')">Previous</button>
    </form>

component.ts

onSubmit(buttonType): void {
        if(buttonType==="Next") {
            console.log(buttonType)
        }
        if(buttonType==="Previous"){
            console.log(buttonType)
        }

}
Krishna Rathore
  • 9,389
  • 5
  • 24
  • 48
18

Try this.

In your component.ts

import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  form: FormGroup;
  nextClicked = false;


  constructor(private fb: FormBuilder) {
   this.form = this.fb.group({
     age: [20],
     name: ['asdas']
   });
  }

  public onSubmit(): void {
    if(this.nextClicked) {
     ////
    }else {
      ////
    }

  }

  public onNextClick(): void {
    this.nextClicked = true;
  }

  public onPreviousClick(): void {
    this.nextClicked = false;
  }
}

And in your component.html

<div>
  <form [formGroup]="form" (ngSubmit)="onSubmit()">
    <input formControlName="age">
    <input formControlName="name">
    <button type="submit" (click)="onNextClick()">Next</button>
    <button type="submit" (click)="onPreviousClick()">Previous</button>
  </form>
</div>

And you can find a working example in this stackblitz.

You can add two separate event handlers for the click events in the two submit buttons. Those event handlers will be triggerd before the onSubmit method. You can use those two event handlers to update a state in the component to identify whether the use clicked on next or previous button.

And depending on that state you can direct the user to diferent pages on onSubmit method.

Anuradha Gunasekara
  • 6,553
  • 2
  • 27
  • 37
  • Great! Simple and obvious! I change to pass a parameter to that function, and I create one handler only. onDoThat(true) or onDoThat(false) – diegodsp Oct 31 '19 at 18:06
  • 3
    I'd say this is a cleaner solution. The accepted answer which uses the `document.activeElement` is not purely Angular solution and seems to be a bit hacky for me. – GoldenAge Nov 21 '19 at 11:44
6

I found an answer. A bit tricky: In the onSubmit event I check:

var buttonName = document.activeElement.getAttribute("Name");

Since one of the button must be the active element on the form when the user click it, this does the trick for me

user1238784
  • 2,250
  • 3
  • 22
  • 41
3
 HTML:
 <form [formGroup]="CreationForm" (ngSubmit)="onSubmit($event)">  
 <button type="submit" name="draft"> Save As Draft </button>   <button
 type="submit" name="save"> Save </button> </form>

Typescript:
onSubmit(event){
 if( event.submitter.name == "draft" )
 { console.log('draft'); }
 else if( event.submitter.name == "save")
 { console.log('save'); }
}
2

You could add a (click)="buttonClicked='previous/next'" event to the buttons (next/previous as appropriate). Then you have a member variable on your class buttonClicked: string which you read in your onSubmit() method and act as appropriate.

William Moore
  • 3,844
  • 3
  • 23
  • 41
2
<button name="Previous" type="button" [disabled]="form.invalid"> Previous</button>

Just replace the type="submit" to type="button" it wont fire submit event. https://github.com/angular/angular.js/issues/6017

0

if you are using wizard it's better to not check validity in Previous step!but if you want to check it you can not use ngsubmit but define your own action:

html:

<button name="Previous" type="submit" (click)="submitForm('pre')"[disabled]="form.invalid"> Previous</button>
<button name="Next" type="submit" (click)="submitForm('next')" [disabled]="form.invalid">Next</button>

in component:

submitForm(type) {
        if (!this.form.valid) {
            this.checkFormValidity();
            return;
        }
    if(type === 'pre'){
      //Redirect one page

}else{
  //Redirect another page
}
}

checkFormValidity() {
        for (let item in this.form.controls) {
            this.form.controls[item].markAsTouched();
        }
    }
Fateme Fazli
  • 11,582
  • 2
  • 31
  • 48
0

I solved this with the following solution:

Add a control to the form to store the value you need:

constructor(private fb: FormBuilder) {
   this.form = this.fb.group({
     next: this.fb.control(true) // Set a default value
   });
}

Create a property to easily access the control:

get submitControl(): AbstractControl { return (this.form) ? this.form.get('next') as AbstractControl : undefined; }

Then add your submit buttons to the form, setting the value by handling the click event:

<form novalidate [formGroup]="form" #f="ngForm" (ngSubmit)="onSubmit(f)">
  <button name="Previous" type="submit" [disabled]="form.invalid" (click)="submitControl.patchValue(false)">Previous</button>
  <button name="Next" type="submit" [disabled]="form.invalid" (click)="submitControl.patchValue(true)">Next</button>
</form>

Then you can access the value from the onSubmit handler:

onSubmit(f: FormGroupDirective) {
    console.log(f.value.next);
}
Emilio Brandon Flanagan
  • 1,142
  • 1
  • 12
  • 13
-2

try this:

HTML File:

<form [formGroup]="form" (ngSubmit)="onSubmit()">
<button name="Previous" type="submit" (click)="buttonClicked = 'previous'" [disabled]="form.invalid"> Previous</button>
        <button name="Next" type="submit" [disabled]="form.invalid" (click)="buttonClicked = 'next'">Next</button>

TS File:

buttonClicked:string;

    onSubmit() {
        if(buttonClicked == 'previous') {
             //Redirect one page
        } else {
             //Redirect another page
        }
    }