diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 626f271070..98550484a8 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -759,10 +759,11 @@ public function DisplayBareRelations(WebPage $oPage, $bEditMode = false) if ($bEditMode && (!$bReadOnly)) { $sInputId = $this->m_iFormId.'_'.$sAttCode; $sDisplayValue = ''; // not used - $sHTMLValue = "".self::GetFormElementForField($oPage, $sClass, $sAttCode, - $oAttDef, $oLinkSet, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).''; + $oDiv=UIContentBlockUIBlockFactory::MakeStandard('field_'.$sInputId); + $oLinkBlock = self::GetBlockFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $oLinkSet, $sDisplayValue, $sInputId, '', $iFlags, $aArgs); + $oDiv->AddSubBlock($oLinkBlock); $this->AddToFieldsMap($sAttCode, $sInputId); - $oPage->add($sHTMLValue); + $oPage->AddUiBlock($oDiv); } else { if ($oAttDef->IsIndirect()) { $oBlockLinkSetViewTable = new BlockIndirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly); @@ -2043,161 +2044,200 @@ public static function GetSearchForm(WebPage $oPage, CMDBObjectSet $oSet, $aExtr */ public static function GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $value = '', $sDisplayValue = '', $iId = '', $sNameSuffix = '', $iFlags = 0, $aArgs = array(), $bPreserveCurrentValue = true, &$sInputType = '') { - $sFormPrefix = isset($aArgs['formPrefix']) ? $aArgs['formPrefix'] : ''; - $sFieldPrefix = isset($aArgs['prefix']) ? $sFormPrefix.$aArgs['prefix'] : $sFormPrefix; - if ($sDisplayValue == '') { - $sDisplayValue = $value; - } - - if (isset($aArgs[$sAttCode]) && empty($value)) { - // default value passed by the context (either the app context of the operation) - $value = $aArgs[$sAttCode]; - } - - if (!empty($iId)) { - $iInputId = $iId; - } else { - $iInputId = utils::GetUniqueId(); - } - - $sHTMLValue = ''; - - // attributes not compatible with bulk modify - $bAttNotCompatibleWithBulk = array_key_exists('bulk_context', $aArgs) && !$oAttDef->IsBulkModifyCompatible(); - if ($bAttNotCompatibleWithBulk) { - $oTagSetBlock = new Html(''.Dict::S('UI:Bulk:modify:IncompatibleAttribute').''); - $sHTMLValue = ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oTagSetBlock); - } + $oBlock = self::GetBlockFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $value, $sDisplayValue, $iId, $sNameSuffix, $iFlags, $aArgs, $bPreserveCurrentValue, $sInputType); + return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock); + } + + /** + * @param \WebPage $oPage + * @param string $sClass + * @param string $sAttCode + * @param \AttributeDefinition $oAttDef + * @param string $value + * @param string $sDisplayValue + * @param string $iId + * @param string $sNameSuffix + * @param int $iFlags + * @param array{this: \DBObject, formPrefix: string} $aArgs + * @param bool $bPreserveCurrentValue Preserve the current value even if not allowed + * @param string $sInputType type of rendering used, see ENUM_INPUT_TYPE_* const + * + * @return UIContentBlock + * + * @throws \ArchivedObjectException + * @throws \ConfigException + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \DictExceptionMissingString + * @throws \MySQLException + * @throws \OQLException + * @throws \ReflectionException + * @throws \Twig\Error\LoaderError + * @throws \Twig\Error\RuntimeError + * @throws \Twig\Error\SyntaxError + * @throws \Exception + */ + public static function GetBlockFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $value = '', $sDisplayValue = '', $iId = '', $sNameSuffix = '', $iFlags = 0, $aArgs = array(), $bPreserveCurrentValue = true, &$sInputType = ''):UIContentBlock + { + $sFormPrefix = isset($aArgs['formPrefix']) ? $aArgs['formPrefix'] : ''; + $sFieldPrefix = isset($aArgs['prefix']) ? $sFormPrefix.$aArgs['prefix'] : $sFormPrefix; + if ($sDisplayValue == '') { + $sDisplayValue = $value; + } - if (!$oAttDef->IsExternalField() && !$bAttNotCompatibleWithBulk) { - $bMandatory = 'false'; - if ((!$oAttDef->IsNullAllowed()) || ($iFlags & OPT_ATT_MANDATORY)) { - $bMandatory = 'true'; - } - $sValidationSpan = ""; - $sReloadSpan = ""; - $sHelpText = utils::EscapeHtml($oAttDef->GetHelpOnEdition()); + if (isset($aArgs[$sAttCode]) && empty($value)) { + // default value passed by the context (either the app context of the operation) + $value = $aArgs[$sAttCode]; + } - // mandatory field control vars - $aEventsList = array(); // contains any native event (like change), plus 'validate' for the form submission - $sNullValue = $oAttDef->GetNullValue(); // used for the ValidateField() call in js/forms-json-utils.js - $sFieldToValidateId = $iId; // can be different than the displayed field (for example in TagSet) + if (!empty($iId)) { + $iInputId = $iId; + } else { + $iInputId = utils::GetUniqueId(); + } - // List of attributes that depend on the current one - // Might be modified depending on the current field - $sWizardHelperJsVarName = "oWizardHelper{$sFormPrefix}"; - $aDependencies = MetaModel::GetDependentAttributes($sClass, $sAttCode); + $oBlockValue = null; + $sHTMLValue = ''; - $sAttDefEditClass = $oAttDef->GetEditClass(); - switch ($sAttDefEditClass) { - case 'Date': - $sInputType = self::ENUM_INPUT_TYPE_SINGLE_INPUT; - $aEventsList[] = 'validate'; - $aEventsList[] = 'keyup'; - $aEventsList[] = 'change'; + // attributes not compatible with bulk modify + $bAttNotCompatibleWithBulk = array_key_exists('bulk_context', $aArgs) && !$oAttDef->IsBulkModifyCompatible(); + if ($bAttNotCompatibleWithBulk) { + $oBlockValue= new Html(''.Dict::S('UI:Bulk:modify:IncompatibleAttribute').''); + } - $sPlaceholderValue = 'placeholder="'.utils::EscapeHtml(AttributeDate::GetFormat()->ToPlaceholder()).'"'; - $sDisplayValueForHtml = utils::EscapeHtml($sDisplayValue); - $sHTMLValue = <<IsExternalField() && !$bAttNotCompatibleWithBulk) { + $bMandatory = 'false'; + if ((!$oAttDef->IsNullAllowed()) || ($iFlags & OPT_ATT_MANDATORY)) { + $bMandatory = 'true'; + } + $sValidationSpan = ""; + $sReloadSpan = ""; + $sHelpText = utils::EscapeHtml($oAttDef->GetHelpOnEdition()); + + // mandatory field control vars + $aEventsList = array(); // contains any native event (like change), plus 'validate' for the form submission + $sNullValue = $oAttDef->GetNullValue(); // used for the ValidateField() call in js/forms-json-utils.js + $sFieldToValidateId = $iId; // can be different than the displayed field (for example in TagSet) + + // List of attributes that depend on the current one + // Might be modified depending on the current field + $sWizardHelperJsVarName = "oWizardHelper{$sFormPrefix}"; + $aDependencies = MetaModel::GetDependentAttributes($sClass, $sAttCode); + + $sAttDefEditClass = $oAttDef->GetEditClass(); + switch ($sAttDefEditClass) { + case 'Date': + $sInputType = self::ENUM_INPUT_TYPE_SINGLE_INPUT; + $aEventsList[] = 'validate'; + $aEventsList[] = 'keyup'; + $aEventsList[] = 'change'; + + $sPlaceholderValue = 'placeholder="'.utils::EscapeHtml(AttributeDate::GetFormat()->ToPlaceholder()).'"'; + $sDisplayValueForHtml = utils::EscapeHtml($sDisplayValue); + $sHTMLValue = << {$sValidationSpan}{$sReloadSpan} HTML; - break; - - case 'DateTime': - $sInputType = self::ENUM_INPUT_TYPE_SINGLE_INPUT; - $aEventsList[] = 'validate'; - $aEventsList[] = 'keyup'; - $aEventsList[] = 'change'; - - $sPlaceholderValue = 'placeholder="'.utils::EscapeHtml(AttributeDateTime::GetFormat()->ToPlaceholder()).'"'; - $sDisplayValueForHtml = utils::EscapeHtml($sDisplayValue); - $sHTMLValue = <<ToPlaceholder()).'"'; + $sDisplayValueForHtml = utils::EscapeHtml($sDisplayValue); + $sHTMLValue = << {$sValidationSpan}{$sReloadSpan} HTML; - break; - - case 'Duration': - $sInputType = self::ENUM_INPUT_TYPE_MULTIPLE_INPUTS; - $aEventsList[] = 'validate'; - $aEventsList[] = 'change'; - $oPage->add_ready_script("$('#{$iId}_d').on('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });"); - $oPage->add_ready_script("$('#{$iId}_h').on('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });"); - $oPage->add_ready_script("$('#{$iId}_m').on('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });"); - $oPage->add_ready_script("$('#{$iId}_s').on('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });"); - $aVal = AttributeDuration::SplitDuration($value); - $sDays = ""; - $sHours = ""; - $sMinutes = ""; - $sSeconds = ""; - $sHidden = ""; - $sHTMLValue = Dict::Format('UI:DurationForm_Days_Hours_Minutes_Seconds', $sDays, $sHours, $sMinutes, $sSeconds).$sHidden." ".$sValidationSpan.$sReloadSpan; - $oPage->add_ready_script("$('#{$iId}').on('update', function(evt, sFormId) { return ToggleDurationField('$iId'); });"); - break; - - case 'Password': - $sInputType = self::ENUM_INPUT_TYPE_PASSWORD; - $aEventsList[] = 'validate'; - $aEventsList[] = 'keyup'; - $aEventsList[] = 'change'; - $sHTMLValue = "
{$sValidationSpan}{$sReloadSpan}"; - break; - - case 'OQLExpression': - case 'Text': - $sInputType = self::ENUM_INPUT_TYPE_TEXTAREA; - $aEventsList[] = 'validate'; - $aEventsList[] = 'keyup'; - $aEventsList[] = 'change'; - - $sEditValue = $oAttDef->GetEditValue($value); - $sEditValueForHtml = utils::EscapeHtml($sEditValue); - $sFullscreenLabelForHtml = utils::EscapeHtml(Dict::S('UI:ToggleFullScreen')); - - $aStyles = array(); - $sStyle = ''; - $sWidth = $oAttDef->GetWidth(); - if (!empty($sWidth)) { - $aStyles[] = 'width:'.$sWidth; - } - $sHeight = $oAttDef->GetHeight(); - if (!empty($sHeight)) { - $aStyles[] = 'height:'.$sHeight; - } - if (count($aStyles) > 0) { - $sStyle = 'style="'.implode('; ', $aStyles).'"'; - } - - $aTextareaCssClasses = []; - - if ($oAttDef->GetEditClass() == 'OQLExpression') { - $aTextareaCssClasses[] = 'ibo-query-oql'; - $aTextareaCssClasses[] = 'ibo-is-code'; - // N°3227 button to open predefined queries dialog - $sPredefinedBtnId = 'predef_btn_'.$sFieldPrefix.$sAttCode.$sNameSuffix; - $sSearchQueryLbl = Dict::S('UI:Edit:SearchQuery'); - $oPredefQueryButton = ButtonUIBlockFactory::MakeIconAction( - 'fas fa-search', - $sSearchQueryLbl, - null, - null, - false, - $sPredefinedBtnId - ); - $oPredefQueryButton->AddCSSClass('ibo-action-button') - ->SetOnClickJsCode( - <<add_ready_script("$('#{$iId}_d').on('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });"); + $oPage->add_ready_script("$('#{$iId}_h').on('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });"); + $oPage->add_ready_script("$('#{$iId}_m').on('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });"); + $oPage->add_ready_script("$('#{$iId}_s').on('keyup change', function(evt, sFormId) { return UpdateDuration('$iId'); });"); + $aVal = AttributeDuration::SplitDuration($value); + $sDays = ""; + $sHours = ""; + $sMinutes = ""; + $sSeconds = ""; + $sHidden = ""; + $sHTMLValue = Dict::Format('UI:DurationForm_Days_Hours_Minutes_Seconds', $sDays, $sHours, $sMinutes, $sSeconds).$sHidden." ".$sValidationSpan.$sReloadSpan; + $oPage->add_ready_script("$('#{$iId}').on('update', function(evt, sFormId) { return ToggleDurationField('$iId'); });"); + $oBlockValue= new Html($sHTMLValue); + break; + + case 'Password': + $sInputType = self::ENUM_INPUT_TYPE_PASSWORD; + $aEventsList[] = 'validate'; + $aEventsList[] = 'keyup'; + $aEventsList[] = 'change'; + $sHTMLValue = "
{$sValidationSpan}{$sReloadSpan}"; + $oBlockValue= new Html($sHTMLValue); + break; + + case 'OQLExpression': + case 'Text': + $sInputType = self::ENUM_INPUT_TYPE_TEXTAREA; + $aEventsList[] = 'validate'; + $aEventsList[] = 'keyup'; + $aEventsList[] = 'change'; + + $sEditValue = $oAttDef->GetEditValue($value); + $sEditValueForHtml = utils::EscapeHtml($sEditValue); + $sFullscreenLabelForHtml = utils::EscapeHtml(Dict::S('UI:ToggleFullScreen')); + + $aStyles = array(); + $sStyle = ''; + $sWidth = $oAttDef->GetWidth(); + if (!empty($sWidth)) { + $aStyles[] = 'width:'.$sWidth; + } + $sHeight = $oAttDef->GetHeight(); + if (!empty($sHeight)) { + $aStyles[] = 'height:'.$sHeight; + } + if (count($aStyles) > 0) { + $sStyle = 'style="'.implode('; ', $aStyles).'"'; + } + + $aTextareaCssClasses = []; + + if ($oAttDef->GetEditClass() == 'OQLExpression') { + $aTextareaCssClasses[] = 'ibo-query-oql'; + $aTextareaCssClasses[] = 'ibo-is-code'; + // N°3227 button to open predefined queries dialog + $sPredefinedBtnId = 'predef_btn_'.$sFieldPrefix.$sAttCode.$sNameSuffix; + $sSearchQueryLbl = Dict::S('UI:Edit:SearchQuery'); + $oPredefQueryButton = ButtonUIBlockFactory::MakeIconAction( + 'fas fa-search', + $sSearchQueryLbl, + null, + null, + false, + $sPredefinedBtnId + ); + $oPredefQueryButton->AddCSSClass('ibo-action-button') + ->SetOnClickJsCode( + <<RenderHtml(); - $oPage->add_ready_script($oPredefQueryRenderer->RenderJsInline($oPredefQueryButton::ENUM_JS_TYPE_ON_INIT)); + ); + $oPredefQueryRenderer = new BlockRenderer($oPredefQueryButton); + $sAdditionalStuff = $oPredefQueryRenderer->RenderHtml(); + $oPage->add_ready_script($oPredefQueryRenderer->RenderJsInline($oPredefQueryButton::ENUM_JS_TYPE_ON_INIT)); - $oPage->add_ready_script(<<add_ready_script(<<GetUniqueId(); - $sBaseUrl = utils::GetAbsoluteUrlAppRoot().'pages/run_query.php?expression='; - $sTestQueryLbl = Dict::S('UI:Edit:TestQuery'); - $oTestQueryButton = ButtonUIBlockFactory::MakeIconAction( - 'fas fa-play', - $sTestQueryLbl, - null, - null, - false, - $sTestResId - ); - $oTestQueryButton->AddCSSClass('ibo-action-button') - ->SetOnClickJsCode( - <<GetUniqueId(); + $sBaseUrl = utils::GetAbsoluteUrlAppRoot().'pages/run_query.php?expression='; + $sTestQueryLbl = Dict::S('UI:Edit:TestQuery'); + $oTestQueryButton = ButtonUIBlockFactory::MakeIconAction( + 'fas fa-play', + $sTestQueryLbl, + null, + null, + false, + $sTestResId + ); + $oTestQueryButton->AddCSSClass('ibo-action-button') + ->SetOnClickJsCode( + <<RenderHtml(); - $oPage->add_ready_script($oTestQueryRenderer->RenderJsInline($oTestQueryButton::ENUM_JS_TYPE_ON_INIT)); - } else { - $sAdditionalStuff = ''; - } - - // Ok, the text area is drawn here - $sTextareCssClassesAsString = implode(' ', $aTextareaCssClasses); - $sHTMLValue = <<RenderHtml(); + $oPage->add_ready_script($oTestQueryRenderer->RenderJsInline($oTestQueryButton::ENUM_JS_TYPE_ON_INIT)); + } else { + $sAdditionalStuff = ''; + } + + // Ok, the text area is drawn here + $sTextareCssClassesAsString = implode(' ', $aTextareaCssClasses); + $sHTMLValue = <<
@@ -2258,8 +2298,8 @@ public static function GetFormElementForField($oPage, $sClass, $sAttCode, $oAttD
{$sValidationSpan}{$sReloadSpan} HTML; - $oPage->add_ready_script( - <<add_ready_script( + <<GetWidth(); - if (!empty($sWidth)) { - $aStyles[] = 'width:'.$sWidth; - } - $sHeight = $oAttDef->GetHeight(); - if (!empty($sHeight)) { - $aStyles[] = 'height:'.$sHeight; - } - if (count($aStyles) > 0) { - $sStyle = 'style="'.implode('; ', $aStyles).'"'; - } - - $sHeader = '
'; // will be hidden in CSS (via :empty) if it remains empty - $sEditValue = is_object($value) ? $value->GetModifiedEntry('html') : ''; - $sPreviousLog = is_object($value) ? $value->GetAsHTML($oPage, true /* bEditMode */, array('AttributeText', 'RenderWikiHtml')) : ''; - $iEntriesCount = is_object($value) ? count($value->GetIndex()) : 0; - $sHidden = ""; // To know how many entries the case log already contains - - $sHTMLValue = "$sHeader
"; - $sHTMLValue .= ""; - $sHTMLValue .= "$sPreviousLog
{$sValidationSpan}{$sReloadSpan}$sHidden"; - - // Note: This should be refactored for all types of attribute (see at the end of this function) but as we are doing this for a maintenance release, we are scheduling it for the next main release in to order to avoid regressions as much as possible. - $sNullValue = $oAttDef->GetNullValue(); - if (!is_numeric($sNullValue)) { - $sNullValue = "'$sNullValue'"; // Add quotes to turn this into a JS string if it's not a number - } - $sOriginalValue = ($iFlags & OPT_ATT_MUSTCHANGE) ? json_encode($value->GetModifiedEntry('html')) : 'undefined'; - - $oPage->add_ready_script("$('#$iId').on('keyup change validate', function(evt, sFormId) { return ValidateCaseLogField('$iId', $bMandatory, sFormId, $sNullValue, $sOriginalValue) } );"); // Custom validation function - - // Replace the text area with CKEditor - // To change the default settings of the editor, - // a) edit the file /js/ckeditor/config.js - // b) or override some of the configuration settings, using the second parameter of ckeditor() - $aConfig = utils::GetCkeditorPref(); - $aConfig['placeholder'] = Dict::S('UI:CaseLogTypeYourTextHere'); - - // - Final config - $sConfigJS = json_encode($aConfig); - - WebResourcesHelper::EnableCKEditorToWebPage($oPage); - $oPage->add_ready_script("$('#$iId').ckeditor(function() { /* callback code */ }, $sConfigJS);"); // Transform $iId into a CKEdit - - $oPage->add_ready_script( -<<GetWidth(); + if (!empty($sWidth)) { + $aStyles[] = 'width:'.$sWidth; + } + $sHeight = $oAttDef->GetHeight(); + if (!empty($sHeight)) { + $aStyles[] = 'height:'.$sHeight; + } + if (count($aStyles) > 0) { + $sStyle = 'style="'.implode('; ', $aStyles).'"'; + } + + $sHeader = '
'; // will be hidden in CSS (via :empty) if it remains empty + $sEditValue = is_object($value) ? $value->GetModifiedEntry('html') : ''; + $sPreviousLog = is_object($value) ? $value->GetAsHTML($oPage, true /* bEditMode */, array('AttributeText', 'RenderWikiHtml')) : ''; + $iEntriesCount = is_object($value) ? count($value->GetIndex()) : 0; + $sHidden = ""; // To know how many entries the case log already contains + + $sHTMLValue = "$sHeader
"; + $sHTMLValue .= ""; + $sHTMLValue .= "$sPreviousLog
{$sValidationSpan}{$sReloadSpan}$sHidden"; + + // Note: This should be refactored for all types of attribute (see at the end of this function) but as we are doing this for a maintenance release, we are scheduling it for the next main release in to order to avoid regressions as much as possible. + $sNullValue = $oAttDef->GetNullValue(); + if (!is_numeric($sNullValue)) { + $sNullValue = "'$sNullValue'"; // Add quotes to turn this into a JS string if it's not a number + } + $sOriginalValue = ($iFlags & OPT_ATT_MUSTCHANGE) ? json_encode($value->GetModifiedEntry('html')) : 'undefined'; + + $oPage->add_ready_script("$('#$iId').on('keyup change validate', function(evt, sFormId) { return ValidateCaseLogField('$iId', $bMandatory, sFormId, $sNullValue, $sOriginalValue) } );"); // Custom validation function + + // Replace the text area with CKEditor + // To change the default settings of the editor, + // a) edit the file /js/ckeditor/config.js + // b) or override some of the configuration settings, using the second parameter of ckeditor() + $aConfig = utils::GetCkeditorPref(); + $aConfig['placeholder'] = Dict::S('UI:CaseLogTypeYourTextHere'); + + // - Final config + $sConfigJS = json_encode($aConfig); + + WebResourcesHelper::EnableCKEditorToWebPage($oPage); + $oPage->add_ready_script("$('#$iId').ckeditor(function() { /* callback code */ }, $sConfigJS);"); // Transform $iId into a CKEdit + + $oPage->add_ready_script( + <<GetEditValue($value); - $oWidget = new UIHTMLEditorWidget($iId, $oAttDef, $sNameSuffix, $sFieldPrefix, $sHelpText, - $sValidationSpan.$sReloadSpan, $sEditValue, $bMandatory); - $sHTMLValue = $oWidget->Display($oPage, $aArgs); - break; - - case 'LinkedSet': - if ($oAttDef->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_PROPERTY) { - $sInputType = self::ENUM_INPUT_TYPE_TAGSET_LINKEDSET; - if (array_key_exists('bulk_context', $aArgs)) { - $oTagSetBlock = LinkSetUIBlockFactory::MakeForBulkLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['bulk_context']); - } else { - $oTagSetBlock = LinkSetUIBlockFactory::MakeForLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['this']); - } - $oTagSetBlock->SetName("attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}"); - $aEventsList[] = 'validate'; - $aEventsList[] = 'change'; - $sHTMLValue = ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oTagSetBlock); - } else { - $sInputType = self::ENUM_INPUT_TYPE_LINKEDSET; - $oObj = $aArgs['this'] ?? null; - if ($oAttDef->IsIndirect()) { - $oWidget = new UILinksWidget($sClass, $sAttCode, $iId, $sNameSuffix, - $oAttDef->DuplicatesAllowed()); - } else { - $oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iId, $sNameSuffix); - } - $aEventsList[] = 'validate'; - $aEventsList[] = 'change'; - $sHTMLValue = $oWidget->Display($oPage, $value, array(), $sFormPrefix, $oObj); - } - break; - - case 'Document': - $sInputType = self::ENUM_INPUT_TYPE_DOCUMENT; - $aEventsList[] = 'validate'; - $aEventsList[] = 'change'; - $oDocument = $value; // Value is an ormDocument object - - $sFileName = ''; - if (is_object($oDocument)) { - $sFileName = $oDocument->GetFileName(); - } - $sFileNameForHtml = utils::EscapeHtml($sFileName); - $bHasFile = !empty($sFileName); - - $iMaxFileSize = utils::ConvertToBytes(ini_get('upload_max_filesize')); - $sRemoveBtnLabelForHtml = utils::EscapeHtml(Dict::S('UI:Button:RemoveDocument')); - $sExtraCSSClassesForRemoveButton = $bHasFile ? '' : 'ibo-is-hidden'; - - $sHTMLValue = <<GetEditValue($value); + $oWidget = new UIHTMLEditorWidget($iId, $oAttDef, $sNameSuffix, $sFieldPrefix, $sHelpText, + $sValidationSpan.$sReloadSpan, $sEditValue, $bMandatory); + $sHTMLValue = $oWidget->Display($oPage, $aArgs); + $oBlockValue= new Html($sHTMLValue); + break; + + case 'LinkedSet': + if ($oAttDef->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_PROPERTY) { + $sInputType = self::ENUM_INPUT_TYPE_TAGSET_LINKEDSET; + if (array_key_exists('bulk_context', $aArgs)) { + $oBlockValue = LinkSetUIBlockFactory::MakeForBulkLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['bulk_context']); + } else { + $oBlockValue = LinkSetUIBlockFactory::MakeForLinkSet($iId, $oAttDef, $value, $sWizardHelperJsVarName, $aArgs['this']); + } + $oBlockValue->SetName("attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}"); + $aEventsList[] = 'validate'; + $aEventsList[] = 'change'; + } else { + $sInputType = self::ENUM_INPUT_TYPE_LINKEDSET; + $oObj = $aArgs['this'] ?? null; + if ($oAttDef->IsIndirect()) { + $oWidget = new UILinksWidget($sClass, $sAttCode, $iId, $sNameSuffix, + $oAttDef->DuplicatesAllowed()); + } else { + $oWidget = new UILinksWidgetDirect($sClass, $sAttCode, $iId, $sNameSuffix); + } + $aEventsList[] = 'validate'; + $aEventsList[] = 'change'; + $oBlockValue = $oWidget->GetBlock($oPage, $value, array(), $sFormPrefix, $oObj); + } + break; + + case 'Document': + $sInputType = self::ENUM_INPUT_TYPE_DOCUMENT; + $aEventsList[] = 'validate'; + $aEventsList[] = 'change'; + $oDocument = $value; // Value is an ormDocument object + + $sFileName = ''; + if (is_object($oDocument)) { + $sFileName = $oDocument->GetFileName(); + } + $sFileNameForHtml = utils::EscapeHtml($sFileName); + $bHasFile = !empty($sFileName); + + $iMaxFileSize = utils::ConvertToBytes(ini_get('upload_max_filesize')); + $sRemoveBtnLabelForHtml = utils::EscapeHtml(Dict::S('UI:Button:RemoveDocument')); + $sExtraCSSClassesForRemoveButton = $bHasFile ? '' : 'ibo-is-hidden'; + + $sHTMLValue = << @@ -2420,138 +2462,145 @@ public static function GetFormElementForField($oPage, $sClass, $sAttCode, $oAttD {$sValidationSpan}{$sReloadSpan} HTML; - if ($sFileName == '') { - $oPage->add_ready_script("$('#remove_attr_{$iId}').addClass('ibo-is-hidden');"); - } - break; + if ($sFileName == '') { + $oPage->add_ready_script("$('#remove_attr_{$iId}').addClass('ibo-is-hidden');"); + } + $oBlockValue= new Html($sHTMLValue); + break; - case 'Image': - $sInputType = self::ENUM_INPUT_TYPE_IMAGE; - $aEventsList[] = 'validate'; - $aEventsList[] = 'change'; + case 'Image': + $sInputType = self::ENUM_INPUT_TYPE_IMAGE; + $aEventsList[] = 'validate'; + $aEventsList[] = 'change'; $oPage->LinkScriptFromAppRoot('js/edit_image.js'); - $oDocument = $value; // Value is an ormDocument objectm - $sDefaultUrl = $oAttDef->Get('default_image'); - if (is_object($oDocument) && !$oDocument->IsEmpty()) { - $sUrl = 'data:'.$oDocument->GetMimeType().';base64,'.base64_encode($oDocument->GetData()); - } else { - $sUrl = null; - } - - $sHTMLValue = "
\n"; - $sHTMLValue .= "{$sValidationSpan}{$sReloadSpan}\n"; - - $aEditImage = array( - 'input_name' => 'attr_'.$sFieldPrefix.$sAttCode.$sNameSuffix, - 'max_file_size' => utils::ConvertToBytes(ini_get('upload_max_filesize')), - 'max_width_px' => $oAttDef->Get('display_max_width'), - 'max_height_px' => $oAttDef->Get('display_max_height'), - 'current_image_url' => $sUrl, - 'default_image_url' => $sDefaultUrl, - 'labels' => array( - 'reset_button' => utils::EscapeHtml(Dict::S('UI:Button:ResetImage')), - 'remove_button' => utils::EscapeHtml(Dict::S('UI:Button:RemoveImage')), - 'upload_button' => !empty($sHelpText) ? $sHelpText : utils::EscapeHtml(Dict::S('UI:Button:UploadImage')), - ), - ); - $sEditImageOptions = json_encode($aEditImage); - $oPage->add_ready_script("$('#edit_$iInputId').edit_image($sEditImageOptions);"); - break; - - case 'StopWatch': - $sHTMLValue = "The edition of a stopwatch is not allowed!!!"; - break; - - case 'List': - // Not editable for now... - $sHTMLValue = ''; - break; - - case 'One Way Password': - $sInputType = self::ENUM_INPUT_TYPE_PASSWORD; - $aEventsList[] = 'validate'; - $oWidget = new UIPasswordWidget($sAttCode, $iId, $sNameSuffix); - $sHTMLValue = $oWidget->Display($oPage, $aArgs); - // Event list & validation is handled directly by the widget - break; - - case 'ExtKey': - /** @var \AttributeExternalKey $oAttDef */ - $aEventsList[] = 'validate'; - $aEventsList[] = 'change'; - - if ($bPreserveCurrentValue) { - $oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs, '', $value); - } else { - $oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs); - } - $sFieldName = $sFieldPrefix.$sAttCode.$sNameSuffix; - $aExtKeyParams = $aArgs; - $aExtKeyParams['iFieldSize'] = $oAttDef->GetMaxSize(); - $aExtKeyParams['iMinChars'] = $oAttDef->GetMinAutoCompleteChars(); - $sHTMLValue = UIExtKeyWidget::DisplayFromAttCode($oPage, $sAttCode, $sClass, $oAttDef->GetLabel(), - $oAllowedValues, $value, $iId, $bMandatory, $sFieldName, $sFormPrefix, $aExtKeyParams, false, $sInputType); - $sHTMLValue .= "\n"; - - $bHasExtKeyUpdatingRemoteClassFields = ( - array_key_exists('replaceDependenciesByRemoteClassFields', $aArgs) - && ($aArgs['replaceDependenciesByRemoteClassFields']) - ); - if ($bHasExtKeyUpdatingRemoteClassFields) { - // On this field update we need to update all the corresponding remote class fields - // Used when extkey widget is in a linkedset indirect - $sWizardHelperJsVarName = $aArgs['wizHelperRemote']; - $aDependencies = $aArgs['remoteCodes']; - } - - break; - - case 'RedundancySetting': - $sHTMLValue .= '
'; - $sHTMLValue .= $oAttDef->GetDisplayForm($value, $oPage, true); - $sHTMLValue .= '
'; - $sHTMLValue .= '
'.$sValidationSpan.$sReloadSpan.'
'; - $oPage->add_ready_script("$('#$iId :input').on('keyup change validate', function(evt, sFormId) { return ValidateRedundancySettings('$iId',sFormId); } );"); // Custom validation function - break; - - case 'CustomFields': - case 'FormField': - if ($sAttDefEditClass === 'CustomFields') { - /** @var \ormCustomFieldsValue $value */ - $oForm = $value->GetForm($sFormPrefix); - } else if ($sAttDefEditClass === 'FormField') { - $oForm = $oAttDef->GetForm($aArgs['this'], $sFormPrefix); - } - - $oFormRenderer = new ConsoleFormRenderer($oForm); - $aFormRenderedContent = $oFormRenderer->Render(); - - $aFieldSetOptions = array( - 'field_identifier_attr' => 'data-field-id', - // convention: fields are rendered into a div and are identified by this attribute - 'fields_list' => $aFormRenderedContent, - 'fields_impacts' => $oForm->GetFieldsImpacts(), - 'form_path' => $oForm->GetId(), - ); - $sFieldSetOptions = json_encode($aFieldSetOptions); - $aFormHandlerOptions = array( - 'wizard_helper_var_name' => 'oWizardHelper'.$sFormPrefix, - 'custom_field_attcode' => $sAttCode, - ); - $sFormHandlerOptions = json_encode($aFormHandlerOptions); - - $sHTMLValue .= '
'; - $sHTMLValue .= '
'; - $sHTMLValue .= '
'; - $sHTMLValue .= '
'.$sReloadSpan.'
'; // No validation span for this one: it does handle its own validation! - $sHTMLValue .= "\n"; + $oDocument = $value; // Value is an ormDocument objectm + $sDefaultUrl = $oAttDef->Get('default_image'); + if (is_object($oDocument) && !$oDocument->IsEmpty()) { + $sUrl = 'data:'.$oDocument->GetMimeType().';base64,'.base64_encode($oDocument->GetData()); + } else { + $sUrl = null; + } + + $sHTMLValue = "
\n"; + $sHTMLValue .= "{$sValidationSpan}{$sReloadSpan}\n"; + + $aEditImage = array( + 'input_name' => 'attr_'.$sFieldPrefix.$sAttCode.$sNameSuffix, + 'max_file_size' => utils::ConvertToBytes(ini_get('upload_max_filesize')), + 'max_width_px' => $oAttDef->Get('display_max_width'), + 'max_height_px' => $oAttDef->Get('display_max_height'), + 'current_image_url' => $sUrl, + 'default_image_url' => $sDefaultUrl, + 'labels' => array( + 'reset_button' => utils::EscapeHtml(Dict::S('UI:Button:ResetImage')), + 'remove_button' => utils::EscapeHtml(Dict::S('UI:Button:RemoveImage')), + 'upload_button' => !empty($sHelpText) ? $sHelpText : utils::EscapeHtml(Dict::S('UI:Button:UploadImage')), + ), + ); + $sEditImageOptions = json_encode($aEditImage); + $oPage->add_ready_script("$('#edit_$iInputId').edit_image($sEditImageOptions);"); + $oBlockValue= new Html($sHTMLValue); + break; + + case 'StopWatch': + $sHTMLValue = "The edition of a stopwatch is not allowed!!!"; + $oBlockValue= new Html($sHTMLValue); + break; + + case 'List': + // Not editable for now... + $sHTMLValue = ''; + $oBlockValue= new Html($sHTMLValue); + break; + + case 'One Way Password': + $sInputType = self::ENUM_INPUT_TYPE_PASSWORD; + $aEventsList[] = 'validate'; + $oWidget = new UIPasswordWidget($sAttCode, $iId, $sNameSuffix); + $sHTMLValue = $oWidget->Display($oPage, $aArgs); + // Event list & validation is handled directly by the widget + $oBlockValue= new Html($sHTMLValue); + break; + + case 'ExtKey': + /** @var \AttributeExternalKey $oAttDef */ + $aEventsList[] = 'validate'; + $aEventsList[] = 'change'; + + if ($bPreserveCurrentValue) { + $oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs, '', $value); + } else { + $oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs); + } + $sFieldName = $sFieldPrefix.$sAttCode.$sNameSuffix; + $aExtKeyParams = $aArgs; + $aExtKeyParams['iFieldSize'] = $oAttDef->GetMaxSize(); + $aExtKeyParams['iMinChars'] = $oAttDef->GetMinAutoCompleteChars(); + $sHTMLValue = UIExtKeyWidget::DisplayFromAttCode($oPage, $sAttCode, $sClass, $oAttDef->GetLabel(), + $oAllowedValues, $value, $iId, $bMandatory, $sFieldName, $sFormPrefix, $aExtKeyParams, false, $sInputType); + $sHTMLValue .= "\n"; + + $bHasExtKeyUpdatingRemoteClassFields = ( + array_key_exists('replaceDependenciesByRemoteClassFields', $aArgs) + && ($aArgs['replaceDependenciesByRemoteClassFields']) + ); + if ($bHasExtKeyUpdatingRemoteClassFields) { + // On this field update we need to update all the corresponding remote class fields + // Used when extkey widget is in a linkedset indirect + $sWizardHelperJsVarName = $aArgs['wizHelperRemote']; + $aDependencies = $aArgs['remoteCodes']; + } + $oBlockValue= new Html($sHTMLValue); + + break; + + case 'RedundancySetting': + $sHTMLValue .= '
'; + $sHTMLValue .= $oAttDef->GetDisplayForm($value, $oPage, true); + $sHTMLValue .= '
'; + $sHTMLValue .= '
'.$sValidationSpan.$sReloadSpan.'
'; + $oPage->add_ready_script("$('#$iId :input').on('keyup change validate', function(evt, sFormId) { return ValidateRedundancySettings('$iId',sFormId); } );"); // Custom validation function + $oBlockValue= new Html($sHTMLValue); + break; + + case 'CustomFields': + case 'FormField': + if ($sAttDefEditClass === 'CustomFields') { + /** @var \ormCustomFieldsValue $value */ + $oForm = $value->GetForm($sFormPrefix); + } else if ($sAttDefEditClass === 'FormField') { + $oForm = $oAttDef->GetForm($aArgs['this'], $sFormPrefix); + } + + $oFormRenderer = new ConsoleFormRenderer($oForm); + $aFormRenderedContent = $oFormRenderer->Render(); + + $aFieldSetOptions = array( + 'field_identifier_attr' => 'data-field-id', + // convention: fields are rendered into a div and are identified by this attribute + 'fields_list' => $aFormRenderedContent, + 'fields_impacts' => $oForm->GetFieldsImpacts(), + 'form_path' => $oForm->GetId(), + ); + $sFieldSetOptions = json_encode($aFieldSetOptions); + $aFormHandlerOptions = array( + 'wizard_helper_var_name' => 'oWizardHelper'.$sFormPrefix, + 'custom_field_attcode' => $sAttCode, + ); + $sFormHandlerOptions = json_encode($aFormHandlerOptions); + + $sHTMLValue .= '
'; + $sHTMLValue .= '
'; + $sHTMLValue .= '
'; + $sHTMLValue .= '
'.$sReloadSpan.'
'; // No validation span for this one: it does handle its own validation! + $sHTMLValue .= "\n"; $oPage->LinkScriptFromAppRoot('js/form_handler.js'); $oPage->LinkScriptFromAppRoot('js/console_form_handler.js'); $oPage->LinkScriptFromAppRoot('js/field_set.js'); $oPage->LinkScriptFromAppRoot('js/form_field.js'); $oPage->LinkScriptFromAppRoot('js/subform_field.js'); - $oPage->add_ready_script( - <<add_ready_script( + <<LinkScriptFromAppRoot('js/selectize.min.js'); $oPage->LinkStylesheetFromAppRoot('css/selectize.default.css'); $oPage->LinkScriptFromAppRoot('js/jquery.itop-set-widget.js'); - $oPage->add_dict_entry('Core:AttributeSet:placeholder'); - - /** @var \ormSet $value */ - $sJson = $oAttDef->GetJsonForWidget($value, $aArgs); - $sEscapedJson = utils::EscapeHtml($sJson); - $sSetInputName = "attr_{$sFormPrefix}{$sAttCode}"; - - // handle form validation - $aEventsList[] = 'change'; - $aEventsList[] = 'validate'; - $sNullValue = ''; - $sFieldToValidateId = $sFieldToValidateId.AttributeSet::EDITABLE_INPUT_ID_SUFFIX; - - // generate form HTML output - $sValidationSpan = ""; - $sHTMLValue = '
'.$sValidationSpan.$sReloadSpan; - $sScript = "$('#$iId').set_widget({inputWidgetIdSuffix: '".AttributeSet::EDITABLE_INPUT_ID_SUFFIX."'});"; - $oPage->add_ready_script($sScript); - - break; - - case 'String': - default: - $aEventsList[] = 'validate'; - // #@# todo - add context information (depending on dimensions) - $aAllowedValues = $oAttDef->GetAllowedValues($aArgs); - $iFieldSize = $oAttDef->GetMaxSize(); - if ($aAllowedValues !== null) - { - // Discrete list of values, use a SELECT or RADIO buttons depending on the config - $sDisplayStyle = $oAttDef->GetDisplayStyle(); - switch ($sDisplayStyle) - { - case 'radio': - case 'radio_horizontal': - case 'radio_vertical': - $sInputType = self::ENUM_INPUT_TYPE_RADIO; - $aEventsList[] = 'change'; - $sHTMLValue = "
"; - $bVertical = ($sDisplayStyle != 'radio_horizontal'); - $sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $iId, - "attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}", $bMandatory, $bVertical, ''); - $sHTMLValue .= "
{$sValidationSpan}{$sReloadSpan}\n"; - break; - - case 'select': - default: - $sInputType = self::ENUM_INPUT_TYPE_DROPDOWN_RAW; - $aEventsList[] = 'change'; - $sHTMLValue = "
'.$sValidationSpan.$sReloadSpan; + $sScript = "$('#$iId').set_widget({inputWidgetIdSuffix: '".AttributeSet::EDITABLE_INPUT_ID_SUFFIX."'});"; + $oPage->add_ready_script($sScript); + $oBlockValue= new Html($sHTMLValue); + + break; + + case 'String': + default: + $aEventsList[] = 'validate'; + // #@# todo - add context information (depending on dimensions) + $aAllowedValues = $oAttDef->GetAllowedValues($aArgs); + $iFieldSize = $oAttDef->GetMaxSize(); + if ($aAllowedValues !== null) + { + // Discrete list of values, use a SELECT or RADIO buttons depending on the config + $sDisplayStyle = $oAttDef->GetDisplayStyle(); + switch ($sDisplayStyle) + { + case 'radio': + case 'radio_horizontal': + case 'radio_vertical': + $sInputType = self::ENUM_INPUT_TYPE_RADIO; + $aEventsList[] = 'change'; + $sHTMLValue = "
"; + $bVertical = ($sDisplayStyle != 'radio_horizontal'); + $sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $iId, + "attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}", $bMandatory, $bVertical, ''); + $sHTMLValue .= "
{$sValidationSpan}{$sReloadSpan}\n"; + break; + + case 'select': + default: + $sInputType = self::ENUM_INPUT_TYPE_DROPDOWN_RAW; + $aEventsList[] = 'change'; + $sHTMLValue = "
{$sValidationSpan}{$sReloadSpan}\n"; - break; - } - } - else - { - $sInputType = self::ENUM_INPUT_TYPE_SINGLE_INPUT; - $sDisplayValueForHtml = utils::EscapeHtml($sDisplayValue); - - // Adding tooltip so we can read the whole value when its very long (eg. URL) + ); + } + $sSelected = ' selected'; + } else { + $sSelected = ($value == $key) ? ' selected' : ''; + } + $sHTMLValue .= "\n"; + } + $sHTMLValue .= "{$sValidationSpan}{$sReloadSpan}\n"; + break; + } + } + else + { + $sInputType = self::ENUM_INPUT_TYPE_SINGLE_INPUT; + $sDisplayValueForHtml = utils::EscapeHtml($sDisplayValue); + + // Adding tooltip so we can read the whole value when its very long (eg. URL) $sTip = ''; - if (!empty($sDisplayValue)) { - $sTip = 'data-tooltip-content="'.$sDisplayValueForHtml.'"'; - $oPage->add_ready_script(<<add_ready_script(<< {$sValidationSpan}{$sReloadSpan} HTML; - $aEventsList[] = 'keyup'; - $aEventsList[] = 'change'; + $aEventsList[] = 'keyup'; + $aEventsList[] = 'change'; - } - break; - } - $sPattern = addslashes($oAttDef->GetValidationPattern()); //'^([0-9]+)$'; - if (!empty($aEventsList)) - { - if (!is_numeric($sNullValue)) - { - $sNullValue = "'$sNullValue'"; // Add quotes to turn this into a JS string if it's not a number - } - $sOriginalValue = ($iFlags & OPT_ATT_MUSTCHANGE) ? json_encode($value) : 'undefined'; - $sEventList = implode(' ', $aEventsList); - $oPage->add_ready_script(<<GetValidationPattern()); //'^([0-9]+)$'; + if (!empty($aEventsList)) + { + if (!is_numeric($sNullValue)) + { + $sNullValue = "'$sNullValue'"; // Add quotes to turn this into a JS string if it's not a number + } + $sOriginalValue = ($iFlags & OPT_ATT_MUSTCHANGE) ? json_encode($value) : 'undefined'; + $sEventList = implode(' ', $aEventsList); + $oPage->add_ready_script(<< 0) - { - //--- Add an event handler to launch a custom event: validate - // * Unbind first to avoid duplicate event handlers in case of reload of the whole (or part of the) form - // * We were using off/on directly on the node before, but that was causing an issue when adding dynamically new nodes - // indeed the events weren't attached on the of the new nodes ! - // So we're adding the handler on a node above, and we're using a selector to catch only the event we're interested in ! - $sDependencies = implode("','", $aDependencies); + ); + } - $oPage->add_ready_script(<< 0) + { + //--- Add an event handler to launch a custom event: validate + // * Unbind first to avoid duplicate event handlers in case of reload of the whole (or part of the) form + // * We were using off/on directly on the node before, but that was causing an issue when adding dynamically new nodes + // indeed the events weren't attached on the of the new nodes ! + // So we're adding the handler on a node above, and we're using a selector to catch only the event we're interested in ! + $sDependencies = implode("','", $aDependencies); + + $oPage->add_ready_script(<<add_dict_entry('UI:ValueMustBeSet'); - $oPage->add_dict_entry('UI:ValueMustBeChanged'); - $oPage->add_dict_entry('UI:ValueInvalidFormat'); + ); + } + } + $oPage->add_dict_entry('UI:ValueMustBeSet'); + $oPage->add_dict_entry('UI:ValueMustBeChanged'); + $oPage->add_dict_entry('UI:ValueInvalidFormat'); + + // N°3750 refresh container data-input-type attribute if in an Ajax context + // indeed in such a case we're only returning the field value content and not the parent container, so we need to update it ! + if (utils::IsXmlHttpRequest()) { + // We are refreshing the data attribute only with the .attr() method + // So any consumer that want to get this attribute value MUST use `.attr()` and not `.data()` + // Actually the later uses a dedicated memory (that is initialized by the DOM values on page loading) + // Whereas `.attr()` uses the DOM directly + $oPage->add_init_script('$("[data-input-id=\''.$iId.'\']").attr("data-input-type", "'.$sInputType.'");'); + } + //TODO 3.0 remove the data-attcode attribute (either because it's has been moved to .field_container in 2.7 or even better because the admin. console has been reworked) + $oBlockEditContainer = UIContentBlockUIBlockFactory::MakeStandard(null, ['attribute-edit']); + $oBlockEditContainer->AddSubBlock($oBlockValue); - // N°3750 refresh container data-input-type attribute if in an Ajax context - // indeed in such a case we're only returning the field value content and not the parent container, so we need to update it ! - if (utils::IsXmlHttpRequest()) { - // We are refreshing the data attribute only with the .attr() method - // So any consumer that want to get this attribute value MUST use `.attr()` and not `.data()` - // Actually the later uses a dedicated memory (that is initialized by the DOM values on page loading) - // Whereas `.attr()` uses the DOM directly - $oPage->add_init_script('$("[data-input-id=\''.$iId.'\']").attr("data-input-type", "'.$sInputType.'");'); - } - //TODO 3.0 remove the data-attcode attribute (either because it's has been moved to .field_container in 2.7 or even better because the admin. console has been reworked) - return "
{$sHTMLValue}
"; - } + $oBlockContainer = UIContentBlockUIBlockFactory::MakeStandard('field_'.$iId, ['field_value_container']); + $oBlockContainer->AddSubBlock($oBlockEditContainer); + + return $oBlockContainer;//// "
{$sHTMLValue}
"; + + } /** * @param WebPage $oPage diff --git a/application/ui.linksdirectwidget.class.inc.php b/application/ui.linksdirectwidget.class.inc.php index 0fdbbd55d3..616a4683ee 100644 --- a/application/ui.linksdirectwidget.class.inc.php +++ b/application/ui.linksdirectwidget.class.inc.php @@ -90,6 +90,27 @@ public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrent return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock); } + /** + * @param WebPage $oPage + * @param $oValue + * @param $aArgs + * @param $sFormPrefix + * @param $oCurrentObj + * @return BlockIndirectLinkSetEditTable + * @throws ArchivedObjectException + * @throws ConfigException + * @throws CoreException + * @throws CoreUnexpectedValue + * @since 3.2 + */ + public function GetBlock(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj) + { + $oBlock = new BlockDirectLinkSetEditTable($this, $this->sInputid); + $oBlock->InitTable($oPage, $oValue, $sFormPrefix, $oCurrentObj); + + return $oBlock; + } + /** * @param WebPage $oPage * @param string $sProposedRealClass diff --git a/application/ui.linkswidget.class.inc.php b/application/ui.linkswidget.class.inc.php index 995d96df1c..453332b8f8 100644 --- a/application/ui.linkswidget.class.inc.php +++ b/application/ui.linkswidget.class.inc.php @@ -144,6 +144,27 @@ public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrent return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock); } + /** + * @param WebPage $oPage + * @param $oValue + * @param $aArgs + * @param $sFormPrefix + * @param $oCurrentObj + * @return BlockIndirectLinkSetEditTable + * @throws ArchivedObjectException + * @throws ConfigException + * @throws CoreException + * @throws CoreUnexpectedValue + * @since 3.2 + */ + public function GetBlock(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj): BlockIndirectLinkSetEditTable + { + $oBlock = new BlockIndirectLinkSetEditTable($this); + $oBlock->InitTable($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $this->m_aTableConfig); + + return $oBlock; + } + /** * @param WebPage $oPage * @param DBObject $oCurrentObj