diff --git a/datamodels/2.x/itop-portal-base/portal/public/js/bootstrap-portal-modal.js b/datamodels/2.x/itop-portal-base/portal/public/js/bootstrap-portal-modal.js index e2fc81d7e..86516d887 100644 --- a/datamodels/2.x/itop-portal-base/portal/public/js/bootstrap-portal-modal.js +++ b/datamodels/2.x/itop-portal-base/portal/public/js/bootstrap-portal-modal.js @@ -34,30 +34,57 @@ var CreatePortalModal = function (oOptions) true, { id: null, // ID of the created modal + attributes: {}, // HTML attributes base_modal: { - usage: 'clone', // Either 'clone' or 'replace' - selector: '#modal-for-all' // Selector of the modal element used to base this one on + usage: 'clone', // Either 'clone' or 'replace' + selector: '#modal-for-all' // Either a selector of the modal element used to base this one on or the modal element itself }, - content: '', // Either a string or an object containing the endpoint / data + content: undefined, // Either a string, an object containing the endpoint / data or undefined to keep base modal content as-is size: 'lg', // Either 'xs' / 'sm' / 'md' / 'lg' }, oOptions ); + // Compute modal selector + var oSelectorElem = null; + switch(typeof oOptions.base_modal.selector) + { + case 'string': + oSelectorElem = $(oOptions.base_modal.selector); + break; + + case 'object': + oSelectorElem = oOptions.base_modal.selector; + break; + + default: + if (window.console && window.console.warn) + { + console.warn('Could not open modal dialog as the select option was malformed: ', oOptions.content); + } + break; + } + // Get modal element by either var oModalElem = null; // - Create a new modal from template // Note : This could be better if we check for an existing modal first instead of always creating a new one if (oOptions.base_modal.usage === 'clone') { - oModalElem = $(oOptions.base_modal.selector).clone(); + oModalElem = oSelectorElem.clone(); oModalElem.attr('id', oOptions.id) .appendTo('body'); } // - Get an existing modal in the DOM else { - oModalElem = $(oOptions.base_modal.selector); + oModalElem = oSelectorElem; + } + + // Set attributes + for(var sProp in oOptions.attributes) + { + oModalElem.attr(sProp, oOptions.attributes[sProp]); } // Resize to small modal @@ -90,15 +117,21 @@ var CreatePortalModal = function (oOptions) ); break; + case 'undefined': + // Do nothing, we keep the content as-is + break; + default: - if (window.console) + if (window.console && window.console.warn) { - console.log('Could not open modal dialog as the content option was malformed: ', oOptions.content); + console.warn('Could not open modal dialog as the content option was malformed: ', oOptions.content); } } // Show modal oModalElem.modal('show'); + + return oModalElem; }; $(document).ready(function() 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 68bf632af..c2de91b0a 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 @@ -167,26 +167,16 @@ $(function() if(bRedirectionAjax) { // Creating a new modal - var oModalElem = $('#modal-for-all').clone(); - oModalElem.attr('id', '').appendTo('body'); - // Loading content - oModalElem.find('.modal-content').html($('#page_overlay .overlay_content').html()); - oModalElem.find('.modal-content').load(sUrl, { - // Passing formmanager data to the next page, just in case it needs it (eg. when applying stimulus) - formmanager_class: me.options.formmanager_class, - formmanager_data: JSON.stringify(me.options.formmanager_data) + CreatePortalModal({ + content: { + endpoint: sUrl, + data: { + // Passing form manager data to the next page, just in case it needs it (eg. when applying stimulus) + formmanager_class: me.options.formmanager_class, + formmanager_data: JSON.stringify(me.options.formmanager_data) + }, }, - function(oData, sStatus, oXHR) - { - if(sStatus === 'error') - { - // Hiding modal in case of error as the general AJAX error handler will display a message - oModalElem.modal('hide'); - } - } - ); - - oModalElem.modal('show'); + }); } else { diff --git a/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php b/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php index 01b8c0e47..454d38ac2 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php @@ -833,7 +833,7 @@ class ObjectFormManager extends FormManager if ($oField instanceof SelectObjectField) { // - Set if remote object can be accessed - if ($this->oContainer !== null && !$oAttDef->IsNull($oField->GetCurrentValue())) + if ($this->oContainer !== null && !$oAttDef->IsNull($oField->GetCurrentValue()) && !is_null($oField->GetSearch())) { $sRemoteObjectFieldClass = $oField->GetSearch()->GetClass(); $sRemoteObjectFieldId = $oField->GetCurrentValue(); diff --git a/datamodels/2.x/itop-portal-base/portal/templates/bricks/create/modal.html.twig b/datamodels/2.x/itop-portal-base/portal/templates/bricks/create/modal.html.twig index 8cde7d9e3..fe9cbbb31 100644 --- a/datamodels/2.x/itop-portal-base/portal/templates/bricks/create/modal.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/templates/bricks/create/modal.html.twig @@ -19,21 +19,21 @@ $('#{{ sLeafClassesListId }} a').off('click').on('click', function(oEvent){ oEvent.preventDefault(); + // Preparing target class url var sUrl = '{{ app['url_generator'].generate('p_object_create', {sObjectClass : '-sObjectClass-'})|raw }}'; - var oModalElem = $(this).closest('.modal'); - // Showing loader - oModalElem.find('.modal-content').html($('#page_overlay .overlay_content').html()); - // Preparing target class url - sUrl = sUrl.replace(/-sObjectClass-/, $(this).attr('data-target-class') ); - sUrl = AddParameterToUrl(sUrl, 'ar_token', '{{ ar_token }}'); - // Loading form - oModalElem.find('.modal-content').load(sUrl, function(oData, sStatus, oXHR){ - if(sStatus === 'error') - { - // Hiding modal in case of error as the general AJAX error handler will display a message - oModalElem.modal('hide'); - } - }); + sUrl = sUrl.replace(/-sObjectClass-/, $(this).attr('data-target-class') ); + sUrl = AddParameterToUrl(sUrl, 'ar_token', '{{ ar_token }}'); + + // Creating a new modal + CreatePortalModal({ + base_modal: { + usage: 'replace', + selector: $(this).closest('.modal'), + }, + content: { + endpoint: sUrl, + }, + }); }); }); diff --git a/datamodels/2.x/itop-portal-base/portal/templates/bricks/object/mode_search_regular.html.twig b/datamodels/2.x/itop-portal-base/portal/templates/bricks/object/mode_search_regular.html.twig index 414567b10..f5919406a 100644 --- a/datamodels/2.x/itop-portal-base/portal/templates/bricks/object/mode_search_regular.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/templates/bricks/object/mode_search_regular.html.twig @@ -142,23 +142,12 @@ // Prevents row selection oEvent.stopPropagation(); - // Note : This could be better if we check for an existing modal first instead of always creating a new one - var oModalElem = $('#modal-for-all').clone(); - oModalElem.attr('id', '').appendTo('body'); - // Loading content - oModalElem.find('.modal-content').html($('#page_overlay .overlay_content').html()); - oModalElem.find('.modal-content').load( - $(this).attr('href'), - {}, - function(sResponseText, sStatus, oXHR){ - // Hiding modal in case of error as the general AJAX error handler will display a message - if(sStatus === 'error') - { - oModalElem.modal('hide'); - } - } - ); - oModalElem.modal('show'); + // Creating a new modal + CreatePortalModal({ + content: { + endpoint: $(this).attr('href'), + }, + }); }); }, "drawCallback": function(settings){ diff --git a/sources/renderer/bootstrap/fieldrenderer/bslinkedsetfieldrenderer.class.inc.php b/sources/renderer/bootstrap/fieldrenderer/bslinkedsetfieldrenderer.class.inc.php index fa708c74d..b8cd6147b 100644 --- a/sources/renderer/bootstrap/fieldrenderer/bslinkedsetfieldrenderer.class.inc.php +++ b/sources/renderer/bootstrap/fieldrenderer/bslinkedsetfieldrenderer.class.inc.php @@ -123,7 +123,7 @@ EOF $sSelectionInputHtml = ($this->oField->GetReadOnly()) ? '' : ''; // - Output $oOutput->AddJs( -<<oField->GetGlobalId()}(); }); }; -EOF +JS ); // Additional features if in edition mode @@ -430,7 +419,7 @@ EOF $sAddButtonEndpoint = str_replace('-sMode-', 'from-attribute', $this->oField->GetSearchEndpoint()); // - Output $oOutput->AddJs( - <<oField->GetGlobalId()} = function() @@ -495,39 +484,34 @@ EOF $('#{$sTableId} tr[role="row"] > td input[data-target-object-id]').each(function(iIndex, oElem){ aObjectIdsToIgnore.push( $(oElem).attr('data-target-object-id') ); }); + // Creating a new modal - var oModalElem; + var oOptions = + { + content: { + endpoint: '{$sAddButtonEndpoint}', + data: { + sFormPath: '{$this->oField->GetFormPath()}', + sFieldId: '{$this->oField->GetId()}', + aObjectIdsToIgnore : aObjectIdsToIgnore + }, + }, + }; + if($('.modal[data-source-element="{$sButtonAddId}"]').length === 0) { - oModalElem = $('#modal-for-all').clone(); - oModalElem.attr('id', '').attr('data-source-element', '{$sButtonAddId}').appendTo('body'); + oOptions['attributes'] = {'data-source-element': '{$sButtonAddId}'}; } else { - oModalElem = $('.modal[data-source-element="{$sButtonAddId}"]').first(); + oOptions['base_modal'] = { + 'usage': 'replace', + 'selector': '.modal[data-source-element="{$sButtonAddId}"]:first' + }; } - // Resizing to small modal - oModalElem.find('.modal-dialog').removeClass('modal-sm').addClass('modal-lg'); - // Loading content - oModalElem.find('.modal-content').html($('#page_overlay .overlay_content').html()); - oModalElem.find('.modal-content').load( - '{$sAddButtonEndpoint}', - { - sFormPath: '{$this->oField->GetFormPath()}', - sFieldId: '{$this->oField->GetId()}', - aObjectIdsToIgnore : aObjectIdsToIgnore - }, - function(sResponseText, sStatus, oXHR){ - // Hiding modal in case of error as the general AJAX error handler will display a message - if(sStatus === 'error') - { - oModalElem.modal('hide'); - } - } - ); - oModalElem.modal('show'); + CreatePortalModal(oOptions); }); -EOF +JS ); } } diff --git a/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php b/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php index 3e0f7de04..e59457d1c 100644 --- a/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php +++ b/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php @@ -385,33 +385,24 @@ EOF $oOutput->AddHtml('
'); $oOutput->AddJs( -<<oField->GetFormPath()}', - sFieldId: '{$this->oField->GetId()}' + CreatePortalModal({ + attributes: { + 'data-source-element': '{$sHierarchicalButtonId}', }, - function(sResponseText, sStatus, oXHR){ - // Hiding modal in case of error as the general AJAX error handler will display a message - if(sStatus === 'error') - { - oModalElem.modal('hide'); - } - } - ); - oModalElem.modal('show'); + content: { + endpoint: '{$sEndpoint}', + data: { + sFormPath: '{$this->oField->GetFormPath()}', + sFieldId: '{$this->oField->GetId()}', + }, + }, + size: 'sm', + }); }); -EOF +JS ); } } @@ -429,43 +420,37 @@ EOF $oOutput->AddHtml('
'); $oOutput->AddJs( -<<oField->GetFormPath()}', + sFieldId: '{$this->oField->GetId()}', + formmanager_class: $(this).closest('.portal_form_handler').portal_form_handler('getOptions').formmanager_class, + formmanager_data: JSON.stringify($(this).closest('.portal_form_handler').portal_form_handler('getOptions').formmanager_data), + current_values: $(this).closest('.portal_form_handler').portal_form_handler('getCurrentValues') + }, + }, + }; + if($('.modal[data-source-element="{$sSearchButtonId}"]').length === 0) { - oModalElem = $('#modal-for-all').clone(); - oModalElem.attr('id', '').attr('data-source-element', '{$sSearchButtonId}').appendTo('body'); + oOptions['attributes'] = {'data-source-element': '{$sSearchButtonId}'}; } else { - oModalElem = $('.modal[data-source-element="{$sSearchButtonId}"]').first(); + oOptions['base_modal'] = { + 'usage': 'replace', + 'selector': '.modal[data-source-element="{$sSearchButtonId}"]:first' + }; } - // Resizing to small modal - oModalElem.find('.modal-dialog').removeClass('modal-sm').addClass('modal-lg'); - // Loading content - oModalElem.find('.modal-content').html($('#page_overlay .overlay_content').html()); - oModalElem.find('.modal-content').load( - '{$sEndpoint}', - { - sFormPath: '{$this->oField->GetFormPath()}', - sFieldId: '{$this->oField->GetId()}', - formmanager_class: $(this).closest('.portal_form_handler').portal_form_handler('getOptions').formmanager_class, - formmanager_data: JSON.stringify($(this).closest('.portal_form_handler').portal_form_handler('getOptions').formmanager_data), - current_values: $(this).closest('.portal_form_handler').portal_form_handler('getCurrentValues') - }, - function(sResponseText, sStatus, oXHR){ - // Hiding modal in case of error as the general AJAX error handler will display a message - if(sStatus === 'error') - { - oModalElem.modal('hide'); - } - } - ); - oModalElem.modal('show'); + CreatePortalModal(oOptions); }); -EOF +JS ); }