Etemplate: Check dirty before closing, ask if there are changes

This commit is contained in:
nathangray 2020-06-19 13:27:41 -06:00
parent 73515cd412
commit 52714f0a63
14 changed files with 149 additions and 23 deletions

View File

@ -58,6 +58,14 @@ var et2_inputWidget = /** @class */ (function (_super) {
_super.prototype.destroy.call(this);
this._labelContainer = null;
};
/**
* Make sure dirty flag is properly set
*/
et2_inputWidget.prototype.doLoadingFinished = function () {
var result = _super.prototype.doLoadingFinished.call(this);
this.resetDirty();
return result;
};
/**
* Load the validation errors from the server
*
@ -212,7 +220,25 @@ var et2_inputWidget = /** @class */ (function (_super) {
return this._oldValue;
};
et2_inputWidget.prototype.isDirty = function () {
return this._oldValue != this.getValue();
var value = this.getValue();
if (typeof value !== typeof this._oldValue) {
return true;
}
if (this._oldValue === value) {
return false;
}
switch (typeof this._oldValue) {
case "object":
if (this._oldValue.length !== value.length)
return true;
for (var key in this._oldValue) {
if (this._oldValue[key] !== value[key])
return true;
}
return false;
default:
return this._oldValue != value;
}
};
et2_inputWidget.prototype.resetDirty = function () {
this._oldValue = this.getValue();

View File

@ -96,6 +96,18 @@ export class et2_inputWidget extends et2_valueWidget implements et2_IInput, et2_
this._labelContainer = null;
}
/**
* Make sure dirty flag is properly set
*/
doLoadingFinished() : boolean | JQueryPromise<unknown>
{
let result = super.doLoadingFinished();
this.resetDirty();
return result;
}
/**
* Load the validation errors from the server
*
@ -300,7 +312,27 @@ export class et2_inputWidget extends et2_valueWidget implements et2_IInput, et2_
isDirty()
{
return this._oldValue != this.getValue();
let value = this.getValue();
if(typeof value !== typeof this._oldValue)
{
return true;
}
if(this._oldValue === value)
{
return false;
}
switch(typeof this._oldValue)
{
case "object":
if(this._oldValue.length !== value.length) return true;
for(let key in this._oldValue)
{
if(this._oldValue[key] !== value[key]) return true;
}
return false;
default:
return this._oldValue != value;
}
}
resetDirty()

View File

@ -316,10 +316,10 @@ var et2_customfields_list = /** @class */ (function (_super) {
return value;
};
et2_customfields_list.prototype.isDirty = function () {
var dirty = true;
var dirty = false;
for (var field_name in this.widgets) {
if (this.widgets[field_name].isDirty) {
dirty = dirty && this.widgets[field_name].isDirty();
dirty = dirty || this.widgets[field_name].isDirty();
}
}
return dirty;

View File

@ -430,12 +430,12 @@ export class et2_customfields_list extends et2_valueWidget implements et2_IDetac
isDirty( )
{
let dirty = true;
let dirty = false;
for(let field_name in this.widgets)
{
if(this.widgets[field_name].isDirty)
{
dirty = dirty && this.widgets[field_name].isDirty();
dirty = dirty || this.widgets[field_name].isDirty();
}
}
return dirty;

View File

@ -344,8 +344,8 @@ var et2_selectbox = /** @class */ (function (_super) {
this.setDOMNode(node[0]);
};
et2_selectbox.prototype.doLoadingFinished = function () {
_super.prototype.doLoadingFinished.call(this);
this.set_tags(this.options.tags, this.options.width);
_super.prototype.doLoadingFinished.call(this);
return true;
};
et2_selectbox.prototype.loadFromXML = function (_node) {
@ -1366,6 +1366,12 @@ var et2_selectbox_ro = /** @class */ (function (_super) {
et2_selectbox_ro.prototype.getValue = function () {
return null;
};
/**
* Readonly selectbox can't be dirty
*/
et2_selectbox_ro.prototype.isDirty = function () {
return false;
};
/**
* Functions for et2_IDetachedDOM
*/

View File

@ -484,10 +484,10 @@ export class et2_selectbox extends et2_inputWidget
doLoadingFinished()
{
super.doLoadingFinished();
this.set_tags(this.options.tags, this.options.width);
super.doLoadingFinished();
return true;
}
@ -1679,6 +1679,14 @@ export class et2_selectbox_ro extends et2_selectbox implements et2_IDetachedDOM
return null;
}
/**
* Readonly selectbox can't be dirty
*/
isDirty()
{
return false;
}
/**
* Functions for et2_IDetachedDOM
*/

View File

@ -218,6 +218,7 @@ var et2_tabbox = /** @class */ (function (_super) {
}
jQuery.when.apply(jQuery, promises).then(function () {
tab_deferred.resolve();
tabs.resetDirty();
});
}, 0);
return tab_deferred.promise();

View File

@ -274,6 +274,7 @@ class et2_tabbox extends et2_valueWidget implements et2_IInput,et2_IResizeable,e
}
jQuery.when.apply(jQuery,promises).then(function() {
tab_deferred.resolve();
tabs.resetDirty();
});
},0);

View File

@ -279,6 +279,7 @@ var et2_taglist = /** @class */ (function (_super) {
this.div.on('blur', 'input', function () {
jQuery('.ms-ctn-focus', widget.div).removeClass('ms-ctn-focus');
});
this.resetDirty();
return true;
};
/**

View File

@ -430,6 +430,8 @@ export class et2_taglist extends et2_selectbox implements et2_IResizeable
this.div.on('blur', 'input', function() {
jQuery('.ms-ctn-focus', widget.div).removeClass('ms-ctn-focus');
});
this.resetDirty();
return true;
}

View File

@ -274,20 +274,34 @@ var etemplate2 = /** @class */ (function () {
* calls, eg. via et2_dialog.
*/
etemplate2.prototype.bind_unload = function () {
// Prompt user to save for dirty popups
if (window !== egw_topWindow() && !this.close_prompt) {
this.close_prompt = this._close_changed_prompt.bind(this);
window.addEventListener("beforeunload", this.close_prompt);
}
if (this._etemplate_exec_id) {
this.destroy_session = jQuery.proxy(function (ev) {
// need to use async === "keepalive" to run via beforeunload
egw.json("EGroupware\\Api\\Etemplate::ajax_destroy_session", [this._etemplate_exec_id], null, null, "keepalive").sendRequest();
}, this);
if (!window.onbeforeunload) {
window.onbeforeunload = this.destroy_session;
}
window.addEventListener("beforeunload", this.destroy_session);
}
};
etemplate2.prototype._close_changed_prompt = function (e) {
if (!this.isDirty()) {
return;
}
// Cancel the event
e.preventDefault(); // If you prevent default behavior in Mozilla Firefox prompt will always be shown
// Chrome requires returnValue to be set
e.returnValue = '';
};
/**
* Unbind our unload handler
*/
etemplate2.prototype.unbind_unload = function () {
window.removeEventListener("beforeunload", this.destroy_session);
window.removeEventListener("beforeunload", this.close_prompt);
if (window.onbeforeunload === this.destroy_session) {
window.onbeforeunload = null;
}

View File

@ -107,6 +107,7 @@ export class etemplate2
private resize_timeout: number | boolean;
private destroy_session: any;
private close_prompt: any;
private app_obj: EgwApp;
app: string;
@ -344,6 +345,12 @@ export class etemplate2
*/
bind_unload()
{
// Prompt user to save for dirty popups
if(window !== egw_topWindow() && !this.close_prompt)
{
this.close_prompt = this._close_changed_prompt.bind(this);
window.addEventListener("beforeunload", this.close_prompt);
}
if (this._etemplate_exec_id)
{
this.destroy_session = jQuery.proxy(function (ev)
@ -353,18 +360,31 @@ export class etemplate2
[this._etemplate_exec_id], null, null, "keepalive").sendRequest();
}, this);
if (!window.onbeforeunload)
{
window.onbeforeunload = this.destroy_session;
}
window.addEventListener("beforeunload", this.destroy_session);
}
}
private _close_changed_prompt(e : BeforeUnloadEvent)
{
if(!this.isDirty())
{
return;
}
// Cancel the event
e.preventDefault(); // If you prevent default behavior in Mozilla Firefox prompt will always be shown
// Chrome requires returnValue to be set
e.returnValue = '';
}
/**
* Unbind our unload handler
*/
unbind_unload()
{
window.removeEventListener("beforeunload", this.destroy_session);
window.removeEventListener("beforeunload", this.close_prompt);
if (window.onbeforeunload === this.destroy_session)
{
window.onbeforeunload = null;

View File

@ -386,9 +386,7 @@ var CalendarApp = /** @class */ (function (_super) {
//send Syncronus ajax request to the server to unlock the on close entry
//set onbeforeunload with json request to send request when the window gets close by X button
if (content.data.lock_token) {
window.onbeforeunload = function () {
this.egw.json('calendar.calendar_uiforms.ajax_unlock', [content.data.id, content.data.lock_token], null, true, "keepalive", null).sendRequest();
};
window.addEventListener("beforeunload", this._unlock.bind(this));
}
}
this.alarm_custom_date();
@ -788,6 +786,15 @@ var CalendarApp = /** @class */ (function (_super) {
sortable.sortable('disable');
}
};
/**
* Unlock the event before closing the popup
*
* @private
*/
CalendarApp.prototype._unlock = function () {
var content = this.et2.getArrayMgr('content');
this.egw.json('calendar.calendar_uiforms.ajax_unlock', [content.data.id, content.data.lock_token], null, this, "keepalive", null).sendRequest();
};
/**
* Bind scroll event
* When the user scrolls, we'll move enddate - startdate days

View File

@ -286,10 +286,7 @@ class CalendarApp extends EgwApp
//set onbeforeunload with json request to send request when the window gets close by X button
if (content.data.lock_token)
{
window.onbeforeunload = function () {
this.egw.json('calendar.calendar_uiforms.ajax_unlock',
[content.data.id, content.data.lock_token],null,true,"keepalive",null).sendRequest();
};
window.addEventListener("beforeunload", this._unlock.bind(this));
}
}
this.alarm_custom_date();
@ -758,6 +755,17 @@ class CalendarApp extends EgwApp
}
}
/**
* Unlock the event before closing the popup
*
* @private
*/
private _unlock () {
const content = this.et2.getArrayMgr('content');
this.egw.json('calendar.calendar_uiforms.ajax_unlock',
[content.data.id, content.data.lock_token],null,this,"keepalive",null).sendRequest();
}
/**
* Bind scroll event
* When the user scrolls, we'll move enddate - startdate days