0

I want to make sure the user submit the form before they jump to other page, so when user type something into the form, if they haven't submit but try to clink the link go to other page, it should pop up the error dialog.

However, I don't really know how to do it in NgForm in Angular.....

below is my template, using template driven

<h2>My Form </h2>
<form (ngSubmit)="onSubmit()" #heroForm="ngForm">
  <div class="form-group">
    <label for="name">Name</label>
    <input type="text" class="form-control" id="name"
           required
           [(ngModel)]="model.name" name="name"
           #name="ngModel">
    <div [hidden]="name.valid || name.pristine"
         class="alert alert-danger">
      Name is required
    </div>
  </div>

  <div class="form-group">
    <label for="alterEgo">Alter Ego</label>
    <input type="text" class="form-control" id="alterEgo"
           [(ngModel)]="model.alterEgo" name="alterEgo">
  </div>

  <div class="form-group">
    <label for="power">Hero Power</label>
    <select class="form-control" id="power"
            required
            [(ngModel)]="model.power" name="power"
            #power="ngModel">
      <option *ngFor="let pow of powers" [value]="pow">{{pow}}</option>
    </select>
    <div [hidden]="power.valid || power.pristine" class="alert alert-danger">
      Power is required
    </div>
  </div>

  <button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>
  <button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
</form>
<ul>
  <li>
    <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
  </li>
  <li>
    <h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
  </li>
  <li>
    <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
  </li>
</ul>

my component

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  powers = ['Really Smart', 'Super Flexible',
  'Super Hot', 'Weather Changer'];

model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet');

submitted = false;

onSubmit() { this.submitted = true; }

newHero() {
this.model = new Hero(42, '', '');
}

get diagnostic() { return JSON.stringify(this.model); }
}

export class Hero {

  constructor(
    public id: number,
    public name: string,
    public power: string,
    public alterEgo?: string
  ) {  }

}
ckky1213
  • 321
  • 5
  • 14
  • 1
    What you are looking for is one of the angular life cycle hook `CanDeactivate` guard. https://stackoverflow.com/questions/35922071/warn-user-of-unsaved-changes-before-leaving-page – penleychan Jun 29 '18 at 16:50
  • This is work on chrome, but when I use IE11, it seems it always pop up the unsubmit error, I guess is because IE11 will always unload the page even I just click to go to different Angular component? @HostListener('window:beforeunload') canDeactivate(): boolean { return !this.form.dirty || this.form.submitted; } – ckky1213 Jul 02 '18 at 08:21

1 Answers1

0

What you could do is, remove the disabled property on the button -- and handle the submit in your component. So in your component if the form.valid then route, if not then do logic to show popup.

Component:

onSubmitOfForm(): void {
     if(form.valid){
      this.router.navigate(['/']);
     } else {
      // Show popup
     }
}

Or you could move validation to form level instead of the component ex:

constructor(private fb: FormBuilder) { 
this.form = this.fb.group({
  rangeStart: [null, Validators.required],
  rangeEnd: [null, Validators.required]
}, { validator: MyAwesomeRangeValidator});   

}

MyAwesomeRangeValidator Which would do whatever validation requirement you have.

  const MyAwesomeRangeValidator: ValidatorFn = (fg: FormGroup) => {
  const start = fg.get('rangeStart').value;
  const end = fg.get('rangeEnd').value;
      return start !== null && end !== null && start < end 
        ? null 
        : { range: true };
};

for Reference: https://medium.com/@realTomaszKula/angular-cross-field-validation-d94e0d063b61

Taranjit Kang
  • 2,510
  • 3
  • 20
  • 40