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
);
}