mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 14:41:29 +01:00
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);
|
_super.prototype.destroy.call(this);
|
||||||
this._labelContainer = null;
|
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
|
* Load the validation errors from the server
|
||||||
*
|
*
|
||||||
@ -212,7 +220,25 @@ var et2_inputWidget = /** @class */ (function (_super) {
|
|||||||
return this._oldValue;
|
return this._oldValue;
|
||||||
};
|
};
|
||||||
et2_inputWidget.prototype.isDirty = function () {
|
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 () {
|
et2_inputWidget.prototype.resetDirty = function () {
|
||||||
this._oldValue = this.getValue();
|
this._oldValue = this.getValue();
|
||||||
|
@ -96,6 +96,18 @@ export class et2_inputWidget extends et2_valueWidget implements et2_IInput, et2_
|
|||||||
this._labelContainer = null;
|
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
|
* Load the validation errors from the server
|
||||||
*
|
*
|
||||||
@ -300,7 +312,27 @@ export class et2_inputWidget extends et2_valueWidget implements et2_IInput, et2_
|
|||||||
|
|
||||||
isDirty()
|
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()
|
resetDirty()
|
||||||
|
@ -316,10 +316,10 @@ var et2_customfields_list = /** @class */ (function (_super) {
|
|||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
et2_customfields_list.prototype.isDirty = function () {
|
et2_customfields_list.prototype.isDirty = function () {
|
||||||
var dirty = true;
|
var dirty = false;
|
||||||
for (var field_name in this.widgets) {
|
for (var field_name in this.widgets) {
|
||||||
if (this.widgets[field_name].isDirty) {
|
if (this.widgets[field_name].isDirty) {
|
||||||
dirty = dirty && this.widgets[field_name].isDirty();
|
dirty = dirty || this.widgets[field_name].isDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dirty;
|
return dirty;
|
||||||
|
@ -430,12 +430,12 @@ export class et2_customfields_list extends et2_valueWidget implements et2_IDetac
|
|||||||
|
|
||||||
isDirty( )
|
isDirty( )
|
||||||
{
|
{
|
||||||
let dirty = true;
|
let dirty = false;
|
||||||
for(let field_name in this.widgets)
|
for(let field_name in this.widgets)
|
||||||
{
|
{
|
||||||
if(this.widgets[field_name].isDirty)
|
if(this.widgets[field_name].isDirty)
|
||||||
{
|
{
|
||||||
dirty = dirty && this.widgets[field_name].isDirty();
|
dirty = dirty || this.widgets[field_name].isDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dirty;
|
return dirty;
|
||||||
|
@ -344,8 +344,8 @@ var et2_selectbox = /** @class */ (function (_super) {
|
|||||||
this.setDOMNode(node[0]);
|
this.setDOMNode(node[0]);
|
||||||
};
|
};
|
||||||
et2_selectbox.prototype.doLoadingFinished = function () {
|
et2_selectbox.prototype.doLoadingFinished = function () {
|
||||||
_super.prototype.doLoadingFinished.call(this);
|
|
||||||
this.set_tags(this.options.tags, this.options.width);
|
this.set_tags(this.options.tags, this.options.width);
|
||||||
|
_super.prototype.doLoadingFinished.call(this);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
et2_selectbox.prototype.loadFromXML = function (_node) {
|
et2_selectbox.prototype.loadFromXML = function (_node) {
|
||||||
@ -1366,6 +1366,12 @@ var et2_selectbox_ro = /** @class */ (function (_super) {
|
|||||||
et2_selectbox_ro.prototype.getValue = function () {
|
et2_selectbox_ro.prototype.getValue = function () {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Readonly selectbox can't be dirty
|
||||||
|
*/
|
||||||
|
et2_selectbox_ro.prototype.isDirty = function () {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Functions for et2_IDetachedDOM
|
* Functions for et2_IDetachedDOM
|
||||||
*/
|
*/
|
||||||
|
@ -484,10 +484,10 @@ export class et2_selectbox extends et2_inputWidget
|
|||||||
|
|
||||||
doLoadingFinished()
|
doLoadingFinished()
|
||||||
{
|
{
|
||||||
super.doLoadingFinished();
|
|
||||||
|
|
||||||
this.set_tags(this.options.tags, this.options.width);
|
this.set_tags(this.options.tags, this.options.width);
|
||||||
|
|
||||||
|
super.doLoadingFinished();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1679,6 +1679,14 @@ export class et2_selectbox_ro extends et2_selectbox implements et2_IDetachedDOM
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Readonly selectbox can't be dirty
|
||||||
|
*/
|
||||||
|
isDirty()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions for et2_IDetachedDOM
|
* Functions for et2_IDetachedDOM
|
||||||
*/
|
*/
|
||||||
|
@ -218,6 +218,7 @@ var et2_tabbox = /** @class */ (function (_super) {
|
|||||||
}
|
}
|
||||||
jQuery.when.apply(jQuery, promises).then(function () {
|
jQuery.when.apply(jQuery, promises).then(function () {
|
||||||
tab_deferred.resolve();
|
tab_deferred.resolve();
|
||||||
|
tabs.resetDirty();
|
||||||
});
|
});
|
||||||
}, 0);
|
}, 0);
|
||||||
return tab_deferred.promise();
|
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() {
|
jQuery.when.apply(jQuery,promises).then(function() {
|
||||||
tab_deferred.resolve();
|
tab_deferred.resolve();
|
||||||
|
tabs.resetDirty();
|
||||||
});
|
});
|
||||||
},0);
|
},0);
|
||||||
|
|
||||||
|
@ -279,6 +279,7 @@ var et2_taglist = /** @class */ (function (_super) {
|
|||||||
this.div.on('blur', 'input', function () {
|
this.div.on('blur', 'input', function () {
|
||||||
jQuery('.ms-ctn-focus', widget.div).removeClass('ms-ctn-focus');
|
jQuery('.ms-ctn-focus', widget.div).removeClass('ms-ctn-focus');
|
||||||
});
|
});
|
||||||
|
this.resetDirty();
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
@ -430,6 +430,8 @@ export class et2_taglist extends et2_selectbox implements et2_IResizeable
|
|||||||
this.div.on('blur', 'input', function() {
|
this.div.on('blur', 'input', function() {
|
||||||
jQuery('.ms-ctn-focus', widget.div).removeClass('ms-ctn-focus');
|
jQuery('.ms-ctn-focus', widget.div).removeClass('ms-ctn-focus');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.resetDirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,20 +274,34 @@ var etemplate2 = /** @class */ (function () {
|
|||||||
* calls, eg. via et2_dialog.
|
* calls, eg. via et2_dialog.
|
||||||
*/
|
*/
|
||||||
etemplate2.prototype.bind_unload = function () {
|
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) {
|
if (this._etemplate_exec_id) {
|
||||||
this.destroy_session = jQuery.proxy(function (ev) {
|
this.destroy_session = jQuery.proxy(function (ev) {
|
||||||
// need to use async === "keepalive" to run via beforeunload
|
// 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();
|
egw.json("EGroupware\\Api\\Etemplate::ajax_destroy_session", [this._etemplate_exec_id], null, null, "keepalive").sendRequest();
|
||||||
}, this);
|
}, this);
|
||||||
if (!window.onbeforeunload) {
|
window.addEventListener("beforeunload", this.destroy_session);
|
||||||
window.onbeforeunload = 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
|
* Unbind our unload handler
|
||||||
*/
|
*/
|
||||||
etemplate2.prototype.unbind_unload = function () {
|
etemplate2.prototype.unbind_unload = function () {
|
||||||
|
window.removeEventListener("beforeunload", this.destroy_session);
|
||||||
|
window.removeEventListener("beforeunload", this.close_prompt);
|
||||||
if (window.onbeforeunload === this.destroy_session) {
|
if (window.onbeforeunload === this.destroy_session) {
|
||||||
window.onbeforeunload = null;
|
window.onbeforeunload = null;
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,7 @@ export class etemplate2
|
|||||||
|
|
||||||
private resize_timeout: number | boolean;
|
private resize_timeout: number | boolean;
|
||||||
private destroy_session: any;
|
private destroy_session: any;
|
||||||
|
private close_prompt: any;
|
||||||
private app_obj: EgwApp;
|
private app_obj: EgwApp;
|
||||||
app: string;
|
app: string;
|
||||||
|
|
||||||
@ -344,6 +345,12 @@ export class etemplate2
|
|||||||
*/
|
*/
|
||||||
bind_unload()
|
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)
|
if (this._etemplate_exec_id)
|
||||||
{
|
{
|
||||||
this.destroy_session = jQuery.proxy(function (ev)
|
this.destroy_session = jQuery.proxy(function (ev)
|
||||||
@ -353,11 +360,22 @@ export class etemplate2
|
|||||||
[this._etemplate_exec_id], null, null, "keepalive").sendRequest();
|
[this._etemplate_exec_id], null, null, "keepalive").sendRequest();
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
if (!window.onbeforeunload)
|
window.addEventListener("beforeunload", this.destroy_session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _close_changed_prompt(e : BeforeUnloadEvent)
|
||||||
{
|
{
|
||||||
window.onbeforeunload = this.destroy_session;
|
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 = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -365,6 +383,8 @@ export class etemplate2
|
|||||||
*/
|
*/
|
||||||
unbind_unload()
|
unbind_unload()
|
||||||
{
|
{
|
||||||
|
window.removeEventListener("beforeunload", this.destroy_session);
|
||||||
|
window.removeEventListener("beforeunload", this.close_prompt);
|
||||||
if (window.onbeforeunload === this.destroy_session)
|
if (window.onbeforeunload === this.destroy_session)
|
||||||
{
|
{
|
||||||
window.onbeforeunload = null;
|
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
|
//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
|
//set onbeforeunload with json request to send request when the window gets close by X button
|
||||||
if (content.data.lock_token) {
|
if (content.data.lock_token) {
|
||||||
window.onbeforeunload = function () {
|
window.addEventListener("beforeunload", this._unlock.bind(this));
|
||||||
this.egw.json('calendar.calendar_uiforms.ajax_unlock', [content.data.id, content.data.lock_token], null, true, "keepalive", null).sendRequest();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.alarm_custom_date();
|
this.alarm_custom_date();
|
||||||
@ -788,6 +786,15 @@ var CalendarApp = /** @class */ (function (_super) {
|
|||||||
sortable.sortable('disable');
|
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
|
* Bind scroll event
|
||||||
* When the user scrolls, we'll move enddate - startdate days
|
* 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
|
//set onbeforeunload with json request to send request when the window gets close by X button
|
||||||
if (content.data.lock_token)
|
if (content.data.lock_token)
|
||||||
{
|
{
|
||||||
window.onbeforeunload = function () {
|
window.addEventListener("beforeunload", this._unlock.bind(this));
|
||||||
this.egw.json('calendar.calendar_uiforms.ajax_unlock',
|
|
||||||
[content.data.id, content.data.lock_token],null,true,"keepalive",null).sendRequest();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.alarm_custom_date();
|
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
|
* Bind scroll event
|
||||||
* When the user scrolls, we'll move enddate - startdate days
|
* When the user scrolls, we'll move enddate - startdate days
|
||||||
|
Loading…
Reference in New Issue
Block a user