@stimulus-library/controllers
Version:
A library of useful controllers for Stimulus
44 lines (43 loc) • 1.79 kB
JavaScript
import { BaseController } from "@stimulus-library/utilities";
import { useDirtyFormTracking, useEventListener } from "@stimulus-library/mixins";
export class FormDirtyConfirmNavigationController extends BaseController {
constructor() {
super(...arguments);
this._enabled = false;
this._teardowns = [];
}
get _message() {
return this.hasMessageValue ? this.messageValue : "Do you want to leave this page? Changes you made may not be saved";
}
connect() {
useDirtyFormTracking(this, this.el);
useEventListener(this, this.el, "form-dirtied", this._enable);
useEventListener(this, this.el, "form-cleaned", this._disable);
}
_enable() {
if (this._enabled) {
return;
}
this._enabled = true;
window.onbeforeunload = () => this._message;
const { teardown: submitTeardown } = useEventListener(this, window, ["submit", "turbo:submit-start"], this._disable);
const { teardown: popstateTeardown } = useEventListener(this, window, "popstate", this._confirmNavigation);
const { teardown: turbolinksTeardown } = useEventListener(this, window, ["turbolinks:before-visit", "turbo:before-visit"], this._confirmTurboNavigation);
this._teardowns = [submitTeardown, popstateTeardown, turbolinksTeardown];
}
_disable() {
this._enabled = false;
window.onbeforeunload = null;
this._teardowns.forEach(teardown => teardown());
this._teardowns = [];
}
_confirmNavigation(_event) {
return false;
}
_confirmTurboNavigation(event) {
if (!confirm(this._message)) {
event.preventDefault();
}
}
}
FormDirtyConfirmNavigationController.values = { message: String };