mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-25 11:38:44 +02:00
N°5976 - Add modal creation for linksets displayed with tagset-like widget (#469)
This commit is contained in:
@@ -3113,10 +3113,22 @@ EOF
|
||||
$sClassIconUrl = MetaModel::GetClassIcon($sClass, false);
|
||||
$oPanel = PanelUIBlockFactory::MakeForClass($sClass, $sTitle)
|
||||
->SetIcon($sClassIconUrl);
|
||||
$oPanel->AddMainBlock(self::DisplayFormBlockSelectClassToCreate($sClass, $sClassLabel, $oAppContext, $aPossibleClasses, $aHiddenFields));
|
||||
|
||||
$oP->AddSubBlock($oPanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
* @param string $sClassLabel
|
||||
* @param array $aPossibleClasses
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Form\Form
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public static function DisplayFormBlockSelectClassToCreate( string $sClass, string $sClassLabel, ApplicationContext $oAppContext, array $aPossibleClasses, array $aHiddenFields): Form
|
||||
{
|
||||
$oClassForm = FormUIBlockFactory::MakeStandard();
|
||||
$oPanel->AddMainBlock($oClassForm);
|
||||
|
||||
$oClassForm->AddHtml($oAppContext->GetForForm())
|
||||
->AddSubBlock(InputUIBlockFactory::MakeForHidden('checkSubclass', '0'))
|
||||
@@ -3149,10 +3161,8 @@ EOF
|
||||
}
|
||||
|
||||
$oClassForm->AddSubBlock(self::DisplayBlockSelectClassToCreate($sClass, $sClassLabel, $aPossibleClasses));
|
||||
|
||||
$oP->AddSubBlock($oPanel);
|
||||
return $oClassForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClassLabel
|
||||
* @param array $aPossibleClasses
|
||||
|
||||
8
css/backoffice/vendors/_selectize.scss
vendored
8
css/backoffice/vendors/_selectize.scss
vendored
@@ -33,15 +33,19 @@ $ibo-vendors-selectize--input-error--border: 1px solid $ibo-color-red-600 !defau
|
||||
display: flex;
|
||||
|
||||
.selectize-add-option {
|
||||
position: absolute;
|
||||
right: $ibo-vendors-selectize-control--plugin-add-button--add-option--right;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
position: absolute;
|
||||
right: $ibo-vendors-selectize-control--plugin-add-button--add-option--right;
|
||||
|
||||
height: $ibo-vendors-selectize-control--plugin-add-button--add-option--height;
|
||||
width: $ibo-vendors-selectize-control--plugin-add-button--add-option--width;
|
||||
z-index: 1;
|
||||
|
||||
color: $ibo-vendors-selectize-control--plugin-add-button--add-option--color;
|
||||
@extend %ibo-font-size-100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2023 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
|
||||
*/
|
||||
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
'UI:Object:Modal:Title' => 'Create an object',
|
||||
));
|
||||
@@ -1,4 +1,4 @@
|
||||
let CombodoLinkSetWorker = new function(){
|
||||
const iTopLinkSetWorker = new function(){
|
||||
|
||||
// defines
|
||||
const ROUTER_BASE_URL = '../pages/ajax.render.php';
|
||||
@@ -1,4 +1,4 @@
|
||||
let CombodoLinkSet = new function () {
|
||||
const iTopLinkSet = new function () {
|
||||
|
||||
/**
|
||||
* Create a new link object and add it to set widget.
|
||||
@@ -12,18 +12,17 @@ let CombodoLinkSet = new function () {
|
||||
* @param oWidget
|
||||
* @constructor
|
||||
*/
|
||||
const CallCreateLinkedObject = function(sLinkedClass, sCode, sHostObjectClass, sHostObjectKey, sRemoteExtKey, sRemoteClass, oWidget)
|
||||
const CallCreateLinkedObject = function(sLinkedClass, oWidget)
|
||||
{
|
||||
// Create link object
|
||||
CombodoLinkSetWorker.CreateLinkedObject(sLinkedClass, sCode, sHostObjectClass, sHostObjectKey,
|
||||
function(){
|
||||
iTopObjectWorker.CreateObject(sLinkedClass, function(){
|
||||
$(this).find("form").remove();
|
||||
$(this).dialog('destroy');
|
||||
},
|
||||
function(event, data){
|
||||
|
||||
// We have just create a link object, now request the remote object
|
||||
CombodoLinkSetWorker.GetRemoteObject(data.data.object.class_name, data.data.object.key, sRemoteExtKey, sRemoteClass, function(data){
|
||||
iTopObjectWorker.GetObject(data.data.object.class_name, data.data.object.key, function(data){
|
||||
|
||||
// Add the new remote object in widget set options list
|
||||
const selectize = oWidget[0].selectize;
|
||||
@@ -32,9 +31,6 @@ let CombodoLinkSet = new function () {
|
||||
|
||||
// Select the new remote object
|
||||
selectize.addItem(data.data.object.key);
|
||||
|
||||
// Add to initial values, to handle remove action
|
||||
selectize.addInitialValue(data.data.object.key);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -34,7 +34,7 @@ $(function()
|
||||
const me = this;
|
||||
|
||||
// link object deletion
|
||||
CombodoLinkSetWorker.DeleteLinkedObject(this.options.link_class, sLinkedObjectKey, function (data) {
|
||||
iTopLinkSetWorker.DeleteLinkedObject(this.options.link_class, sLinkedObjectKey, function (data) {
|
||||
if (data.data.success === true) {
|
||||
me.$tableSettingsDialog.DataTableSettings('DoRefresh');
|
||||
} else {
|
||||
@@ -55,7 +55,7 @@ $(function()
|
||||
const me = this;
|
||||
|
||||
// link object unlink
|
||||
CombodoLinkSetWorker.DetachLinkedObject(this.options.link_class, sLinkedObjectKey, this.options.external_key_to_me, function (data) {
|
||||
iTopLinkSetWorker.DetachLinkedObject(this.options.link_class, sLinkedObjectKey, this.options.external_key_to_me, function (data) {
|
||||
if (data.data.success === true) {
|
||||
me.$tableSettingsDialog.DataTableSettings('DoRefresh');
|
||||
} else {
|
||||
@@ -82,7 +82,7 @@ $(function()
|
||||
const sHostObjectId = $Table.closest('[data-role="ibo-object-details"]').attr('data-object-id');
|
||||
|
||||
// link object creation
|
||||
CombodoLinkSetWorker.CreateLinkedObject(sClass, sAttCode, sHostObjectClass, sHostObjectId, function(){
|
||||
iTopLinkSetWorker.CreateLinkedObject(sClass, sAttCode, sHostObjectClass, sHostObjectId, function(){
|
||||
$(this).find("form").remove();
|
||||
$(this).dialog('destroy');
|
||||
},function (event, data) {
|
||||
@@ -102,7 +102,7 @@ $(function()
|
||||
const me = this;
|
||||
|
||||
// link object modification
|
||||
ObjectWorker.ModifyObject(this.options.link_class, sLinkedObjectKey, function () {
|
||||
iTopObjectWorker.ModifyObject(this.options.link_class, sLinkedObjectKey, function () {
|
||||
$(this).find("form").remove();
|
||||
$(this).dialog('destroy');
|
||||
}, function(event, data){
|
||||
|
||||
@@ -1,10 +1,32 @@
|
||||
let ObjectWorker = new function(){
|
||||
const iTopObjectWorker = new function(){
|
||||
|
||||
// defines
|
||||
const ROUTER_BASE_URL = '../pages/ajax.render.php';
|
||||
const ROUTE_CREATE_OBJECT = 'object.new';
|
||||
const ROUTE_MODIFY_OBJECT = 'object.modify';
|
||||
const ROUTE_GET_OBJECT = 'object.get';
|
||||
|
||||
const CallAjaxCreateObject = function(sClass, oOnModalCloseCallback = null, oOnFormSubmittedCallback = null){
|
||||
|
||||
let oOptions = {
|
||||
title: Dict.S('UI:Object:Modal:Title'),
|
||||
content: {
|
||||
endpoint: `${ROUTER_BASE_URL}?route=${ROUTE_CREATE_OBJECT}`,
|
||||
data: {
|
||||
class: sClass,
|
||||
}
|
||||
},
|
||||
extra_options: {
|
||||
callback_on_modal_close: oOnModalCloseCallback
|
||||
},
|
||||
}
|
||||
|
||||
const oModal = CombodoModal.OpenModal(oOptions);
|
||||
if(oOnFormSubmittedCallback !== null){
|
||||
oModal.on('itop.form.submitted', 'form', oOnFormSubmittedCallback);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* CallAjaxModifyObject.
|
||||
*
|
||||
@@ -40,7 +62,7 @@ let ObjectWorker = new function(){
|
||||
* CallAjaxGetObject.
|
||||
*
|
||||
* @param {string} sObjectClass
|
||||
* @param {string} sObjectKey
|
||||
* @param {string} sObjectId
|
||||
* @param oOnResponseCallback
|
||||
* @constructor
|
||||
*/
|
||||
@@ -54,6 +76,7 @@ let ObjectWorker = new function(){
|
||||
|
||||
|
||||
return {
|
||||
CreateObject: CallAjaxCreateObject,
|
||||
ModifyObject: CallAjaxModifyObject,
|
||||
GetObject: CallAjaxGetObject
|
||||
}
|
||||
@@ -28,7 +28,7 @@ Selectize.define("combodo_add_button", function (aOptions) {
|
||||
label: "+",
|
||||
html: function () {
|
||||
return (
|
||||
'<a class="' + this.className + ' fas fa-plus" title="' + this.title + '"></a>'
|
||||
'<a class="' + this.className + '"><i class="fas fa-plus" title="' + this.title + '"/></a>'
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
78
pages/UI.php
78
pages/UI.php
@@ -704,80 +704,12 @@ try
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/** @deprecated 3.1.0 Use the "object.new" route instead */
|
||||
// Kept for backward compatibility
|
||||
case 'new': // Form to create a new object
|
||||
$oP->DisableBreadCrumb();
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$sStateCode = utils::ReadParam('state', '');
|
||||
$bCheckSubClass = utils::ReadParam('checkSubclass', true);
|
||||
if ( empty($sClass) )
|
||||
{
|
||||
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
|
||||
}
|
||||
|
||||
/*
|
||||
$aArgs = utils::ReadParam('default', array(), false, 'raw_data');
|
||||
$aContext = $oAppContext->GetAsHash();
|
||||
foreach( $oAppContext->GetNames() as $key)
|
||||
{
|
||||
$aArgs[$key] = $oAppContext->GetCurrentValue($key);
|
||||
}
|
||||
*/
|
||||
// If the specified class has subclasses, ask the user an instance of which class to create
|
||||
$aSubClasses = MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||
$aPossibleClasses = array();
|
||||
$sRealClass = '';
|
||||
if ($bCheckSubClass)
|
||||
{
|
||||
foreach($aSubClasses as $sCandidateClass)
|
||||
{
|
||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
||||
{
|
||||
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
||||
}
|
||||
}
|
||||
// Only one of the subclasses can be instantiated...
|
||||
if (count($aPossibleClasses) == 1)
|
||||
{
|
||||
$aKeys = array_keys($aPossibleClasses);
|
||||
$sRealClass = $aKeys[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sRealClass = $sClass;
|
||||
}
|
||||
|
||||
if (!empty($sRealClass))
|
||||
{
|
||||
// Set all the default values in an object and clone this "default" object
|
||||
$oObjToClone = MetaModel::NewObject($sRealClass);
|
||||
// 1st - set context values
|
||||
$oAppContext->InitObjectFromContext($oObjToClone);
|
||||
// 2nd - set values from the page argument 'default'
|
||||
$oObjToClone->UpdateObjectFromArg('default');
|
||||
$aPrefillFormParam = array(
|
||||
'user' => Session::Get('auth_user'),
|
||||
'context' => $oAppContext->GetAsHash(),
|
||||
'default' => utils::ReadParam('default', array(), '', 'raw_data'),
|
||||
'origin' => 'console',
|
||||
);
|
||||
// 3rd - prefill API
|
||||
$oObjToClone->PrefillForm('creation_from_0', $aPrefillFormParam);
|
||||
|
||||
// Display the creation form
|
||||
$sClassLabel = MetaModel::GetName($sRealClass);
|
||||
$sClassIcon = MetaModel::GetClassIcon($sRealClass);
|
||||
$sObjectTmpKey = $oObjToClone->GetKey();
|
||||
$sHeaderTitle = Dict::Format('UI:CreationTitle_Class', $sClassLabel);
|
||||
// Note: some code has been duplicated to the case 'apply_new' when a data integrity issue has been found
|
||||
$oP->set_title(Dict::Format('UI:CreationPageTitle_Class', $sClassLabel));
|
||||
$oP->SetContentLayout(PageContentFactory::MakeForObjectDetails($oObjToClone, cmdbAbstractObject::ENUM_DISPLAY_MODE_CREATE));
|
||||
cmdbAbstractObject::DisplayCreationForm($oP, $sRealClass, $oObjToClone, array(), array('wizard_container' => 1, 'keep_source_object' => true)); // wizard_container: Display the title above the form
|
||||
} else {
|
||||
// Select the derived class to create
|
||||
cmdbAbstractObject::DisplaySelectClassToCreate($sClass, $oP, $oAppContext, $aPossibleClasses,['state' => $sStateCode]);
|
||||
}
|
||||
$oController = new ObjectController();
|
||||
$oP = $oController->OperationNew();
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -37,7 +37,8 @@ class Set extends AbstractInput
|
||||
public const DEFAULT_JS_ON_READY_TEMPLATE_REL_PATH = 'base/components/input/set/layout';
|
||||
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
'js/links/links_set_worker.js',
|
||||
'js/links/links-set-worker.js',
|
||||
'js/object/object-worker.js',
|
||||
'js/selectize/plugin_combodo_add_button.js',
|
||||
'js/selectize/plugin_combodo_auto_position.js',
|
||||
'js/selectize/plugin_combodo_update_operations.js',
|
||||
|
||||
@@ -36,8 +36,8 @@ abstract class AbstractBlockLinksViewTable extends UIContentBlock
|
||||
public const DEFAULT_JS_ON_READY_TEMPLATE_REL_PATH = 'application/links/layout';
|
||||
public const DEFAULT_JS_FILES_REL_PATH = [
|
||||
'js/links/links_view_table_widget.js',
|
||||
'js/links/links_set_worker.js',
|
||||
'js/objects/objects_worker.js',
|
||||
'js/links/links-set-worker.js',
|
||||
'js/object/object-worker.js',
|
||||
'js/wizardhelper.js',
|
||||
];
|
||||
|
||||
|
||||
@@ -59,18 +59,14 @@ class LinksSetUIBlockFactory extends SetUIBlockFactory
|
||||
// Set UI block for OQL
|
||||
$oSetUIBlock = SetUIBlockFactory::MakeForOQL($sId, $sTargetClass, $oAttDef->GetValuesDef()->GetFilterExpression(), $sWizardHelperJsVarName);
|
||||
|
||||
$oSetUIBlock->AddJsFileRelPath('js/links/links_set.js');
|
||||
$oSetUIBlock->AddJsFileRelPath('js/links/links-set.js');
|
||||
|
||||
// Remove add button for 3_1_lot1
|
||||
// Linkset controller OperationCreateLinkedObject need the host object to exist, so if we are in creation of the host object (id=-1) the linked object creation doesn't work.
|
||||
//
|
||||
// // Add button behaviour
|
||||
// if (in_array($oAttDef->GetEditMode(), [LINKSET_EDITMODE_ADDREMOVE, LINKSET_EDITMODE_ADDONLY, LINKSET_EDITMODE_INPLACE, LINKSET_EDITMODE_ACTIONS])
|
||||
// && $oHostDbObject !== null) {
|
||||
// $sHostClass = get_class($oHostDbObject);
|
||||
// $oSetUIBlock->SetHasAddOptionButton(true);
|
||||
// $oSetUIBlock->SetAddOptionButtonJsOnClick("CombodoLinkSet.CreateLinkedObject('{$oAttDef->GetLinkedClass()}', '{$oAttDef->GetCode()}', '{$sHostClass}', '{$oHostDbObject->GetKey()}', '{$sTargetField}', '{$sTargetClass}', oWidget{$oSetUIBlock->GetId()} );");
|
||||
// }
|
||||
// Add button behaviour
|
||||
if (in_array($oAttDef->GetEditMode(), [LINKSET_EDITMODE_ADDREMOVE, LINKSET_EDITMODE_ADDONLY, LINKSET_EDITMODE_INPLACE, LINKSET_EDITMODE_ACTIONS])
|
||||
&& $oHostDbObject !== null) {
|
||||
$oSetUIBlock->SetHasAddOptionButton(true);
|
||||
$oSetUIBlock->SetAddOptionButtonJsOnClick("iTopLinkSet.CreateLinkedObject('{$sTargetClass}', oWidget{$oSetUIBlock->GetId()} );");
|
||||
}
|
||||
|
||||
// Current value
|
||||
$aCurrentValues = LinkSetDataTransformer::Decode($oDbObjectSet, $sTargetClass, $sTargetField);
|
||||
|
||||
@@ -219,6 +219,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
// Modals
|
||||
$this->add_dict_entries('UI:Modal:');
|
||||
$this->add_dict_entries('UI:Links:');
|
||||
$this->add_dict_entries('UI:Object:');
|
||||
$this->add_dict_entry('UI:Layout:ObjectDetails:New:Modal:Title');
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
namespace Combodo\iTop\Controller\Base\Layout;
|
||||
|
||||
use AjaxPage;
|
||||
use ApplicationContext;
|
||||
use ApplicationException;
|
||||
use cmdbAbstractObject;
|
||||
use CMDBObjectSet;
|
||||
use Combodo\iTop\Application\Helper\Session;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\QuickCreate\QuickCreateHelper;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
||||
@@ -40,6 +42,161 @@ class ObjectController extends AbstractController
|
||||
{
|
||||
public const ROUTE_NAMESPACE = 'object';
|
||||
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \MySQLException
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \ConfigException
|
||||
* @throws \ApplicationException
|
||||
* @throws \MissingQueryArgument
|
||||
*/
|
||||
public function OperationNew()
|
||||
{
|
||||
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$sStateCode = utils::ReadParam('state', '');
|
||||
$bCheckSubClass = utils::ReadParam('checkSubclass', true);
|
||||
$oAppContext = new ApplicationContext();
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$oPage = new AjaxPage('');
|
||||
} else {
|
||||
$oPage = new iTopWebPage('', $bPrintable);
|
||||
$oPage->DisableBreadCrumb();
|
||||
$this->AddRequiredForModificationJsFilesToPage($oPage);
|
||||
}
|
||||
|
||||
|
||||
if (empty($sClass))
|
||||
{
|
||||
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
|
||||
}
|
||||
|
||||
// If the specified class has subclasses, ask the user an instance of which class to create
|
||||
$aSubClasses = MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||
$aPossibleClasses = array();
|
||||
$sRealClass = '';
|
||||
if ($bCheckSubClass)
|
||||
{
|
||||
foreach($aSubClasses as $sCandidateClass)
|
||||
{
|
||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
||||
{
|
||||
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
||||
}
|
||||
}
|
||||
// Only one of the subclasses can be instantiated...
|
||||
if (count($aPossibleClasses) === 1)
|
||||
{
|
||||
$aKeys = array_keys($aPossibleClasses);
|
||||
$sRealClass = $aKeys[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sRealClass = $sClass;
|
||||
}
|
||||
|
||||
if (!empty($sRealClass))
|
||||
{
|
||||
// Set all the default values in an object and clone this "default" object
|
||||
$oObjToClone = MetaModel::NewObject($sRealClass);
|
||||
// 1st - set context values
|
||||
$oAppContext->InitObjectFromContext($oObjToClone);
|
||||
// 2nd - set values from the page argument 'default'
|
||||
$oObjToClone->UpdateObjectFromArg('default');
|
||||
$aPrefillFormParam = array(
|
||||
'user' => Session::Get('auth_user'),
|
||||
'context' => $oAppContext->GetAsHash(),
|
||||
'default' => utils::ReadParam('default', array(), '', 'raw_data'),
|
||||
'origin' => 'console',
|
||||
);
|
||||
// 3rd - prefill API
|
||||
$oObjToClone->PrefillForm('creation_from_0', $aPrefillFormParam);
|
||||
|
||||
// Display the creation form
|
||||
$sClassLabel = MetaModel::GetName($sRealClass);
|
||||
$sClassIcon = MetaModel::GetClassIcon($sRealClass);
|
||||
$sObjectTmpKey = $oObjToClone->GetKey();
|
||||
$sHeaderTitle = Dict::Format('UI:CreationTitle_Class', $sClassLabel);
|
||||
// Note: some code has been duplicated to the case 'apply_new' when a data integrity issue has been found
|
||||
|
||||
$aFormExtraParams = array('wizard_container' => 1, 'keep_source_object' => true);
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$aFormExtraParams['js_handlers'] = [];
|
||||
$aFormExtraParams['noRelations'] = true;
|
||||
$aFormExtraParams['hide_transitions'] = true;
|
||||
// Add a random prefix to avoid ID collision for form elements
|
||||
$aFormExtraParams['formPrefix'] = utils::Sanitize(uniqid('', true), '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER).'_';
|
||||
// We display this form in a modal, once we submit (in ajax) we probably want to only close the modal
|
||||
$aFormExtraParams['js_handlers']['form_on_submit'] =
|
||||
<<<JS
|
||||
event.preventDefault();
|
||||
if(bOnSubmitForm === true)
|
||||
{
|
||||
let oForm = $(this);
|
||||
let sUrl = oForm.attr('action');
|
||||
let sPosting = $.post( sUrl, oForm.serialize());
|
||||
|
||||
/* Alerts the results */
|
||||
sPosting.done(function(data) {
|
||||
// fire event
|
||||
oForm.trigger('itop.form.submitted', [data]);
|
||||
if(data.success !== undefined && data.success === true) {
|
||||
oForm.closest('[data-role="ibo-modal"]').dialog('close');
|
||||
}
|
||||
else {
|
||||
/* We're not in submit anymore */
|
||||
window.bInSubmit = false;
|
||||
oForm.attr('data-form-state', 'default');
|
||||
/* Display error popup */
|
||||
CombodoModal.OpenInformativeModal(data.data.error_message, 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
JS;
|
||||
|
||||
|
||||
$aFormExtraParams['js_handlers']['cancel_button_on_click'] =
|
||||
<<<JS
|
||||
function() {
|
||||
$(this).closest('[data-role="ibo-modal"]').dialog('close');
|
||||
};
|
||||
JS;
|
||||
} else {
|
||||
$oPage->set_title(Dict::Format('UI:CreationPageTitle_Class', $sClassLabel));
|
||||
$oPage->SetContentLayout(PageContentFactory::MakeForObjectDetails($oObjToClone, cmdbAbstractObject::ENUM_DISPLAY_MODE_CREATE));
|
||||
}
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObjToClone, array(), $aFormExtraParams);
|
||||
} else {
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$oClassForm = cmdbAbstractObject::DisplayFormBlockSelectClassToCreate($sClass, MetaModel::GetName($sClass), $oAppContext, $aPossibleClasses, ['state' => $sStateCode]);
|
||||
$sCurrentUrl = utils::GetAbsoluteUrlAppRoot().'/pages/UI.php?route=object.new';
|
||||
$oClassForm->SetOnSubmitJsCode(
|
||||
<<<JS
|
||||
let me = this;
|
||||
let aParam = {};
|
||||
aParam['class'] = $(this).find('[name="class"]').val();
|
||||
let sPosting = $.post('$sCurrentUrl', aParam);
|
||||
sPosting.done(function(data){
|
||||
$(me).closest('[data-role="ibo-modal"]').html(data);
|
||||
$(me).closest('[data-role="ibo-modal"]').dialog({ position: { my: "center", at: "center", of: window }});;
|
||||
});
|
||||
return false;
|
||||
JS
|
||||
);
|
||||
$oPage->AddUiBlock($oClassForm);
|
||||
}
|
||||
else{
|
||||
cmdbAbstractObject::DisplaySelectClassToCreate($sClass, $oPage, $oAppContext, $aPossibleClasses,['state' => $sStateCode]);
|
||||
}
|
||||
}
|
||||
return $oPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \iTopWebPage|\AjaxPage Object edit form in its webpage
|
||||
* @throws \ApplicationException
|
||||
@@ -603,7 +760,7 @@ JS;
|
||||
|
||||
// Retrieve query params
|
||||
$sObjectClass = utils::ReadParam('object_class', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
$sObjectKey = utils::ReadParam('object_key', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
$sObjectKey = utils::ReadParam('object_key', 0, false, utils::ENUM_SANITIZATION_FILTER_INTEGER);
|
||||
|
||||
// Retrieve object
|
||||
try {
|
||||
|
||||
@@ -270,7 +270,7 @@ JS
|
||||
try {
|
||||
$oObject = MetaModel::GetObject($sObjectClass, $sObjectKey);
|
||||
$sLinkKey = $oObject->GetKey();
|
||||
if ($sRemoteExtKey !== null) {
|
||||
if (!utils::IsNullOrEmptyString($sRemoteExtKey)) {
|
||||
$oObject = MetaModel::GetObject($sRemoteClass, $oObject->Get($sRemoteExtKey));
|
||||
}
|
||||
$aObjectData = ObjectRepository::ConvertObjectToArray($oObject, $sObjectClass);
|
||||
|
||||
Reference in New Issue
Block a user