ngneat / dirty-check-forms

🐬Detect Unsaved Changes in Angular Forms

Home Page:https://netbasal.com/detect-unsaved-changes-in-angular-forms-75fd8f5f1fa6

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool


Test MIT commitizen PRs styled with prettier All Contributors ngneat spectator

The cleanest way to do the dirty job

Detect Unsaved Changes in Angular Forms

Features

  • ✅ Dirty Check Forms!
  • ✅ Support In-App Navigation
  • ✅ Support Form Departure

Table of Contents

Installation

npm install @ngneat/dirty-check-forms

Usage

Call the dirtyCheck function, which accepts three arguments:

  1. AbstractControl (FormControl, FormGroup, FormArray)
  2. A stream with the original value to compare
  3. Config:
  • debounce - debounce time of valueChanges. Defaults to 300
  • withDisabled - whether to include disable fields (by using control's getRawValue) or not. Defaults to true.
  • useBeforeunloadEvent - enable or disable onbeforeunload event handling. Defaults to true.

The function returns an Observable<boolean>, which notifies whether the form is dirty. Furthermore, it also hooks on the browser's beforeunload event to confirm upon refreshing/closing the tab when needed.

For example:

import { dirtyCheck } from '@ngneat/dirty-check-forms';

@Component({ ... })
export class SettingsComponent {
  storeSub: Subscription;

  settings = new FormGroup({
    firstName: new FormControl(''),
    lastName: new FormControl('')
  });

  isDirty$: Observable<boolean>;

  constructor(private store: Store) {}

  ngOnInit() {
    // Update the form with the current store value
    this.storeSub = this.store.selectSettings()
      .subscribe(state => this.settings.patchValue(state, { emitEvent: false }));

    // Initialize dirtyCheck
    this.isDirty$ = dirtyCheck(this.settings, this.store.selectSettings());
  }

  ngOnDestroy() {
    this.storeSub && this.storeSub.unsubscribe();
  }
}
<form [formGroup]="settings">
  <input type="text" formControlName="firstName" placeholder="First name" />
  <input type="text" formControlName="lastName" placeholder="Last name" />

  <button (click)="submit()" [disabled]="isDirty$ | async">Submit</button>
</form>

In-App Navigation:

Create a guard that extends DirtyCheckGuard, and provide the confirmChanges method:

import { Injectable } from "@angular/core";
import { DirtyCheckGuard } from "@ngneat/dirty-check-forms";
import { Observable } from "rxjs";

@Injectable()
export class DirtyGuard extends DirtyCheckGuard {
  constructor() {
    super();
  }

  confirmChanges(): Observable<boolean> | boolean {
    return confirm('Are you sure you want to discard changes?');
  }
}

Note that when using a guard, your component must implement the DirtyComponent interface:

import { dirtyCheck, DirtyComponent } from '@ngneat/dirty-check-forms';

@Component({ ... })
export class SettingsComponent implements DirtyComponent { ... }

The last step is to activate the DirtyCheckGuard:

const routes: Routes = [
  {
    path: 'settings',
    component: SettingsComponent,
    canDeactivate: [DirtyCheckGuard],
  },
];

You can find a complete example here.

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Dan Roujinsky

💻 📖 💡 🤔 📆

Netanel Basal

📝 💻 🖋 🎨 📖 💡 🚇 🚧 📆 ⚠️

This project follows the all-contributors specification. Contributions of any kind welcome!

About

🐬Detect Unsaved Changes in Angular Forms

https://netbasal.com/detect-unsaved-changes-in-angular-forms-75fd8f5f1fa6

License:MIT License


Languages

Language:TypeScript 70.7%Language:JavaScript 22.7%Language:HTML 5.9%Language:SCSS 0.6%