From 50970810d26262ff0666d0669d7e2eb93119e0db Mon Sep 17 00:00:00 2001 From: Guillaume Lajarige Date: Mon, 15 May 2017 12:50:09 +0000 Subject: [PATCH] =?UTF-8?q?N=C2=B0635=20Portal:=20Forms=20now=20have=202?= =?UTF-8?q?=20differents=20layout=20(display=5Fmode),=20see=20online=20doc?= =?UTF-8?q?umentation=20(when=20released)=20for=20more=20information.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: This is a first step, some refactoring could be done soon. SVN:trunk[4735] --- .../objectcontroller.class.inc.php | 3 +- .../src/forms/objectformmanager.class.inc.php | 53 +++-- .../helpers/applicationhelper.class.inc.php | 12 +- .../views/bricks/object/mode_create.html.twig | 3 +- .../web/css/bootstrap-theme-combodo.css | 68 ++++-- .../web/css/bootstrap-theme-combodo.scss | 39 +++- .../portal/web/css/portal.css | 8 +- .../portal/web/css/portal.scss | 11 +- .../portal/web/css/variables.scss | 4 +- js/field_set.js | 24 +- sources/form/field/field.class.inc.php | 38 ++- .../bsselectobjectfieldrenderer.class.inc.php | 78 ++++--- .../bssimplefieldrenderer.class.inc.php | 216 +++++++++--------- sources/renderer/formrenderer.class.inc.php | 9 +- .../renderer/renderingoutput.class.inc.php | 91 +++++--- 15 files changed, 427 insertions(+), 230 deletions(-) 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 9d4552fa5..d5a6a76d9 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 @@ -1,6 +1,6 @@ GetRenderer(); $aFormData['object_name'] = $oFormManager->GetObject()->GetName(); $aFormData['fieldset'] = $aFieldSetData; + $aFormData['display_mode'] = (isset($aFormProperties['properties'])) ? $aFormProperties['properties']['display_mode'] : ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE; return $aFormData; } 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 9a39cd5d0..f14169f2b 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 @@ -1,10 +1,10 @@ sMode; $aJson['formactionrulestoken'] = $this->sActionRulesToken; $aJson['formproperties'] = $this->aFormProperties; - + return $aJson; } @@ -384,12 +385,20 @@ class ObjectFormManager extends FormManager { $oFieldNode->setAttribute('data-form-path', $oForm->GetId()); } - - // Checking if field should be displayed opened (For linked set) + // Checking if field should be displayed opened (For linked set) if($oFieldNode->hasAttribute('data-field-opened') && ($oFieldNode->getAttribute('data-field-opened') === 'true') ) { $aFieldsExtraData[$sFieldId]['opened'] = true; } + // Checking field display mode + if($oFieldNode->hasAttribute('data-field-display-mode') && $oFieldNode->getAttribute('data-field-display-mode') !== '') + { + $aFieldsExtraData[$sFieldId]['display_mode'] = $oFieldNode->getAttribute('data-field-display-mode'); + } + else + { + $aFieldsExtraData[$sFieldId]['display_mode'] = $this->aFormProperties['properties']['display_mode']; + } // Settings field flags from the data-field-flags attribute foreach (explode(' ', $sFieldFlags) as $sFieldFlag) @@ -436,7 +445,7 @@ class ObjectFormManager extends FormManager { $iFieldFlags = $this->oObject->GetAttributeFlags($sAttCode); } - + // Merging flags with those from the form definition // - only if the field if it's in fields list if (array_key_exists($sAttCode, $aFieldsAtts)) @@ -459,12 +468,12 @@ class ObjectFormManager extends FormManager foreach ($aFieldsAtts as $sAttCode => $iFieldFlags) { $oAttDef = MetaModel::GetAttributeDef(get_class($this->oObject), $sAttCode); - + // Failsafe for AttributeType that would not have MakeFormField and therefore could not be used in a form if (is_callable(get_class($oAttDef) . '::MakeFormField')) { $oField = $oAttDef->MakeFormField($this->oObject); - + if ($this->sMode !== static::ENUM_MODE_VIEW) { // Field dependencies @@ -510,7 +519,7 @@ class ObjectFormManager extends FormManager { // Normal field } - + // Specific operation on field // - Field that require a transaction id if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\TextAreaField', 'Combodo\\iTop\\Form\\Field\\CaseLogField'))) @@ -546,7 +555,7 @@ class ObjectFormManager extends FormManager if ($this->oApp !== null) { $oScopeOriginal = ($oField->GetSearch() !== null) ? $oField->GetSearch() : DBSearch::FromOQL($oAttDef->GetValuesDef()->GetFilterExpression()); - + $oScopeSearch = $this->oApp['scope_validator']->GetScopeFilterForProfiles(UserRights::ListProfiles(), $oScopeOriginal->GetClass(), UR_ACTION_READ); if ($oScopeSearch === null) { @@ -638,8 +647,6 @@ class ObjectFormManager extends FormManager $oField->SetDisplayOpened(true); } } - - $oForm->AddField($oField); } else { @@ -648,10 +655,18 @@ class ObjectFormManager extends FormManager ->SetHidden(false) ->SetCurrentValue(get_class($oAttDef) . ' : Sorry, that AttributeType is not implemented yet.') ->SetLabel($oAttDef->GetLabel()); - $oForm->AddField($oField); } + + // Setting field display mode + if(array_key_exists($sAttCode, $aFieldsExtraData) && array_key_exists('display_mode', $aFieldsExtraData[$sAttCode])) + { + $sFieldDisplayMode = ($aFieldsExtraData[$sAttCode]['display_mode'] === ApplicationHelper::FORM_ENUM_DISPLAY_MODE_COSY) ? Field::ENUM_DISPLAY_MODE_VERTICAL : Field::ENUM_DISPLAY_MODE_HORIZONTAL; + $oField->SetDisplayMode($sFieldDisplayMode); + } + + $oForm->AddField($oField); } - + // Checking dependencies to ensure that all needed fields are in the form // (This is kind of a garbage collector for dependancies) foreach ($oForm->GetDependencies() as $sImpactedFieldId => $aDependancies) @@ -663,7 +678,7 @@ class ObjectFormManager extends FormManager $oAttDef = MetaModel::GetAttributeDef(get_class($this->oObject), $sDependancyFieldId); $oField = $oAttDef->MakeFormField($this->oObject); $oField->SetHidden(true); - + $oForm->AddField($oField); } } @@ -683,7 +698,7 @@ class ObjectFormManager extends FormManager break; } } - + // Adding attachment field if ($bClassAllowed) { @@ -916,7 +931,7 @@ class ObjectFormManager extends FormManager $aData['valid'] = false; $aData['messages']['error'] += $this->oForm->GetErrorMessages(); } - + return $aData; } @@ -1036,7 +1051,7 @@ class ObjectFormManager extends FormManager } $this->oObject->DoComputeValues(); } - + // Then we retrieve properties of the form to build if (isset($aArgs['formProperties'])) { diff --git a/datamodels/2.x/itop-portal-base/portal/src/helpers/applicationhelper.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/helpers/applicationhelper.class.inc.php index 5c9c9a9ae..113339cef 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/helpers/applicationhelper.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/helpers/applicationhelper.class.inc.php @@ -1,6 +1,6 @@ false, + 'display_mode' => static::FORM_DEFAULT_DISPLAY_MODE, + 'always_show_submit' => static::FORM_DEFAULT_ALWAYS_SHOW_SUBMIT, ); if($oFormNode->GetOptionalElement('properties') !== null) { @@ -861,6 +866,9 @@ class ApplicationHelper { switch($oPropertyNode->nodeName) { + case 'display_mode': + $aFormProperties['display_mode'] = $oPropertyNode->GetText(static::FORM_DEFAULT_DISPLAY_MODE); + break; case 'always_show_submit': $aFormProperties['always_show_submit'] = ($oPropertyNode->GetText('false') === 'true') ? true : false; break; diff --git a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_create.html.twig b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_create.html.twig index 17375c1a7..f3c74e39a 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_create.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_create.html.twig @@ -2,10 +2,11 @@ {# Object brick create layout #} {% set sFormId = (form.id is defined and form.id is not null) ? form.id : 'object_form' %} +{% set sFormClass = (form.display_mode is defined and form.display_mode is not null) ? 'form_' ~ form.display_mode : '' %} {% set sFormIdSanitized = sFormId|replace({'-': ''}) %} {% set tIsModal = (tIsModal is defined and tIsModal == true) ? true : false %} -
+
{% block pFormAlerts %} diff --git a/datamodels/2.x/itop-portal-base/portal/web/css/bootstrap-theme-combodo.css b/datamodels/2.x/itop-portal-base/portal/web/css/bootstrap-theme-combodo.css index 716f70391..76412054b 100644 --- a/datamodels/2.x/itop-portal-base/portal/web/css/bootstrap-theme-combodo.css +++ b/datamodels/2.x/itop-portal-base/portal/web/css/bootstrap-theme-combodo.css @@ -66,7 +66,7 @@ img { height: auto; } .img-rounded { - border-radius: 6px; + border-radius: 0px; } .img-thumbnail { padding: 4px; @@ -375,7 +375,7 @@ kbd { font-size: 90%; color: #fff; background-color: #333; - border-radius: 3px; + border-radius: 0px; -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); } @@ -1388,7 +1388,7 @@ input[type="radio"][disabled], input[type="checkbox"][disabled], input[type="rad padding: 5px 10px; font-size: 12px; line-height: 1.5; - border-radius: 3px; + border-radius: 0px; } select.input-sm { height: 30px; @@ -1402,7 +1402,7 @@ textarea.input-sm, select[multiple].input-sm { padding: 5px 10px; font-size: 12px; line-height: 1.5; - border-radius: 3px; + border-radius: 0px; } .form-group-sm select.form-control { height: 30px; @@ -1423,7 +1423,7 @@ textarea.input-sm, select[multiple].input-sm { padding: 14px 16px; font-size: 17px; line-height: 1.33333; - border-radius: 6px; + border-radius: 0px; } select.input-lg { height: 53px; @@ -1437,7 +1437,7 @@ textarea.input-lg, select[multiple].input-lg { padding: 14px 16px; font-size: 17px; line-height: 1.33333; - border-radius: 6px; + border-radius: 0px; } .form-group-lg select.form-control { height: 53px; @@ -1906,19 +1906,19 @@ a.btn.disabled, fieldset[disabled] a.btn { padding: 14px 16px; font-size: 17px; line-height: 1.33333; - border-radius: 6px; + border-radius: 0px; } .btn-sm, .btn-group-sm > .btn { padding: 5px 10px; font-size: 12px; line-height: 1.5; - border-radius: 3px; + border-radius: 0px; } .btn-xs, .btn-group-xs > .btn { padding: 1px 5px; font-size: 12px; line-height: 1.5; - border-radius: 3px; + border-radius: 0px; } .btn-block { display: block; @@ -2271,7 +2271,7 @@ tbody.collapse.in { padding: 14px 16px; font-size: 17px; line-height: 1.33333; - border-radius: 6px; + border-radius: 0px; } select.input-group-lg > .form-control, select.input-group-lg > .input-group-addon, select.input-group-lg > .input-group-btn > .btn { height: 53px; @@ -2285,7 +2285,7 @@ textarea.input-group-lg > .form-control, textarea.input-group-lg > .input-group- padding: 5px 10px; font-size: 12px; line-height: 1.5; - border-radius: 3px; + border-radius: 0px; } select.input-group-sm > .form-control, select.input-group-sm > .input-group-addon, select.input-group-sm > .input-group-btn > .btn { height: 30px; @@ -2313,18 +2313,18 @@ textarea.input-group-sm > .form-control, textarea.input-group-sm > .input-group- color: #777; text-align: center; background-color: #ddd; - border: 1px solid #ddd; + border: 1px solid #c7c7c7; border-radius: 0px; } .input-group-addon.input-sm { padding: 5px 10px; font-size: 12px; - border-radius: 3px; + border-radius: 0px; } .input-group-addon.input-lg { padding: 14px 16px; font-size: 17px; - border-radius: 6px; + border-radius: 0px; } .input-group-addon input[type="radio"], .input-group-addon input[type="checkbox"] { margin-top: 0; @@ -3334,7 +3334,7 @@ a.badge:hover, a.badge:focus { border-top-color: #dbdbdb; } .container .jumbotron, .container-fluid .jumbotron { - border-radius: 6px; + border-radius: 0px; } .jumbotron .container { max-width: 100%; @@ -4022,11 +4022,11 @@ a.list-group-item-danger.active, button.list-group-item-danger.active, a.list-gr } .well-lg { padding: 24px; - border-radius: 6px; + border-radius: 0px; } .well-sm { padding: 9px; - border-radius: 3px; + border-radius: 0px; } .close { float: right; @@ -4324,7 +4324,7 @@ button.close { background-clip: padding-box; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; + border-radius: 0px; -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); } @@ -4929,7 +4929,37 @@ label { box-shadow: -1px 1px 2px rgba(0, 0, 0, 0.4); } /* Help blocks in forms */ -.form_fields .form-group > .help-block { +.form_fields .form-group .help-block { margin-top: 0px; margin-bottom: 0px; } +/* Overriding Twitter Typeahead */ +.input-group span.twitter-typeahead { + height: initial; +} +.input-group span.twitter-typeahead:first-child .form-control, .input-group span.twitter-typeahead:last-child .form-control, .input-group span.twitter-typeahead .form-control { + border-radius: 0px; +} +.input-group span.twitter-typeahead .tt-suggestion.tt-cursor, .input-group span.twitter-typeahead .tt-suggestion:hover, .input-group span.twitter-typeahead .tt-suggestion:focus { + color: #fff; + background-color: #ea7d1e; +} +/* Compact form display */ +.form_compact .form-group.form_group_small { + margin-bottom: 10px; +} +.form_compact .form-group.form_group_small .control-label { + margin-right: 0.5em; +} +.form_compact .form-group.form_group_small .form-control-static { + display: inline; +} +.form_compact .form-group.form_group_small .form-control { + height: 28px; + padding: 4px 5px; + font-size: 12px; +} +.form_compact .form-group.form_group_small .input-group-addon { + padding: 4px 10px; + font-size: 12px; +} diff --git a/datamodels/2.x/itop-portal-base/portal/web/css/bootstrap-theme-combodo.scss b/datamodels/2.x/itop-portal-base/portal/web/css/bootstrap-theme-combodo.scss index 027b67f1e..e1df30caf 100644 --- a/datamodels/2.x/itop-portal-base/portal/web/css/bootstrap-theme-combodo.scss +++ b/datamodels/2.x/itop-portal-base/portal/web/css/bootstrap-theme-combodo.scss @@ -2995,7 +2995,7 @@ select[multiple].input-group-sm>.input-group-btn>.btn { color: $gray; text-align: center; background-color: #dddddd; - border: 1px solid #dddddd; + border: 1px solid #c7c7c7; border-radius: $border-radius-base } .input-group-addon.input-sm { @@ -6012,7 +6012,42 @@ label { box-shadow: -1px 1px 2px rgba(0, 0, 0, 0.4); } /* Help blocks in forms */ -.form_fields .form-group > .help-block{ +.form_fields .form-group .help-block{ margin-top: 0px; margin-bottom: 0px; +} +/* Overriding Twitter Typeahead */ +.input-group span.twitter-typeahead{ + height: initial; +} +.input-group span.twitter-typeahead:first-child .form-control, +.input-group span.twitter-typeahead:last-child .form-control, +.input-group span.twitter-typeahead .form-control{ + border-radius: $border-radius-base; +} +.input-group span.twitter-typeahead .tt-suggestion.tt-cursor, +.input-group span.twitter-typeahead .tt-suggestion:hover, +.input-group span.twitter-typeahead .tt-suggestion:focus{ + color: $btn-primary-color; + background-color: $btn-primary-bg; +} +/* Compact form display */ +.form_compact .form-group.form_group_small{ + margin-bottom: 10px; + + .control-label{ + margin-right: 0.5em; + } + .form-control-static{ + display: inline; + } + .form-control{ + height: 28px; + padding: 4px 5px; + font-size: 12px; + } + .input-group-addon { + padding: 4px 10px; + font-size: 12px; + } } \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/web/css/portal.css b/datamodels/2.x/itop-portal-base/portal/web/css/portal.css index 567cded40..9cb52c4b2 100644 --- a/datamodels/2.x/itop-portal-base/portal/web/css/portal.css +++ b/datamodels/2.x/itop-portal-base/portal/web/css/portal.css @@ -258,10 +258,6 @@ footer { padding-right: 0px; /* To align all actions on the right without indent */ } -/* Custom "glyphicons" */ -.glyphicon-ext-hierarchy:before { - content: url('../img/icons/hierarchy-white-13px.png'); -} /******************/ /* Modal settings */ /******************/ @@ -853,6 +849,10 @@ table .group-actions { color: #ea7d1e; font-size: 0.9em; } +/* ExternalKey */ +.selectobject .input-group-addon { + cursor: pointer; +} /* InlineImage */ .inline-image { cursor: pointer; diff --git a/datamodels/2.x/itop-portal-base/portal/web/css/portal.scss b/datamodels/2.x/itop-portal-base/portal/web/css/portal.scss index 81cf77781..4623727cf 100644 --- a/datamodels/2.x/itop-portal-base/portal/web/css/portal.scss +++ b/datamodels/2.x/itop-portal-base/portal/web/css/portal.scss @@ -272,11 +272,6 @@ footer{ padding-right: 0px; /* To align all actions on the right without indent */ } -/* Custom "glyphicons" */ -.glyphicon-ext-hierarchy:before { - content: url('../img/icons/hierarchy-white-13px.png'); -} - /******************/ /* Modal settings */ /******************/ @@ -920,6 +915,10 @@ table .group-actions .item-action-wrapper .panel-body > p:last-child{ color: $brand-primary; font-size: 0.9em; } +/* ExternalKey */ +.selectobject .input-group-addon{ + cursor: pointer; +} /* InlineImage */ .inline-image{ cursor: pointer; @@ -1242,4 +1241,4 @@ table .group-actions .item-action-wrapper .panel-body > p:last-child{ /* Wiki text (hyperlinks) */ .wiki_broken_link { text-decoration: line-through; -} \ No newline at end of file +} diff --git a/datamodels/2.x/itop-portal-base/portal/web/css/variables.scss b/datamodels/2.x/itop-portal-base/portal/web/css/variables.scss index 81230df8e..fe6ea3737 100644 --- a/datamodels/2.x/itop-portal-base/portal/web/css/variables.scss +++ b/datamodels/2.x/itop-portal-base/portal/web/css/variables.scss @@ -130,8 +130,8 @@ $line-height-large: 1.3333333 !default; // extra decimals for Win 8.1 Ch $line-height-small: 1.5 !default; $border-radius-base: 0px !default; -$border-radius-large: 6px !default; -$border-radius-small: 3px !default; +$border-radius-large: $border-radius-base; // Default: 6px !default; +$border-radius-small: $border-radius-base; // Default: 3px !default; //** Global color for active items (e.g., navs or dropdowns). $component-active-color: #fff !default; diff --git a/js/field_set.js b/js/field_set.js index 02d1d899f..92e3e45bb 100644 --- a/js/field_set.js +++ b/js/field_set.js @@ -279,14 +279,22 @@ $(function() this._loadJsFile(oField.js_files[i]); } } - // CSS files - if( (oField.css_files !== undefined) && (oField.css_files.length > 0) ) - { - for(var i in oField.css_files) - { - this._loadCssFile(oField.css_files[i]); - } - } + // CSS files + if( (oField.css_files !== undefined) && (oField.css_files.length > 0) ) + { + for(var i in oField.css_files) + { + this._loadCssFile(oField.css_files[i]); + } + } + // CSS classes + if( (oField.css_classes !== undefined) && (oField.css_classes.length > 0) ) + { + for(var i in oField.css_classes) + { + oFieldContainer.addClass(oField.css_classes[i]); + } + } // JS inline if( (oField.js_inline !== undefined) && (oField.js_inline !== '') ) { diff --git a/sources/form/field/field.class.inc.php b/sources/form/field/field.class.inc.php index eb9ce9d35..aabed9852 100644 --- a/sources/form/field/field.class.inc.php +++ b/sources/form/field/field.class.inc.php @@ -1,6 +1,6 @@ bHidden = static::DEFAULT_HIDDEN; $this->bReadOnly = static::DEFAULT_READ_ONLY; $this->bMandatory = static::DEFAULT_MANDATORY; + $this->sDisplayMode = static::DEFAULT_DISPLAY_MODE; $this->aValidators = array(); $this->bValid = static::DEFAULT_VALID; $this->aErrorMessages = array(); @@ -136,6 +142,15 @@ abstract class Field return $this->bMandatory; } + /** + * + * @return string + */ + public function GetDisplayMode() + { + return $this->sDisplayMode; + } + /** * * @return array @@ -256,6 +271,17 @@ abstract class Field return $this; } + /** + * + * @param $sDisplayMode + * @return $this + */ + public function SetDisplayMode($sDisplayMode) + { + $this->sDisplayMode = $sDisplayMode; + return $this; + } + /** * * @param array $aValidators @@ -364,6 +390,16 @@ abstract class Field return $this; } + /** + * Returns if the field should be displayed horizontally (label and value side by side) + * + * @return bool + */ + public function IsHorizontalDisplayMode() + { + return $this->sDisplayMode === static::ENUM_DISPLAY_MODE_HORIZONTAL; + } + /** * Returns if the field is editable. Meaning that it is not editable nor hidden. * diff --git a/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php b/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php index e9b2d4470..7cf41c03a 100644 --- a/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php +++ b/sources/renderer/bootstrap/fieldrenderer/bsselectobjectfieldrenderer.class.inc.php @@ -50,6 +50,7 @@ class BsSelectObjectFieldRenderer extends FieldRenderer $oOutput = new RenderingOutput(); $sFieldValueClass = $this->oField->GetSearch()->GetClass(); $sFieldMandatoryClass = ($this->oField->GetMandatory()) ? 'form_mandatory' : ''; + $sFieldContainerClass = ($this->oField->IsHorizontalDisplayMode() && !$this->oField->GetHidden()) ? 'row' : ''; $iFieldControlType = $this->oField->GetControlType(); // TODO : Remove this when hierarchical search supported @@ -59,11 +60,19 @@ class BsSelectObjectFieldRenderer extends FieldRenderer if (!$this->oField->GetReadOnly() && !$this->oField->GetHidden()) { // Rendering field - $oOutput->AddHtml('
'); + // - Opening container + $oOutput->AddHtml('
'); + + // Label + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } if ($this->oField->GetLabel() !== '') { $oOutput->AddHtml(''); } + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + + // Value + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } $oOutput->AddHtml('
'); // - As a select // TODO : This should be changed when we do the radio button display. For now we display everything with select @@ -77,7 +86,7 @@ class BsSelectObjectFieldRenderer extends FieldRenderer // Note : Autocomplete/Search is disabled for template fields as they are not external keys, thus they will just be displayed as regular select. $bRegularSelect = ( ($iSetCount <= $this->oField->GetMaximumComboLength()) || ($this->oField->GetSearchEndpoint() === null) || ($this->oField->GetSearchEndpoint() === '') ); unset($oCountSet); - +$bRegularSelect=false; // - For regular select if ($bRegularSelect) { @@ -158,24 +167,18 @@ EOF } // HTML for autocomplete part - // - Opening row - $oOutput->AddHtml('
'); - // - Rendering autocomplete search - $oOutput->AddHtml('
'); - $oOutput->AddHtml(''); - $oOutput->AddHtml(''); - $oOutput->AddHtml('
'); - // - Rendering buttons - $oOutput->AddHtml('
'); - $oOutput->AddHtml('
'); - // - Rendering hierarchy button - $this->RenderHierarchicalSearch($oOutput); - // - Rendering regular search - $this->RenderRegularSearch($oOutput); - $oOutput->AddHtml('
'); - $oOutput->AddHtml('
'); - // - Closing row - $oOutput->AddHtml('
'); + // - Opening input group + $oOutput->AddHtml('
'); + // - Rendering autocomplete search + $oOutput->AddHtml(''); + $oOutput->AddHtml(''); + // - Rendering buttons + // - Rendering hierarchy button + $this->RenderHierarchicalSearch($oOutput); + // - Rendering regular search + $this->RenderRegularSearch($oOutput); + // - Closing input group + $oOutput->AddHtml('
'); // JS FieldChange trigger (:input are not always at the same depth) // Note : Not used for that field type @@ -296,6 +299,9 @@ EOF ); } } + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + + // - Closing container $oOutput->AddHtml('
'); } // ... and in read-only mode (or hidden) @@ -313,19 +319,31 @@ EOF $sFieldValue = Dict::S('UI:UndefinedObject'); } - $oOutput->AddHtml('
'); + // Opening container + $oOutput->AddHtml('
'); + // Showing label / value only if read-only but not hidden if (!$this->oField->GetHidden()) { + // Label + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } if ($this->oField->GetLabel() !== '') { $oOutput->AddHtml(''); } - $oOutput->AddHtml('
' . $sFieldValue . '
'); - } - $oOutput->AddHtml(''); - $oOutput->AddHtml('
'); + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + // Value + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + $oOutput->AddHtml('
' . $sFieldValue . '
'); + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + } + + // Adding hidden value + $oOutput->AddHtml(''); + + // Closing container + $oOutput->AddHtml('
'); // JS FieldChange trigger (:input are not always at the same depth) $oOutput->AddJs( @@ -362,12 +380,12 @@ EOF */ protected function RenderHierarchicalSearch(RenderingOutput &$oOutput) { - if ($this->oField->GetHierarchical()) - { + if ($this->oField->GetHierarchical()) + { $sHierarchicalButtonId = 's_hi_' . $this->oField->GetGlobalId(); $sEndpoint = str_replace('-sMode-', 'hierarchy', $this->oField->GetSearchEndpoint()); - $oOutput->AddHtml(''); + $oOutput->AddHtml('
'); $oOutput->AddJs( <<oField->GetGlobalId(); $sEndpoint = str_replace('-sMode-', 'from-attribute', $this->oField->GetSearchEndpoint()); - $oOutput->AddHtml(''); - + $oOutput->AddHtml('
'); + $oOutput->AddJs( <<oField); $sFieldMandatoryClass = ($this->oField->GetMandatory()) ? 'form_mandatory' : ''; + $sFieldContainerClass = ($this->oField->IsHorizontalDisplayMode() && !$this->oField->GetHidden()) ? 'row' : ''; // Rendering field in edition mode if (!$this->oField->GetReadOnly() && !$this->oField->GetHidden()) { switch ($sFieldClass) { - case 'Combodo\\iTop\\Form\\Field\\DateTimeField': - $oOutput->AddHtml('
'); - if ($this->oField->GetLabel() !== '') - { - $oOutput->AddHtml(''); - } - $oOutput->AddHtml('
'); - $oOutput->AddHtml('
'); - $oOutput->AddHtml(''); - $oOutput->AddHtml(''); - $oOutput->AddHtml('
'); - $oOutput->AddHtml('
'); - $sJSFormat = json_encode($this->oField->GetJSDateTimeFormat()); - $oOutput->AddJs( -<<oField->GetGlobalId()}').datetimepicker({format: $sJSFormat}); -EOF - ); - break; - case 'Combodo\\iTop\\Form\\Field\\PasswordField': - $oOutput->AddHtml('
'); - if ($this->oField->GetLabel() !== '') - { - $oOutput->AddHtml(''); - } - $oOutput->AddHtml('
'); - $oOutput->AddHtml(''); - $oOutput->AddHtml('
'); - break; - - case 'Combodo\\iTop\\Form\\Field\\StringField': + case 'Combodo\\iTop\\Form\\Field\\DateTimeField': + case 'Combodo\\iTop\\Form\\Field\\PasswordField': + case 'Combodo\\iTop\\Form\\Field\\StringField': case 'Combodo\\iTop\\Form\\Field\\UrlField': - $oOutput->AddHtml('
'); - if ($this->oField->GetLabel() !== '') - { - $oOutput->AddHtml(''); - } - $oOutput->AddHtml('
'); - $oOutput->AddHtml(''); - $oOutput->AddHtml('
'); - break; + case 'Combodo\\iTop\\Form\\Field\\SelectField': + case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField': + // Opening container + $oOutput->AddHtml('
'); + + // Label + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + if ($this->oField->GetLabel() !== '') + { + $oOutput->AddHtml(''); + } + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + + // Value + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + // - Help block + $oOutput->AddHtml('
'); + // - Value regarding the field type + switch($sFieldClass) + { + case 'Combodo\\iTop\\Form\\Field\\DateTimeField': + $oOutput->AddHtml('
'); + $oOutput->AddHtml(''); + $oOutput->AddHtml(''); + $oOutput->AddHtml('
'); + $sJSFormat = json_encode($this->oField->GetJSDateTimeFormat()); + $oOutput->AddJs( + <<oField->GetGlobalId()}').datetimepicker({format: $sJSFormat}); +EOF + ); + break; + + case 'Combodo\\iTop\\Form\\Field\\PasswordField': + $oOutput->AddHtml(''); + break; + + case 'Combodo\\iTop\\Form\\Field\\StringField': + case 'Combodo\\iTop\\Form\\Field\\UrlField': + $oOutput->AddHtml(''); + break; + + case 'Combodo\\iTop\\Form\\Field\\SelectField': + case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField': + $oOutput->AddHtml(''); + break; + } + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + + // Closing container + $oOutput->AddHtml('
'); + break; case 'Combodo\\iTop\\Form\\Field\\TextAreaField': case 'Combodo\\iTop\\Form\\Field\\CaseLogField': $bRichEditor = ($this->oField->GetFormat() === TextAreaField::ENUM_FORMAT_HTML); - + $oOutput->AddHtml('
'); if ($this->oField->GetLabel() !== '') { @@ -133,25 +156,6 @@ EOF } break; - case 'Combodo\\iTop\\Form\\Field\\SelectField': - case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField': - $oOutput->AddHtml('
'); - if ($this->oField->GetLabel() !== '') - { - $oOutput->AddHtml(''); - } - $oOutput->AddHtml('
'); - $oOutput->AddHtml(''); - $oOutput->AddHtml('
'); - break; - case 'Combodo\\iTop\\Form\\Field\\RadioField': case 'Combodo\\iTop\\Form\\Field\\CheckboxField': $sFieldType = ($sFieldClass === 'Combodo\\iTop\\Form\\Field\\RadioField') ? 'radio' : 'checkbox'; @@ -198,21 +202,42 @@ EOF switch ($sFieldClass) { case 'Combodo\\iTop\\Form\\Field\\LabelField': - $oOutput->AddHtml('
'); + case 'Combodo\\iTop\\Form\\Field\\StringField': + case 'Combodo\\iTop\\Form\\Field\\UrlField': + case 'Combodo\\iTop\\Form\\Field\\DateTimeField': + case 'Combodo\\iTop\\Form\\Field\\DurationField': + // Opening container + $oOutput->AddHtml('
'); + // Showing label / value only if read-only but not hidden if (!$this->oField->GetHidden()) { + // Label + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } if ($this->oField->GetLabel() !== '') { $oOutput->AddHtml(''); } - $oOutput->AddHtml('
')->AddHtml($this->oField->GetCurrentValue(), true)->AddHtml('
'); + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + + // Value + $bEncodeHtmlEntities = ($sFieldClass === 'Combodo\\iTop\\Form\\Field\\UrlField') ? false : true; + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + $oOutput->AddHtml('
')->AddHtml($this->oField->GetDisplayValue(), $bEncodeHtmlEntities)->AddHtml('
'); + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } } + + // Adding hidden input if not a label + if($sFieldClass !== 'Combodo\\iTop\\Form\\Field\\LabelField') + { + $sValueForInput = ($sFieldClass === 'Combodo\\iTop\\Form\\Field\\DateTimeField') ? $this->oField->GetDisplayValue() : $this->oField->GetCurrentValue(); + $oOutput->AddHtml(''); + } + + // Closing container $oOutput->AddHtml('
'); break; - case 'Combodo\\iTop\\Form\\Field\\StringField': - case 'Combodo\\iTop\\Form\\Field\\UrlField': case 'Combodo\\iTop\\Form\\Field\\TextAreaField': $oOutput->AddHtml('
'); // Showing label / value only if read-only but not hidden @@ -223,18 +248,10 @@ EOF $oOutput->AddHtml(''); } - if($sFieldClass === 'Combodo\\iTop\\Form\\Field\\UrlField' || $sFieldClass === 'Combodo\\iTop\\Form\\Field\\TextAreaField') - { - $bEncodeHtmlEntities = false; - $sDisplayValue = $this->oField->GetDisplayValue(); - } - else - { - $bEncodeHtmlEntities = true; - $sDisplayValue = $this->oField->GetCurrentValue(); - } - $oOutput->AddHtml('
')->AddHtml($sDisplayValue, $bEncodeHtmlEntities)->AddHtml('
'); + + $oOutput->AddHtml('
')->AddHtml($this->oField->GetDisplayValue(), false)->AddHtml('
'); } + // Adding hidden input $oOutput->AddHtml(''); $oOutput->AddHtml('
'); break; @@ -250,37 +267,7 @@ EOF $oOutput->AddHtml('
'); break; - case 'Combodo\\iTop\\Form\\Field\\DateTimeField': - $oOutput->AddHtml('
'); - // Showing label / value only if read-only but not hidden - if (!$this->oField->GetHidden()) - { - if ($this->oField->GetLabel() !== '') - { - $oOutput->AddHtml(''); - } - $oOutput->AddHtml('
')->AddHtml($this->oField->GetDisplayValue(), true)->AddHtml('
'); - } - $oOutput->AddHtml(''); - $oOutput->AddHtml('
'); - break; - - case 'Combodo\\iTop\\Form\\Field\\DurationField': - $oOutput->AddHtml('
'); - // Showing label / value only if read-only but not hidden - if (!$this->oField->GetHidden()) - { - if ($this->oField->GetLabel() !== '') - { - $oOutput->AddHtml(''); - } - $oOutput->AddHtml('
')->AddHtml($this->oField->GetDisplayValue(), true)->AddHtml('
'); - } - $oOutput->AddHtml(''); - $oOutput->AddHtml('
'); - break; - - case 'Combodo\\iTop\\Form\\Field\\BlobField': + case 'Combodo\\iTop\\Form\\Field\\BlobField': case 'Combodo\\iTop\\Form\\Field\\ImageField': $oOutput->AddHtml('
'); // Showing label / value only if read-only but not hidden @@ -311,17 +298,30 @@ EOF $aFieldChoices = $this->oField->GetChoices(); $sFieldValue = (isset($aFieldChoices[$this->oField->GetCurrentValue()])) ? $aFieldChoices[$this->oField->GetCurrentValue()] : Dict::S('UI:UndefinedObject'); - $oOutput->AddHtml('
'); + // Opening container + $oOutput->AddHtml('
'); + // Showing label / value only if read-only but not hidden if (!$this->oField->GetHidden()) { + // Label + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } if ($this->oField->GetLabel() !== '') { $oOutput->AddHtml(''); } + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } + + // Value + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } $oOutput->AddHtml('
' . $sFieldValue . '
'); + if($this->oField->IsHorizontalDisplayMode()){ $oOutput->AddHtml('
'); } } + + // Adding hidden value $oOutput->AddHtml(''); + + // Closing container $oOutput->AddHtml('
'); break; diff --git a/sources/renderer/formrenderer.class.inc.php b/sources/renderer/formrenderer.class.inc.php index 6056dc2ad..58f179b9f 100644 --- a/sources/renderer/formrenderer.class.inc.php +++ b/sources/renderer/formrenderer.class.inc.php @@ -223,11 +223,13 @@ abstract class FormRenderer 'js_inline' => '', 'css_inline' => '', 'js_files' => array(), - 'css_files' => array() + 'css_files' => array(), + 'css_classes' => array(), ); $sFieldRendererClass = $this->GetFieldRendererClass($oField); + /** @var FieldRenderer $oFieldRenderer */ $oFieldRenderer = new $sFieldRendererClass($oField); $oFieldRenderer->SetEndpoint($this->GetEndpoint()); @@ -301,6 +303,11 @@ abstract class FormRenderer $output['html'] .= ''; } } + // CSS classes + if ($oRenderingOutput->GetHtml() !== '') + { + $output['css_classes'] = $oRenderingOutput->GetCssClasses(); + } return $output; } diff --git a/sources/renderer/renderingoutput.class.inc.php b/sources/renderer/renderingoutput.class.inc.php index 63d195177..db92c5f62 100644 --- a/sources/renderer/renderingoutput.class.inc.php +++ b/sources/renderer/renderingoutput.class.inc.php @@ -31,6 +31,7 @@ class RenderingOutput protected $aJsFiles; protected $sCssInline; protected $aCssFiles; + protected $aCssClasses; public function __construct() { @@ -39,6 +40,7 @@ class RenderingOutput $this->aJsFiles = array(); $this->sCssInline = ''; $this->aCssFiles = array(); + $this->aCssClasses = array(); } /** @@ -86,6 +88,15 @@ class RenderingOutput return $this->aCssFiles; } + /** + * + * @return array + */ + public function GetCssClasses() + { + return $this->aCssClasses; + } + /** * * @param string $sHtml @@ -147,32 +158,60 @@ class RenderingOutput return $this; } - /** - * - * @param string $sFile - * @return \Combodo\iTop\Renderer\RenderingOutput - */ - public function AddCssFile($sFile) - { - if (!in_array($sFile, $this->aCssFiles)) - { - $this->aCssFiles[] = $sFile; - } - return $this; - } + /** + * + * @param string $sFile + * @return \Combodo\iTop\Renderer\RenderingOutput + */ + public function AddCssFile($sFile) + { + if (!in_array($sFile, $this->aCssFiles)) + { + $this->aCssFiles[] = $sFile; + } + return $this; + } - /** - * - * @param string $sFile - * @return \Combodo\iTop\Renderer\RenderingOutput - */ - public function RemoveCssFile($sFile) - { - if (in_array($sFile, $this->aCssFiles)) - { - unset($this->aCssFiles[$sFile]); - } - return $this; - } + /** + * + * @param string $sFile + * @return \Combodo\iTop\Renderer\RenderingOutput + */ + public function RemoveCssFile($sFile) + { + if (in_array($sFile, $this->aCssFiles)) + { + unset($this->aCssFiles[$sFile]); + } + return $this; + } + + /** + * + * @param string $sClass + * @return \Combodo\iTop\Renderer\RenderingOutput + */ + public function AddCssClass($sClass) + { + if (!in_array($sClass, $this->aCssClasses)) + { + $this->aCssClasses[] = $sClass; + } + return $this; + } + + /** + * + * @param string $sClass + * @return \Combodo\iTop\Renderer\RenderingOutput + */ + public function RemoveCssClass($sClass) + { + if (in_array($sClass, $this->aCssClasses)) + { + unset($this->aCssClasses[$sClass]); + } + return $this; + } }