Portal: Refactor creation of modal dialog through a common helper (CreatePortalModal(oOptions))

This commit is contained in:
Molkobain
2019-07-31 15:50:09 +02:00
parent 661ecc57c5
commit 66287757b3
7 changed files with 134 additions and 153 deletions

View File

@@ -34,30 +34,57 @@ var CreatePortalModal = function (oOptions)
true, true,
{ {
id: null, // ID of the created modal id: null, // ID of the created modal
attributes: {}, // HTML attributes
base_modal: { base_modal: {
usage: 'clone', // Either 'clone' or 'replace' usage: 'clone', // Either 'clone' or 'replace'
selector: '#modal-for-all' // Selector of the modal element used to base this one on 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' size: 'lg', // Either 'xs' / 'sm' / 'md' / 'lg'
}, },
oOptions 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 // Get modal element by either
var oModalElem = null; var oModalElem = null;
// - Create a new modal from template // - 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 // 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') if (oOptions.base_modal.usage === 'clone')
{ {
oModalElem = $(oOptions.base_modal.selector).clone(); oModalElem = oSelectorElem.clone();
oModalElem.attr('id', oOptions.id) oModalElem.attr('id', oOptions.id)
.appendTo('body'); .appendTo('body');
} }
// - Get an existing modal in the DOM // - Get an existing modal in the DOM
else 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 // Resize to small modal
@@ -90,15 +117,21 @@ var CreatePortalModal = function (oOptions)
); );
break; break;
case 'undefined':
// Do nothing, we keep the content as-is
break;
default: 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 // Show modal
oModalElem.modal('show'); oModalElem.modal('show');
return oModalElem;
}; };
$(document).ready(function() $(document).ready(function()

View File

@@ -167,26 +167,16 @@ $(function()
if(bRedirectionAjax) if(bRedirectionAjax)
{ {
// Creating a new modal // Creating a new modal
var oModalElem = $('#modal-for-all').clone(); CreatePortalModal({
oModalElem.attr('id', '').appendTo('body'); content: {
// Loading content endpoint: sUrl,
oModalElem.find('.modal-content').html($('#page_overlay .overlay_content').html()); data: {
oModalElem.find('.modal-content').load(sUrl, { // Passing form manager data to the next page, just in case it needs it (eg. when applying stimulus)
// Passing formmanager data to the next page, just in case it needs it (eg. when applying stimulus) formmanager_class: me.options.formmanager_class,
formmanager_class: me.options.formmanager_class, formmanager_data: JSON.stringify(me.options.formmanager_data)
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 else
{ {

View File

@@ -833,7 +833,7 @@ class ObjectFormManager extends FormManager
if ($oField instanceof SelectObjectField) if ($oField instanceof SelectObjectField)
{ {
// - Set if remote object can be accessed // - 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(); $sRemoteObjectFieldClass = $oField->GetSearch()->GetClass();
$sRemoteObjectFieldId = $oField->GetCurrentValue(); $sRemoteObjectFieldId = $oField->GetCurrentValue();

View File

@@ -19,21 +19,21 @@
$('#{{ sLeafClassesListId }} a').off('click').on('click', function(oEvent){ $('#{{ sLeafClassesListId }} a').off('click').on('click', function(oEvent){
oEvent.preventDefault(); oEvent.preventDefault();
// Preparing target class url
var sUrl = '{{ app['url_generator'].generate('p_object_create', {sObjectClass : '-sObjectClass-'})|raw }}'; var sUrl = '{{ app['url_generator'].generate('p_object_create', {sObjectClass : '-sObjectClass-'})|raw }}';
var oModalElem = $(this).closest('.modal'); sUrl = sUrl.replace(/-sObjectClass-/, $(this).attr('data-target-class') );
// Showing loader sUrl = AddParameterToUrl(sUrl, 'ar_token', '{{ ar_token }}');
oModalElem.find('.modal-content').html($('#page_overlay .overlay_content').html());
// Preparing target class url // Creating a new modal
sUrl = sUrl.replace(/-sObjectClass-/, $(this).attr('data-target-class') ); CreatePortalModal({
sUrl = AddParameterToUrl(sUrl, 'ar_token', '{{ ar_token }}'); base_modal: {
// Loading form usage: 'replace',
oModalElem.find('.modal-content').load(sUrl, function(oData, sStatus, oXHR){ selector: $(this).closest('.modal'),
if(sStatus === 'error') },
{ content: {
// Hiding modal in case of error as the general AJAX error handler will display a message endpoint: sUrl,
oModalElem.modal('hide'); },
} });
});
}); });
}); });
</script> </script>

View File

@@ -142,23 +142,12 @@
// Prevents row selection // Prevents row selection
oEvent.stopPropagation(); oEvent.stopPropagation();
// Note : This could be better if we check for an existing modal first instead of always creating a new one // Creating a new modal
var oModalElem = $('#modal-for-all').clone(); CreatePortalModal({
oModalElem.attr('id', '').appendTo('body'); content: {
// Loading content endpoint: $(this).attr('href'),
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');
}); });
}, },
"drawCallback": function(settings){ "drawCallback": function(settings){

View File

@@ -123,7 +123,7 @@ EOF
$sSelectionInputHtml = ($this->oField->GetReadOnly()) ? '' : '<span class="row_input"><input type="checkbox" name="' . $this->oField->GetGlobalId() . '" /></span>'; $sSelectionInputHtml = ($this->oField->GetReadOnly()) ? '' : '<span class="row_input"><input type="checkbox" name="' . $this->oField->GetGlobalId() . '" /></span>';
// - Output // - Output
$oOutput->AddJs( $oOutput->AddJs(
<<<EOF <<<JS
// Collapse handlers // Collapse handlers
// - Collapsing by default to optimize form space // - Collapsing by default to optimize form space
// It would be better to be able to construct the widget as collapsed, but in this case, datatables thinks the container is very small and therefore renders the table as if it was in microbox. // It would be better to be able to construct the widget as collapsed, but in this case, datatables thinks the container is very small and therefore renders the table as if it was in microbox.
@@ -239,22 +239,11 @@ EOF
oEvent.stopPropagation(); oEvent.stopPropagation();
// Note : This could be better if we check for an existing modal first instead of always creating a new one // 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(); CreatePortalModal({
oModalElem.attr('id', '').appendTo('body'); content: {
// Loading content endpoint: $(this).attr('href'),
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');
}); });
}, },
}); });
@@ -310,7 +299,7 @@ EOF
updateRemoveButtonState_{$this->oField->GetGlobalId()}(); updateRemoveButtonState_{$this->oField->GetGlobalId()}();
}); });
}; };
EOF JS
); );
// Additional features if in edition mode // Additional features if in edition mode
@@ -430,7 +419,7 @@ EOF
$sAddButtonEndpoint = str_replace('-sMode-', 'from-attribute', $this->oField->GetSearchEndpoint()); $sAddButtonEndpoint = str_replace('-sMode-', 'from-attribute', $this->oField->GetSearchEndpoint());
// - Output // - Output
$oOutput->AddJs( $oOutput->AddJs(
<<<EOF <<<JS
// Handles items selection/deselection // Handles items selection/deselection
// - Remove button state handler // - Remove button state handler
var updateRemoveButtonState_{$this->oField->GetGlobalId()} = function() var updateRemoveButtonState_{$this->oField->GetGlobalId()} = function()
@@ -495,39 +484,34 @@ EOF
$('#{$sTableId} tr[role="row"] > td input[data-target-object-id]').each(function(iIndex, oElem){ $('#{$sTableId} tr[role="row"] > td input[data-target-object-id]').each(function(iIndex, oElem){
aObjectIdsToIgnore.push( $(oElem).attr('data-target-object-id') ); aObjectIdsToIgnore.push( $(oElem).attr('data-target-object-id') );
}); });
// Creating a new modal // 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) if($('.modal[data-source-element="{$sButtonAddId}"]').length === 0)
{ {
oModalElem = $('#modal-for-all').clone(); oOptions['attributes'] = {'data-source-element': '{$sButtonAddId}'};
oModalElem.attr('id', '').attr('data-source-element', '{$sButtonAddId}').appendTo('body');
} }
else else
{ {
oModalElem = $('.modal[data-source-element="{$sButtonAddId}"]').first(); oOptions['base_modal'] = {
'usage': 'replace',
'selector': '.modal[data-source-element="{$sButtonAddId}"]:first'
};
} }
// Resizing to small modal CreatePortalModal(oOptions);
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');
}); });
EOF JS
); );
} }
} }

View File

@@ -385,33 +385,24 @@ EOF
$oOutput->AddHtml('<div class="input-group-addon" id="' . $sHierarchicalButtonId . '"><span class="fas fa-sitemap"></span></div>'); $oOutput->AddHtml('<div class="input-group-addon" id="' . $sHierarchicalButtonId . '"><span class="fas fa-sitemap"></span></div>');
$oOutput->AddJs( $oOutput->AddJs(
<<<EOF <<<JS
$('#{$sHierarchicalButtonId}').off('click').on('click', function(){ $('#{$sHierarchicalButtonId}').off('click').on('click', function(){
// Creating a new modal // Creating a new modal
// Note : This could be better if we check for an existing modal first instead of always creating a new one CreatePortalModal({
var oModalElem = $('#modal-for-all').clone(); attributes: {
oModalElem.attr('id', '').attr('data-source-element', '{$sHierarchicalButtonId}').appendTo('body'); 'data-source-element': '{$sHierarchicalButtonId}',
// Resizing to small modal
oModalElem.find('.modal-dialog').removeClass('modal-lg').addClass('modal-sm');
// 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()}'
}, },
function(sResponseText, sStatus, oXHR){ content: {
// Hiding modal in case of error as the general AJAX error handler will display a message endpoint: '{$sEndpoint}',
if(sStatus === 'error') data: {
{ sFormPath: '{$this->oField->GetFormPath()}',
oModalElem.modal('hide'); sFieldId: '{$this->oField->GetId()}',
} },
} },
); size: 'sm',
oModalElem.modal('show'); });
}); });
EOF JS
); );
} }
} }
@@ -429,43 +420,37 @@ EOF
$oOutput->AddHtml('<div class="input-group-addon" id="' . $sSearchButtonId . '"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></div>'); $oOutput->AddHtml('<div class="input-group-addon" id="' . $sSearchButtonId . '"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></div>');
$oOutput->AddJs( $oOutput->AddJs(
<<<EOF <<<JS
$('#{$sSearchButtonId}').off('click').on('click', function(){ $('#{$sSearchButtonId}').off('click').on('click', function(){
// Creating a new modal // Creating a new modal
var oModalElem; var oOptions =
{
content: {
endpoint: '{$sEndpoint}',
data: {
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')
},
},
};
if($('.modal[data-source-element="{$sSearchButtonId}"]').length === 0) if($('.modal[data-source-element="{$sSearchButtonId}"]').length === 0)
{ {
oModalElem = $('#modal-for-all').clone(); oOptions['attributes'] = {'data-source-element': '{$sSearchButtonId}'};
oModalElem.attr('id', '').attr('data-source-element', '{$sSearchButtonId}').appendTo('body');
} }
else else
{ {
oModalElem = $('.modal[data-source-element="{$sSearchButtonId}"]').first(); oOptions['base_modal'] = {
'usage': 'replace',
'selector': '.modal[data-source-element="{$sSearchButtonId}"]:first'
};
} }
// Resizing to small modal CreatePortalModal(oOptions);
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');
}); });
EOF JS
); );
} }