From d506efa92d1bcd1f60876727f0bb9f91345971d1 Mon Sep 17 00:00:00 2001 From: Ralf Zimmermann <ralf.zimmermann@tritum.de> Date: Sun, 26 Mar 2017 12:54:07 +0200 Subject: [PATCH] [TASK] EXT:form - make 'grid rows' independent from 'grid containers' * Create 'grid rows' without 'grid container' wrappers * Disable 'grid containers' within the form editor by default because twitter bootstrap prohibits container nesting Resolves: #80455 Releases: master Change-Id: I3997943858ac3b235094b765697f724cb1e4c95d Reviewed-on: https://review.typo3.org/52166 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Susanne Moog <susanne.moog@typo3.org> Tested-by: Susanne Moog <susanne.moog@typo3.org> Reviewed-by: Frank Naegler <frank.naegler@typo3.org> Tested-by: Frank Naegler <frank.naegler@typo3.org> --- .../Domain/Model/FormElements/GridRow.php | 28 ---------- ...ColumnClassAutoConfigurationViewHelper.php | 19 ++++--- .../form/Configuration/Yaml/BaseSetup.yaml | 12 +++++ .../Configuration/Yaml/FormEditorSetup.yaml | 2 - .../Public/JavaScript/Backend/FormEditor.js | 13 +++++ .../JavaScript/Backend/FormEditor/Core.js | 24 +++++++++ .../Backend/FormEditor/StageComponent.js | 52 +++++++++++-------- .../Backend/FormEditor/TreeComponent.js | 12 ++--- .../Backend/FormEditor/ViewModel.js | 5 +- 9 files changed, 96 insertions(+), 71 deletions(-) diff --git a/typo3/sysext/form/Classes/Domain/Model/FormElements/GridRow.php b/typo3/sysext/form/Classes/Domain/Model/FormElements/GridRow.php index 06f03b32fa52..5be61bd435c1 100644 --- a/typo3/sysext/form/Classes/Domain/Model/FormElements/GridRow.php +++ b/typo3/sysext/form/Classes/Domain/Model/FormElements/GridRow.php @@ -30,24 +30,6 @@ use TYPO3\CMS\Form\Domain\Exception\TypeDefinitionNotValidException; class GridRow extends Section implements GridRowInterface { - /** - * Register this element at the parent form, if there is a connection to the parent form. - * - * @return void - * @throws TypeDefinitionNotValidException - * @internal - */ - public function registerInFormIfPossible() - { - if (!$this->getParentRenderable() instanceof GridContainerInterface) { - throw new TypeDefinitionNotValidException( - sprintf('Grid rows ("%s") only allowed within grid containers.', $this->getIdentifier()), - 1489413805 - ); - } - parent::registerInFormIfPossible(); - } - /** * Add a new form element at the end of the grid row * @@ -63,11 +45,6 @@ class GridRow extends Section implements GridRowInterface sprintf('Grid containers ("%s") within grid rows ("%s") are not allowed.', $formElement->getIdentifier(), $this->getIdentifier()), 1489413379 ); - } elseif ($formElement instanceof GridRowInterface) { - throw new TypeDefinitionNotValidException( - sprintf('Grid rows ("%s") within grid rows ("%s") are not allowed.', $formElement->getIdentifier(), $this->getIdentifier()), - 1489413696 - ); } $this->addRenderable($formElement); @@ -91,11 +68,6 @@ class GridRow extends Section implements GridRowInterface sprintf('Grid containers ("%s") within grid rows ("%s") are not allowed.', $element->getIdentifier(), $this->getIdentifier()), 1489413538 ); - } elseif ($element instanceof GridRowInterface) { - throw new TypeDefinitionNotValidException( - sprintf('Grid rows ("%s") within grid rows ("%s") are not allowed.', $element->getIdentifier(), $this->getIdentifier()), - 1489413697 - ); } return $element; diff --git a/typo3/sysext/form/Classes/ViewHelpers/GridColumnClassAutoConfigurationViewHelper.php b/typo3/sysext/form/Classes/ViewHelpers/GridColumnClassAutoConfigurationViewHelper.php index e70c5f3bcb1d..93bf6e28afae 100644 --- a/typo3/sysext/form/Classes/ViewHelpers/GridColumnClassAutoConfigurationViewHelper.php +++ b/typo3/sysext/form/Classes/ViewHelpers/GridColumnClassAutoConfigurationViewHelper.php @@ -16,6 +16,7 @@ namespace TYPO3\CMS\Form\ViewHelpers; */ use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper; +use TYPO3\CMS\Form\Domain\Model\FormElements\GridContainerInterface; use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; @@ -63,23 +64,27 @@ class GridColumnClassAutoConfigurationViewHelper extends AbstractViewHelper $gridContainerElement = $gridRowElement->getParentRenderable(); $gridRowEChildElements = $gridRowElement->getElementsRecursively(); - $gridContainerViewPortConfiguration = $gridContainerElement->getProperties()['gridColumnClassAutoConfiguration']; - if (empty($gridContainerViewPortConfiguration)) { - return ''; + if ($gridContainerElement instanceof GridContainerInterface) { + $gridViewPortConfiguration = $gridContainerElement->getProperties()['gridColumnClassAutoConfiguration']; + } else { + $gridViewPortConfiguration = $gridRowElement->getProperties()['gridColumnClassAutoConfiguration']; } - $gridSize = (int)$gridContainerViewPortConfiguration['gridSize']; + if (empty($gridViewPortConfiguration)) { + return ''; + } + $gridSize = (int)$gridViewPortConfiguration['gridSize']; $columnsToCalculate = []; $usedColumns = []; foreach ($gridRowEChildElements as $childElement) { if (empty($childElement->getProperties()['gridColumnClassAutoConfiguration'])) { - foreach ($gridContainerViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) { + foreach ($gridViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) { $columnsToCalculate[$viewPortName]['elements']++; } } else { $gridColumnViewPortConfiguration = $childElement->getProperties()['gridColumnClassAutoConfiguration']; - foreach ($gridContainerViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) { + foreach ($gridViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) { $configuration = $gridColumnViewPortConfiguration['viewPorts'][$viewPortName]; if ( isset($configuration['numbersOfColumnsToUse']) @@ -100,7 +105,7 @@ class GridColumnClassAutoConfigurationViewHelper extends AbstractViewHelper } $classes = []; - foreach ($gridContainerViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) { + foreach ($gridViewPortConfiguration['viewPorts'] as $viewPortName => $configuration) { if (isset($usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse'])) { $numbersOfColumnsToUse = $usedColumns[$viewPortName]['concreteNumbersOfColumnsToUse']; } else { diff --git a/typo3/sysext/form/Configuration/Yaml/BaseSetup.yaml b/typo3/sysext/form/Configuration/Yaml/BaseSetup.yaml index a8b4fd30af2f..a0a500b2c30b 100644 --- a/typo3/sysext/form/Configuration/Yaml/BaseSetup.yaml +++ b/typo3/sysext/form/Configuration/Yaml/BaseSetup.yaml @@ -77,6 +77,7 @@ TYPO3: _isGridContainerFormElement: true properties: elementClassAttribute: 'container' + # overrules 'GridRow.properties.gridColumnClassAutoConfiguration' gridColumnClassAutoConfiguration: gridSize: 12 viewPorts: @@ -95,6 +96,17 @@ TYPO3: implementationClassName: 'TYPO3\CMS\Form\Domain\Model\FormElements\GridRow' properties: elementClassAttribute: 'row' + gridColumnClassAutoConfiguration: + gridSize: 12 + viewPorts: + xs: + classPattern: 'col-xs-{@numbersOfColumnsToUse}' + sm: + classPattern: 'col-sm-{@numbersOfColumnsToUse}' + md: + classPattern: 'col-md-{@numbersOfColumnsToUse}' + lg: + classPattern: 'col-lg-{@numbersOfColumnsToUse}' renderingOptions: _isCompositeFormElement: true _isGridRowFormElement: true diff --git a/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml b/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml index 8716b328bd69..142d42045521 100644 --- a/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml +++ b/typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml @@ -304,8 +304,6 @@ TYPO3: GridContainer: formEditor: label: 'formEditor.elements.GridContainer.label' - group: container - groupSorting: 200 _isCompositeFormElement: true _isGridContainerFormElement: true iconIdentifier: 't3-form-icon-gridcontainer' diff --git a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor.js b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor.js index 14e42a55d5ca..9f620eb8fe67 100644 --- a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor.js +++ b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor.js @@ -812,6 +812,18 @@ define(['jquery', ); }; + /** + * @public + * + * @param object formElement + * @return object|null + */ + function findEnclosingGridRowFormElement(formElement) { + return _getRepository().findEnclosingGridRowFormElement( + _getRepository().findFormElement(formElement) + ); + }; + /** * @public * @@ -1071,6 +1083,7 @@ define(['jquery', getLastTopLevelElementOnCurrentPage: getLastTopLevelElementOnCurrentPage, findEnclosingCompositeFormElementWhichIsNotOnTopLevel: findEnclosingCompositeFormElementWhichIsNotOnTopLevel, findEnclosingGridContainerFormElement: findEnclosingGridContainerFormElement, + findEnclosingGridRowFormElement: findEnclosingGridRowFormElement, isRootFormElementSelected: isRootFormElementSelected, getLastFormElementWithinParentFormElement: getLastFormElementWithinParentFormElement, getNonCompositeNonToplevelFormElements: getNonCompositeNonToplevelFormElements, diff --git a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Core.js b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Core.js index d1824db06565..9be812ad9890 100644 --- a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Core.js +++ b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/Core.js @@ -1353,6 +1353,29 @@ define(['jquery'], function($) { return formElement; }; + /** + * @param object formElement + * @return object|null + * @throws 1490520271 + */ + function findEnclosingGridRowFormElement(formElement) { + var formElementTypeDefinition; + utility().assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1490520271); + + formElementTypeDefinition = repository().getFormEditorDefinition('formElements', formElement.get('type')); + while (!formElementTypeDefinition['_isGridRowFormElement']) { + if (formElementTypeDefinition['_isTopLevelFormElement']) { + return null; + } + formElement = formElement.get('__parentRenderable'); + formElementTypeDefinition = repository().getFormEditorDefinition('formElements', formElement.get('type')); + } + if (formElementTypeDefinition['_isTopLevelFormElement']) { + return null; + } + return formElement; + }; + /** * @param object formElement * @return object|null @@ -1706,6 +1729,7 @@ define(['jquery'], function($) { findEnclosingCompositeFormElementWhichIsNotOnTopLevel: findEnclosingCompositeFormElementWhichIsNotOnTopLevel, findEnclosingCompositeFormElementWhichIsOnTopLevel: findEnclosingCompositeFormElementWhichIsOnTopLevel, findEnclosingGridContainerFormElement: findEnclosingGridContainerFormElement, + findEnclosingGridRowFormElement: findEnclosingGridRowFormElement, getIndexForEnclosingCompositeFormElementWhichIsOnTopLevelForFormElement: getIndexForEnclosingCompositeFormElementWhichIsOnTopLevelForFormElement, getNonCompositeNonToplevelFormElements: getNonCompositeNonToplevelFormElements, diff --git a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/StageComponent.js b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/StageComponent.js index ff2a1174374a..69f7478e43ad 100644 --- a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/StageComponent.js +++ b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/StageComponent.js @@ -372,14 +372,10 @@ define(['jquery', if ( formElementTypeDefinition['_isGridContainerFormElement'] - && getFormEditorApp().findEnclosingGridContainerFormElement(targetFormElementIdentifierPath) - ) { - return false; - } - - if ( - formElementTypeDefinition['_isGridRowFormElement'] - && !targetFormElementTypeDefinition['_isGridContainerFormElement'] + && ( + getFormEditorApp().findEnclosingGridContainerFormElement(targetFormElementIdentifierPath) + || getFormEditorApp().findEnclosingGridRowFormElement(targetFormElementIdentifierPath) + ) ) { return false; } @@ -701,10 +697,21 @@ define(['jquery', disableElementTypes = []; onlyEnableElementTypes = []; if (formElementTypeDefinition['_isGridRowFormElement']) { - onlyEnableElementTypes = ['GridRow']; - disableElementTypes = []; + if (getFormEditorApp().findEnclosingGridContainerFormElement(getCurrentlySelectedFormElement())) { + onlyEnableElementTypes = ['GridRow']; + } else if (getFormEditorApp().findEnclosingGridRowFormElement(getCurrentlySelectedFormElement().get('__parentRenderable'))) { + disableElementTypes = ['GridContainer']; + } } else { - disableElementTypes = ['GridRow']; + if ( + !formElementTypeDefinition['_isGridContainerFormElement'] + && ( + getFormEditorApp().findEnclosingGridContainerFormElement(getCurrentlySelectedFormElement()) + || getFormEditorApp().findEnclosingGridRowFormElement(getCurrentlySelectedFormElement()) + ) + ) { + disableElementTypes = ['GridContainer']; + } } getPublisherSubscriber().publish('view/stage/abstract/elementToolbar/button/newElement/clicked', [ @@ -719,14 +726,18 @@ define(['jquery', $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElementSplitButtonInside'), template).on('click', function(e) { var disableElementTypes, onlyEnableElementTypes; - disableElementTypes = ['GridRow']; + disableElementTypes = []; onlyEnableElementTypes = []; if (formElementTypeDefinition['_isGridContainerFormElement']) { onlyEnableElementTypes = ['GridRow']; - disableElementTypes = []; - } else if (formElementTypeDefinition['_isGridRowFormElement']) { - onlyEnableElementTypes = []; - disableElementTypes = ['GridContainer', 'GridRow']; + } else if ( + formElementTypeDefinition['_isGridRowFormElement'] + || ( + getFormEditorApp().findEnclosingGridContainerFormElement(getCurrentlySelectedFormElement()) + || getFormEditorApp().findEnclosingGridRowFormElement(getCurrentlySelectedFormElement()) + ) + ) { + disableElementTypes = ['GridContainer']; } getPublisherSubscriber().publish('view/stage/abstract/elementToolbar/button/newElement/clicked', [ @@ -742,14 +753,11 @@ define(['jquery', getViewModel().hideComponent($(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElementSplitButton'), template)); $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElement'), template).on('click', function(e) { - var disableElementTypes, onlyEnableElementTypes; + var disableElementTypes; disableElementTypes = []; - onlyEnableElementTypes = []; - if (getFormEditorApp().findEnclosingGridContainerFormElement(formElement)) { - disableElementTypes = ['GridContainer', 'GridRow']; - } else { - disableElementTypes = ['GridRow']; + if (getFormEditorApp().findEnclosingGridRowFormElement(formElement)) { + disableElementTypes = ['GridContainer']; } getPublisherSubscriber().publish( diff --git a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/TreeComponent.js b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/TreeComponent.js index f9c0ac090af6..03a45127fc95 100644 --- a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/TreeComponent.js +++ b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/TreeComponent.js @@ -325,14 +325,10 @@ define(['jquery', if ( formElementTypeDefinition['_isGridContainerFormElement'] - && getFormEditorApp().findEnclosingGridContainerFormElement(targetFormElementIdentifierPath) - ) { - return false; - } - - if ( - formElementTypeDefinition['_isGridRowFormElement'] - && !targetFormElementTypeDefinition['_isGridContainerFormElement'] + && ( + getFormEditorApp().findEnclosingGridContainerFormElement(targetFormElementIdentifierPath) + || getFormEditorApp().findEnclosingGridRowFormElement(targetFormElementIdentifierPath) + ) ) { return false; } diff --git a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js index fe699912bcd7..cc4813a00c69 100644 --- a/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js +++ b/typo3/sysext/form/Resources/Public/JavaScript/Backend/FormEditor/ViewModel.js @@ -404,10 +404,7 @@ define(['jquery', $(getHelper().getDomElementDataIdentifierSelector('buttonStageNewElementBottom')).on('click', function(e) { getPublisherSubscriber().publish( 'view/stage/abstract/button/newElement/clicked', [ - 'view/insertElements/perform/bottom', - { - disableElementTypes: ['GridRow'] - } + 'view/insertElements/perform/bottom' ] ); }); -- GitLab