forked from extern/egroupware
Etemplate: Check dirty before closing, ask if there are changes
This commit is contained in:
parent
73515cd412
commit
52714f0a63
@ -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();
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user