diff --git a/datamodels/2.x/itop-portal-base/cs.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/cs.dict.itop-portal-base.php index 6cb4d4fd8d..c33b72e7b6 100644 --- a/datamodels/2.x/itop-portal-base/cs.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/cs.dict.itop-portal-base.php @@ -68,6 +68,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'Portal:File:DisplayInfo' => '%1$s', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Open / Download', 'Portal:Calendar-FirstDayOfWeek' => 'cs', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/da.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/da.dict.itop-portal-base.php index 50b69e598e..ade9a5102b 100644 --- a/datamodels/2.x/itop-portal-base/da.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/da.dict.itop-portal-base.php @@ -65,6 +65,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'Portal:File:DisplayInfo' => '%1$s~~', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Open / Download~~', 'Portal:Calendar-FirstDayOfWeek' => 'da', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/de.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/de.dict.itop-portal-base.php index 0299e68bdb..dfa3d7f274 100644 --- a/datamodels/2.x/itop-portal-base/de.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/de.dict.itop-portal-base.php @@ -65,6 +65,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'Portal:File:DisplayInfo' => '%1$s', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Öffnen / Download', 'Portal:Calendar-FirstDayOfWeek' => 'de', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/en.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/en.dict.itop-portal-base.php index bbf90ef2bc..efaf74fbb0 100644 --- a/datamodels/2.x/itop-portal-base/en.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/en.dict.itop-portal-base.php @@ -66,6 +66,7 @@ Dict::Add('EN US', 'English', 'English', array( 'Portal:File:DisplayInfo' => '%1$s', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Open / Download', 'Portal:Calendar-FirstDayOfWeek' => 'en-us', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/es_cr.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/es_cr.dict.itop-portal-base.php index 972443949b..8008b8344f 100644 --- a/datamodels/2.x/itop-portal-base/es_cr.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/es_cr.dict.itop-portal-base.php @@ -64,6 +64,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array( 'Portal:File:DisplayInfo' => '%1$s', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Abierto / Download', 'Portal:Calendar-FirstDayOfWeek' => 'es', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/fr.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/fr.dict.itop-portal-base.php index eece26d890..2ec988a54c 100644 --- a/datamodels/2.x/itop-portal-base/fr.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/fr.dict.itop-portal-base.php @@ -64,6 +64,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Portal:File:DisplayInfo' => '%1$s', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Ouvrir / Télécharger', 'Portal:Calendar-FirstDayOfWeek' => 'fr', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Voulez-vous quitter ce formulaire ? Les données saisies seront perdues', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/hu.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/hu.dict.itop-portal-base.php index 611d2ee522..89a521ecdf 100644 --- a/datamodels/2.x/itop-portal-base/hu.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/hu.dict.itop-portal-base.php @@ -65,6 +65,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array( 'Portal:File:DisplayInfo' => '%1$s~~', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Open / Download~~', 'Portal:Calendar-FirstDayOfWeek' => 'hu', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/it.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/it.dict.itop-portal-base.php index 655d54bf7b..81d8c44e39 100644 --- a/datamodels/2.x/itop-portal-base/it.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/it.dict.itop-portal-base.php @@ -65,6 +65,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array( 'Portal:File:DisplayInfo' => '%1$s~~', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Open / Download~~', 'Portal:Calendar-FirstDayOfWeek' => 'it', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/ja.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/ja.dict.itop-portal-base.php index 4af075286b..f2645fabe7 100644 --- a/datamodels/2.x/itop-portal-base/ja.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/ja.dict.itop-portal-base.php @@ -65,6 +65,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Portal:File:DisplayInfo' => '%1$s~~', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Open / Download~~', 'Portal:Calendar-FirstDayOfWeek' => 'ja', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/nl.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/nl.dict.itop-portal-base.php index 85086b6000..ff41fb0c91 100644 --- a/datamodels/2.x/itop-portal-base/nl.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/nl.dict.itop-portal-base.php @@ -65,6 +65,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array( 'Portal:File:DisplayInfo' => '%1$s', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Open / Download', 'Portal:Calendar-FirstDayOfWeek' => 'nl', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field.js b/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field.js index 3749b9f4cb..96dca4518d 100644 --- a/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field.js +++ b/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field.js @@ -1,3 +1,23 @@ +/* + * + * * Copyright (C) 2013-2019 Combodo SARL + * * + * * This file is part of iTop. + * * + * * iTop is free software; you can redistribute it and/or modify + * * it under the terms of the GNU Affero General Public License as published by + * * the Free Software Foundation, either version 3 of the License, or + * * (at your option) any later version. + * * + * * iTop is distributed in the hope that it will be useful, + * * but WITHOUT ANY WARRANTY; without even the implied warranty of + * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * * GNU Affero General Public License for more details. + * * + * * You should have received a copy of the GNU Affero General Public License + * + */ + //iTop Portal Form field ; $(function() diff --git a/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field_html.js b/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field_html.js index 0404cf63e6..ec729b3111 100644 --- a/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field_html.js +++ b/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field_html.js @@ -1,3 +1,23 @@ +/* + * + * * Copyright (C) 2013-2019 Combodo SARL + * * + * * This file is part of iTop. + * * + * * iTop is free software; you can redistribute it and/or modify + * * it under the terms of the GNU Affero General Public License as published by + * * the Free Software Foundation, either version 3 of the License, or + * * (at your option) any later version. + * * + * * iTop is distributed in the hope that it will be useful, + * * but WITHOUT ANY WARRANTY; without even the implied warranty of + * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * * GNU Affero General Public License for more details. + * * + * * You should have received a copy of the GNU Affero General Public License + * + */ + //iTop Portal Form field HTML //Used for field containing html data such as rich editors, html blocks, ... ; diff --git a/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field_set.js b/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field_set.js index fd2aad7d4e..26114d5b66 100644 --- a/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field_set.js +++ b/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_field_set.js @@ -1,3 +1,23 @@ +/* + * + * * Copyright (C) 2013-2019 Combodo SARL + * * + * * This file is part of iTop. + * * + * * iTop is free software; you can redistribute it and/or modify + * * it under the terms of the GNU Affero General Public License as published by + * * the Free Software Foundation, either version 3 of the License, or + * * (at your option) any later version. + * * + * * iTop is distributed in the hope that it will be useful, + * * but WITHOUT ANY WARRANTY; without even the implied warranty of + * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * * GNU Affero General Public License for more details. + * * + * * You should have received a copy of the GNU Affero General Public License + * + */ + //iTop Portal Form field Set //Used for field containing tagset ... ; diff --git a/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_handler.js b/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_handler.js index ba4a3ed351..281ebda4a1 100644 --- a/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_handler.js +++ b/datamodels/2.x/itop-portal-base/portal/public/js/portal_form_handler.js @@ -63,6 +63,13 @@ $(function() { this._super( key, value ); }, + // - Callback when some fields have been touched + _onFieldsTouched: function(oEvent) + { + this._super(oEvent); + $('body').trigger('register_blocker.portal.itop', {'sBlockerId': this.element.attr('id'), 'sTargetElemSelector': '#' + this.element.closest('.modal').attr('id'), 'oTargetElemSelector': '#' + this.element.closest('.modal').attr('id'), 'sEventName': 'hide.bs.modal'}); + $('body').trigger('register_blocker.portal.itop', {'sBlockerId': this.element.attr('id'), 'sTargetElemSelector': 'document', 'oTargetElemSelector': document, 'sEventName': 'beforeunload'}); + }, // Overload from parent class _onSubmitClick: function(oEvent) { @@ -153,6 +160,9 @@ $(function() // If everything is okay, we close the form and reload it. if(oValidation.valid) { + + $('body').trigger('unregister_blocker.portal.itop', {'sBlockerId': me.element.attr('id')}); + if(me.options.is_modal) { me.element.closest('.modal').modal('hide'); @@ -248,6 +258,7 @@ $(function() if(me.options.field_set.field_set('option', 'touched_fields').length > 0) { me._disableFormBeforeLoading(); + $('body').trigger('unregister_blocker.portal.itop', {'sBlockerId': me.element.attr('id')}); $.post( me.options.endpoint, { diff --git a/datamodels/2.x/itop-portal-base/portal/public/js/portal_leave_handler.js b/datamodels/2.x/itop-portal-base/portal/public/js/portal_leave_handler.js new file mode 100644 index 0000000000..f372c7ee9e --- /dev/null +++ b/datamodels/2.x/itop-portal-base/portal/public/js/portal_leave_handler.js @@ -0,0 +1,124 @@ +/* + * + * * Copyright (C) 2013-2019 Combodo SARL + * * + * * This file is part of iTop. + * * + * * iTop is free software; you can redistribute it and/or modify + * * it under the terms of the GNU Affero General Public License as published by + * * the Free Software Foundation, either version 3 of the License, or + * * (at your option) any later version. + * * + * * iTop is distributed in the hope that it will be useful, + * * but WITHOUT ANY WARRANTY; without even the implied warranty of + * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * * GNU Affero General Public License for more details. + * * + * * You should have received a copy of the GNU Affero General Public License + * + */ + +; +$(function() +{ + // the widget definition, where 'itop' is the namespace, + // 'portal_leave_handler' the widget name + $.widget( 'itop.portal_leave_handler', + { + // default options + options: + { + 'message': 'allo la', + }, + events: ['hide.bs.modal', 'beforeunload'], + //[event] + registered_blockers: {}, + // {id : {target : 'event1', target : 'event2'}} + + // the constructor + _create: function() + { + var me =this; + this.element + .addClass('portal_leave_handler'); + + this.element.on('register_blocker.portal.itop', function(oEvent, oData){ + me._onRegisterBlocker(oData.sBlockerId, oData.sTargetElemSelector, oData.oTargetElemSelector, oData.sEventName); + }); + this.element.on('unregister_blocker.portal.itop', function(oEvent, oData){ + me._onUnregisterBlocker(oData.sBlockerId); + }); + + this.element.on('hide.bs.modal', function(oEvent) {return me._onLeaveHandler(oEvent);}); + window.addEventListener('beforeunload', function(oEvent) {return me._onLeaveHandler(oEvent);}); + + this._super(); + }, + _onRegisterBlocker: function(sBlockerId, sTargetElemSelector, oTargetElemSelector, sEventName) + { + var aRegisteredBlock = {}; + aRegisteredBlock[sTargetElemSelector] = {'eventName': sEventName, 'selector': oTargetElemSelector}; + $.extend( + aRegisteredBlock, + this.registered_blockers[sBlockerId] + ); + this.registered_blockers[sBlockerId] = aRegisteredBlock; + }, + _onUnregisterBlocker: function(sBlockerId) + { + delete this.registered_blockers[sBlockerId]; + }, + _onLeaveHandler: function(oEvent) + { + var me = this; + for(var aRegisteredBlocker in me.registered_blockers) + { + for(var sBlockerTarget in me.registered_blockers[aRegisteredBlocker]) + { + if($(me.registered_blockers[aRegisteredBlocker][sBlockerTarget]['selector'])[0] === oEvent.target && me.registered_blockers[aRegisteredBlocker][sBlockerTarget]['eventName'].split('.')[0] === oEvent.type) + { + if(oEvent.type === 'beforeunload') + { + oEvent.returnValue = me.options.message; + return; + } + else + { + var $bReturnValue = confirm(me.options.message); + if ($bReturnValue) + { + $('body').trigger('unregister_blocker.portal.itop', {'sBlockerId': aRegisteredBlocker}); + } + return $bReturnValue; + } + } + } + } + }, + // events bound via _bind are removed automatically + // revert other modifications here + _destroy: function() + { + this.element + .removeClass('portal_leave_handler'); + + this._super(); + }, + // _setOptions is called with a hash of all options that are changing + // always refresh when changing options + _setOptions: function() + { + this._superApply(arguments); + }, + // _setOption is called for each individual option that is changing + _setOption: function( key, value ) + { + this._super( key, value ); + }, + showOptions: function() + { + return this.options; + } + }); +}); + diff --git a/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig b/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig index a73d5d1075..777bfa8f15 100644 --- a/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/templates/layout.html.twig @@ -123,6 +123,9 @@ {# Typeahead files for autocomplete #} + + + {# Selectize for sets #} @@ -489,6 +492,9 @@ ShowErrorDialog(); } }); + + // Initialize confirmation message handler when a form with touched fields is closed + $('body').portal_leave_handler({'message': '{{ 'Portal:Form:Close:Warning'|dict_s }}'}); {% endblock %} }); diff --git a/datamodels/2.x/itop-portal-base/pt_br.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/pt_br.dict.itop-portal-base.php index 1afd25094d..5e4a8f7301 100644 --- a/datamodels/2.x/itop-portal-base/pt_br.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/pt_br.dict.itop-portal-base.php @@ -64,6 +64,7 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array( 'Portal:File:DisplayInfo' => '%1$s', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Abrir / Download', 'Portal:Calendar-FirstDayOfWeek' => 'pt-br', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/ru.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/ru.dict.itop-portal-base.php index 12cde67c9d..3d35f7258f 100755 --- a/datamodels/2.x/itop-portal-base/ru.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/ru.dict.itop-portal-base.php @@ -53,6 +53,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', array( 'Portal:File:DisplayInfo' => '%1$s~~', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Открыть / Скачать', 'Portal:Calendar-FirstDayOfWeek' => 'ru', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/sk.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/sk.dict.itop-portal-base.php index 92e16ac60f..53aa286254 100644 --- a/datamodels/2.x/itop-portal-base/sk.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/sk.dict.itop-portal-base.php @@ -65,6 +65,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'Portal:File:DisplayInfo' => '%1$s~~', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Open / Download~~', 'Portal:Calendar-FirstDayOfWeek' => 'en-us~~', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/tr.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/tr.dict.itop-portal-base.php index a8c5b421e8..a2fcc576be 100644 --- a/datamodels/2.x/itop-portal-base/tr.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/tr.dict.itop-portal-base.php @@ -65,6 +65,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array( 'Portal:File:DisplayInfo' => '%1$s~~', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Open / Download~~', 'Portal:Calendar-FirstDayOfWeek' => 'tr', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/datamodels/2.x/itop-portal-base/zh_cn.dict.itop-portal-base.php b/datamodels/2.x/itop-portal-base/zh_cn.dict.itop-portal-base.php index 447e64db76..f3ec050c6b 100644 --- a/datamodels/2.x/itop-portal-base/zh_cn.dict.itop-portal-base.php +++ b/datamodels/2.x/itop-portal-base/zh_cn.dict.itop-portal-base.php @@ -65,6 +65,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array( 'Portal:File:DisplayInfo' => '%1$s', 'Portal:File:DisplayInfo+' => '%1$s (%2$s) Open / Download', 'Portal:Calendar-FirstDayOfWeek' => 'en-us~~', //work with moment.js locales + 'Portal:Form:Close:Warning' => 'Do you want to leave this form ? Data entered may be lost~~', )); // UserProfile brick diff --git a/sources/renderer/bootstrap/fieldrenderer/bssimplefieldrenderer.class.inc.php b/sources/renderer/bootstrap/fieldrenderer/bssimplefieldrenderer.class.inc.php index f68b727d91..d9b4657493 100644 --- a/sources/renderer/bootstrap/fieldrenderer/bssimplefieldrenderer.class.inc.php +++ b/sources/renderer/bootstrap/fieldrenderer/bssimplefieldrenderer.class.inc.php @@ -168,7 +168,9 @@ EOF $oOutput->AddJs( <<oField->GetGlobalId()}').addClass('htmlEditor'); - $('#{$this->oField->GetGlobalId()}').ckeditor(function(){}, {language: '$sEditorLanguage', contentsLanguage: '$sEditorLanguage', extraPlugins: 'codesnippet'}); + $('#{$this->oField->GetGlobalId()}').ckeditor(function(){}, {language: '$sEditorLanguage', contentsLanguage: '$sEditorLanguage', extraPlugins: 'codesnippet'}).editor.on("change", function(){ + $('#{$this->oField->GetGlobalId()}').trigger("change"); + }); EOF ); if (($this->oField->GetObject() !== null) && ($this->oField->GetTransactionId() !== null))