diff --git a/datamodels/2.x/itop-portal-base/portal/src/controllers/objectcontroller.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/controllers/objectcontroller.class.inc.php index a1430d393..fa003a3dc 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/controllers/objectcontroller.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/controllers/objectcontroller.class.inc.php @@ -639,6 +639,29 @@ class ObjectController extends AbstractController $oApp['context_manipulator']->PrepareObject($aActionRules, $oHostObject); } + // Updating host object with form data / values + $sFormManagerClass = $aRequestContent['formmanager_class']; + $sFormManagerData = $aRequestContent['formmanager_data']; + if ($sFormManagerClass !== null && $sFormManagerData !== null) + { + $oFormManager = $sFormManagerClass::FromJSON($sFormManagerData); + $oFormManager->SetApplication($oApp); + $oFormManager->SetObject($oHostObject); + + // Applying action rules if present + if (($oFormManager->GetActionRulesToken() !== null) && ($oFormManager->GetActionRulesToken() !== '')) + { + $aActionRules = ContextManipulatorHelper::DecodeRulesToken($oFormManager->GetActionRulesToken()); + $oObj = $oFormManager->GetObject(); + $oApp['context_manipulator']->PrepareObject($aActionRules, $oObj); + $oFormManager->SetObject($oObj); + } + + // Updating host object + $oFormManager->OnUpdate(array('currentValues' => $aRequestContent['current_values'])); + $oHostObject = $oFormManager->GetObject(); + } + // Building search query // - Retrieving target object class from attcode $oTargetAttDef = MetaModel::GetAttributeDef($sHostObjectClass, $sTargetAttCode); @@ -649,7 +672,7 @@ class ObjectController extends AbstractController $oSearch->AddConditionExpression(new BinaryExpression(new FieldExpression('friendlyname', $oSearch->GetClassAlias()), 'LIKE', new VariableExpression('ac_query'))); // - Intersecting with scope constraints $oSearch = $oSearch->Intersect($oApp['scope_validator']->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sTargetObjectClass, UR_ACTION_READ)); - + // Retrieving results // - Preparing object set $oSet = new DBObjectSet($oSearch, array(), array('this' => $oHostObject, 'ac_query' => '%' . $sQuery . '%')); @@ -720,6 +743,30 @@ class ObjectController extends AbstractController $oApp['context_manipulator']->PrepareObject($aActionRules, $oHostObject); } + // Updating host object with form data / values + $oRequestParams = $oRequest->request; + $sFormManagerClass = $oRequestParams->get('formmanager_class'); + $sFormManagerData = $oRequestParams->get('formmanager_data'); + if ($sFormManagerClass !== null && $sFormManagerData !== null) + { + $oFormManager = $sFormManagerClass::FromJSON($sFormManagerData); + $oFormManager->SetApplication($oApp); + $oFormManager->SetObject($oHostObject); + + // Applying action rules if present + if (($oFormManager->GetActionRulesToken() !== null) && ($oFormManager->GetActionRulesToken() !== '')) + { + $aActionRules = ContextManipulatorHelper::DecodeRulesToken($oFormManager->GetActionRulesToken()); + $oObj = $oFormManager->GetObject(); + $oApp['context_manipulator']->PrepareObject($aActionRules, $oObj); + $oFormManager->SetObject($oObj); + } + + // Updating host object + $oFormManager->OnUpdate(array('currentValues' => $oRequestParams->get('current_values'))); + $oHostObject = $oFormManager->GetObject(); + } + // Retrieving request parameters $iPageNumber = ($oRequest->get('iPageNumber') !== null) ? $oRequest->get('iPageNumber') : 1; $iCountPerPage = ($oRequest->get('iCountPerPage') !== null) ? $oRequest->get('iCountPerPage') : static::DEFAULT_COUNT_PER_PAGE_LIST; @@ -752,7 +799,7 @@ class ObjectController extends AbstractController { throw new Exception('Search from attribute can only apply on AttributeExternalKey or AttributeLinkedSet objects, ' . get_class($oTargetAttDef) . ' given.'); } - + // - Retrieving class attribute list $aAttCodes = MetaModel::FlattenZList(MetaModel::GetZListItems($sTargetObjectClass, 'list')); // - Adding friendlyname attribute to the list is not already in it @@ -895,6 +942,8 @@ class ObjectController extends AbstractController 'sFormPath' => $sFormPath, 'sFieldId' => $sFieldId, 'aObjectIdsToIgnore' => $aObjectIdsToIgnore, + 'sFormManagerClass' => $sFormManagerClass, + 'sFormManagerData' => $sFormManagerData ) ); diff --git a/datamodels/2.x/itop-portal-base/portal/src/forms/objectformmanager.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/forms/objectformmanager.class.inc.php index 265196ccf..746bb931e 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/forms/objectformmanager.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/forms/objectformmanager.class.inc.php @@ -67,7 +67,14 @@ class ObjectFormManager extends FormManager */ static function FromJSON($sJson) { - $aJson = json_decode($sJson, true); + if (is_array($sJson)) + { + $aJson = $sJson; + } + else + { + $aJson = json_decode($sJson, true); + } $oFormManager = parent::FromJSON($sJson); @@ -80,7 +87,7 @@ class ObjectFormManager extends FormManager if (!isset($aJson['formobject_id'])) { - $oObject = new $sObjectClass(); + $oObject = MetaModel::NewObject($sObjectClass); } else { @@ -104,6 +111,11 @@ class ObjectFormManager extends FormManager // Retrieving form properties if (isset($aJson['formproperties'])) { + // As empty array are no passed through HTTP, this one is not always present and we have to ensure it is. + if (!isset($aJson['formproperties']['fields'])) + { + $aJson['formproperties']['fields'] = array(); + } $oFormManager->SetFormProperties($aJson['formproperties']); } @@ -258,7 +270,7 @@ class ObjectFormManager extends FormManager $aJson['formmode'] = $this->sMode; $aJson['formactionrulestoken'] = $this->sActionRulesToken; $aJson['formproperties'] = $this->aFormProperties; - + return $aJson; } diff --git a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_search_regular.html.twig b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_search_regular.html.twig index 399f1e5eb..c7f0198ca 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_search_regular.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_search_regular.html.twig @@ -150,6 +150,7 @@ "serverSide": true, "ajax": { "url": "{{ app.url_generator.generate('p_object_search_from_attribute', {'sTargetAttCode': sTargetAttCode, 'sHostObjectClass': sHostObjectClass, 'sHostObjectId': sHostObjectId, 'ar_token': sActionRulesToken})|raw }}", + "type": "POST", "data": function(d){ d.aObjectIdsToIgnore = {{ aSource.aObjectIdsToIgnore|json_encode()|raw }}; d.iPageNumber = Math.floor(d.start/d.length) + 1; @@ -160,6 +161,13 @@ { d.sSearchValue = d.search.value; } + {% if aSource.sFormManagerClass is not null and aSource.sFormManagerData is not null %} + // Retrieving form data + d.formmanager_class = "{{ aSource.sFormManagerClass|escape('js') }}"; + d.formmanager_data = {{ aSource.sFormManagerData|json_encode()|raw }}; + // Retrieving values from source form + d.current_values = $('[data-form-path="{{aSource.sFormPath}}"][data-field-id="{{aSource.sFieldId}}"]').closest('.portal_form_handler').portal_form_handler('getCurrentValues'); + {% endif %} } } }); diff --git a/datamodels/2.x/itop-portal-base/portal/web/js/portal_form_handler.js b/datamodels/2.x/itop-portal-base/portal/web/js/portal_form_handler.js index 9252b7a13..63a6c28cc 100644 --- a/datamodels/2.x/itop-portal-base/portal/web/js/portal_form_handler.js +++ b/datamodels/2.x/itop-portal-base/portal/web/js/portal_form_handler.js @@ -322,6 +322,10 @@ $(function() { this._onSubmitClick(oEvent); }, + getOptions: function() + { + return this.options; + }, getAttachmentIds: function() { var me = this; diff --git a/sources/form/formmanager.class.inc.php b/sources/form/formmanager.class.inc.php index 12db9d27a..2bfbc3516 100644 --- a/sources/form/formmanager.class.inc.php +++ b/sources/form/formmanager.class.inc.php @@ -43,7 +43,14 @@ abstract class FormManager static function FromJSON($sJson) { // Overload in child class when needed - $aJson = json_decode($sJson, true); + if (is_array($sJson)) + { + $aJson = $sJson; + } + else + { + $aJson = json_decode($sJson, true); + } $oFormManager = new static(); diff --git a/sources/renderer/bootstrap/fieldrenderer/bslinkedsetfieldrenderer.class.inc.php b/sources/renderer/bootstrap/fieldrenderer/bslinkedsetfieldrenderer.class.inc.php index fcff7ec8e..f60a6015b 100644 --- a/sources/renderer/bootstrap/fieldrenderer/bslinkedsetfieldrenderer.class.inc.php +++ b/sources/renderer/bootstrap/fieldrenderer/bslinkedsetfieldrenderer.class.inc.php @@ -406,7 +406,6 @@ EOF // - Item count state handler var updateItemCount = function() { - console.log(oSelectedItems_{$this->oField->GetGlobalId()}); $('#{$sCollapseTogglerId} > .text').text( oTable_{$this->oField->GetGlobalId()}.rows().count() ); }; diff --git a/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php b/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php index 948536dbb..e34bc4ec1 100644 --- a/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php +++ b/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php @@ -184,7 +184,7 @@ EOF me.element.find('#{$this->oField->GetGlobalId()}').val(sItemId); me.element.find('#{$sAutocompleteFieldId}').val(sItemName); oAutocompleteSource_{$this->oField->GetId()}.index.datums[sItemId] = {id: sItemId, name: sItemName}; - +console.log('callback', oData); // Triggering field change event me.element.closest(".field_set").trigger("field_change", { id: me.element.find('#{$this->oField->GetGlobalId()}').attr("id"), @@ -208,7 +208,10 @@ EOF settings.type = "POST"; settings.contentType = "application/json; charset=UTF-8"; settings.data = { - sQuery: query + sQuery: query, + formmanager_class: $("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}']").closest('.portal_form_handler').portal_form_handler('getOptions').formmanager_class, + formmanager_data: $("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}']").closest('.portal_form_handler').portal_form_handler('getOptions').formmanager_data, + current_values: $("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}']").closest('.portal_form_handler').portal_form_handler('getCurrentValues') } return settings; }, @@ -241,6 +244,10 @@ EOF }) .off('typeahead:select').on('typeahead:select', function(oEvent, oSuggestion){ $('#{$this->oField->GetGlobalId()}').val(oSuggestion.id); + // Triggering set_current_value event + var oValue = {}; + oValue[oSuggestion.id] = oSuggestion.name; + $("[data-field-id='{$this->oField->GetId()}'][data-form-path='{$this->oField->GetFormPath()}']").trigger('set_current_value', {value: oValue}); }) .off('typeahead:change').on('typeahead:change', function(oEvent, oSuggestion){ // Checking if the value is a correct value. This is necessary because the user could empty the field / remove some chars and typeahead would not update the hidden input @@ -397,7 +404,10 @@ EOF '{$sEndpoint}', { sFormPath: '{$this->oField->GetFormPath()}', - sFieldId: '{$this->oField->GetId()}' + 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') } ); oModalElem.modal('show');