From 73d19ef3d98622939d563b14e2d42502821322c2 Mon Sep 17 00:00:00 2001 From: Nikita Hovratov <nikita.h@live.de> Date: Sat, 30 Mar 2024 18:02:28 +0100 Subject: [PATCH] [BUGFIX] Bring back valuePicker for TCA type `email` While extracting dedicated TCA types from the god type `input`, the `valuePicker` option was forgotten for type `email`. Other types like `number` do have this option. An acceptance test is added to ensure this option will not be dropped by accident in the future. Resolves: #103510 Related: #97013 Releases: main, 12.4 Change-Id: I95c51d858ca9cb3caefa174cd8ce5946c8352aa2 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83631 Reviewed-by: Georg Ringer <georg.ringer@gmail.com> Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: core-ci <typo3@b13.com> Tested-by: Benni Mack <benni@typo3.org> Tested-by: Georg Ringer <georg.ringer@gmail.com> Tested-by: Nikita Hovratov <nikita.h@live.de> Reviewed-by: Nikita Hovratov <nikita.h@live.de> --- .../Classes/Form/Element/EmailElement.php | 29 ++++++- .../FormEngine/ElementsBasicEmailCest.php | 87 +++++++++++++++++++ .../TCA/tx_styleguide_elements_basic.php | 20 ++++- 3 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 typo3/sysext/core/Tests/Acceptance/Application/FormEngine/ElementsBasicEmailCest.php diff --git a/typo3/sysext/backend/Classes/Form/Element/EmailElement.php b/typo3/sysext/backend/Classes/Form/Element/EmailElement.php index deeb311c2650..d435ea6ba075 100644 --- a/typo3/sysext/backend/Classes/Form/Element/EmailElement.php +++ b/typo3/sysext/backend/Classes/Form/Element/EmailElement.php @@ -17,6 +17,7 @@ declare(strict_types=1); namespace TYPO3\CMS\Backend\Form\Element; +use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; use TYPO3\CMS\Core\Utility\StringUtility; @@ -139,6 +140,31 @@ class EmailElement extends AbstractFormElement $attributes['autocomplete'] = empty($config['autocomplete']) ? 'new-' . $fieldName : 'on'; } + $valuePickerHtml = []; + if (is_array($config['valuePicker']['items'] ?? false)) { + $valuePickerConfiguration = [ + 'mode' => $config['valuePicker']['mode'] ?? 'replace', + 'linked-field' => '[data-formengine-input-name="' . $itemName . '"]', + ]; + $valuePickerAttributes = array_merge( + [ + 'class' => 'form-select form-control-adapt', + ], + $this->getOnFieldChangeAttrs('change', $parameterArray['fieldChangeFunc'] ?? []) + ); + + $valuePickerHtml[] = '<typo3-formengine-valuepicker ' . GeneralUtility::implodeAttributes($valuePickerConfiguration, true) . '>'; + $valuePickerHtml[] = '<select ' . GeneralUtility::implodeAttributes($valuePickerAttributes, true) . '>'; + $valuePickerHtml[] = '<option></option>'; + foreach ($config['valuePicker']['items'] as $item) { + $valuePickerHtml[] = '<option value="' . htmlspecialchars((string)$item[1]) . '">' . htmlspecialchars($languageService->sL($item[0])) . '</option>'; + } + $valuePickerHtml[] = '</select>'; + $valuePickerHtml[] = '</typo3-formengine-valuepicker>'; + + $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/form-engine/field-wizard/value-picker.js'); + } + $fieldControlResult = $this->renderFieldControl(); $fieldControlHtml = $fieldControlResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldControlResult, false); @@ -154,9 +180,10 @@ class EmailElement extends AbstractFormElement $mainFieldHtml[] = '<input type="email" ' . GeneralUtility::implodeAttributes($attributes, true) . ' />'; $mainFieldHtml[] = '<input type="hidden" name="' . $itemName . '" value="' . htmlspecialchars((string)$itemValue) . '" />'; $mainFieldHtml[] = '</div>'; - if (!empty($fieldControlHtml)) { + if (!empty($valuePickerHtml) || !empty($fieldControlHtml)) { $mainFieldHtml[] = '<div class="form-wizards-items-aside form-wizards-items-aside--field-control">'; $mainFieldHtml[] = '<div class="btn-group">'; + $mainFieldHtml[] = implode(LF, $valuePickerHtml); $mainFieldHtml[] = $fieldControlHtml; $mainFieldHtml[] = '</div>'; $mainFieldHtml[] = '</div>'; diff --git a/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/ElementsBasicEmailCest.php b/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/ElementsBasicEmailCest.php new file mode 100644 index 000000000000..d6d3f9969511 --- /dev/null +++ b/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/ElementsBasicEmailCest.php @@ -0,0 +1,87 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Core\Tests\Acceptance\Application\FormEngine; + +use Codeception\Attribute\DataProvider; +use Codeception\Example; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverKeys; +use TYPO3\CMS\Core\Tests\Acceptance\Support\ApplicationTester; +use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\PageTree; + +/** + * Tests for "elements_basic" simple input fields of ext:styleguide + */ +final class ElementsBasicEmailCest extends AbstractElementsBasicCest +{ + /** + * Open list module of styleguide elements basic page + */ + public function _before(ApplicationTester $I, PageTree $pageTree): void + { + $I->useExistingSession('admin'); + $I->click('List'); + $pageTree->openPath(['styleguide TCA demo', 'elements basic']); + // Wait until DOM actually rendered everything + $I->switchToContentFrame(); + + // Open record and wait until form is ready + $I->waitForText('elements basic', 20); + $editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_basic a[aria-label="Edit record"]'; + $I->click($editRecordLinkCssPath); + $I->waitForElementNotVisible('#t3js-ui-block'); + $I->waitForText('Edit Form', 3, 'h1'); + + // Make sure the test operates on the "email" tab + $I->click('email'); + } + + /** + * Data provider to check various type=email variants + */ + private function emailFieldsDataProvider(): array + { + return [ + [ + 'label' => 'email_1', + 'inputValue' => 'foo@example.com', + 'expectedValue' => 'foo@example.com', + 'expectedInternalValue' => 'foo@example.com', + 'expectedValueAfterSave' => 'foo@example.com', + 'comment' => '', + ], + ]; + } + + #[DataProvider('emailFieldsDataProvider')] + public function emailFields(ApplicationTester $I, Example $testData): void + { + $this->runInputFieldTest($I, $testData); + } + + public function canSelectValueFromValuePicker(ApplicationTester $I): void + { + $formSection = $this->getFormSectionByFieldLabel($I, 'email_5'); + $select = $formSection->findElement(WebDriverBy::xpath('.//*/typo3-formengine-valuepicker/select')); + $input = $this->getInputField($formSection); + // Select second option from value picker. + $select->sendKeys(WebDriverKeys::ARROW_DOWN); + $select->sendKeys(WebDriverKeys::ARROW_DOWN); + $I->seeInField($input, 'info@example.org'); + } +} diff --git a/typo3/sysext/styleguide/Configuration/TCA/tx_styleguide_elements_basic.php b/typo3/sysext/styleguide/Configuration/TCA/tx_styleguide_elements_basic.php index a04dd58f371a..61ed52870817 100644 --- a/typo3/sysext/styleguide/Configuration/TCA/tx_styleguide_elements_basic.php +++ b/typo3/sysext/styleguide/Configuration/TCA/tx_styleguide_elements_basic.php @@ -846,20 +846,34 @@ return [ ], ], 'email_3' => [ - 'label' => 'email_3 nullable', + 'label' => 'email_3', + 'description' => 'nullable', 'config' => [ 'type' => 'email', 'nullable' => true, ], ], 'email_4' => [ - 'label' => 'email_4 nullable with placeholder', + 'label' => 'email_4', + 'description' => 'nullable with placeholder', 'config' => [ 'type' => 'email', 'nullable' => true, 'placeholder' => 'info@example.org', ], ], + 'email_5' => [ + 'label' => 'email_5', + 'description' => 'valuePicker', + 'config' => [ + 'type' => 'email', + 'valuePicker' => [ + 'items' => [ + ['Example email', 'info@example.org'], + ], + ], + ], + ], 'text_1' => [ 'l10n_mode' => 'prefixLangTitle description', @@ -1878,7 +1892,7 @@ backend_layout { --div--;number, number_1, number_2, number_3, number_4, number_5, number_7, --div--;email, - email_1, email_2, email_3, email_4, + email_1, email_2, email_3, email_4, email_5, --div--;text, text_1, text_2, text_3, text_4, text_5, text_6, text_7, text_9, text_10, text_11, text_12, text_13, text_18, text_14, text_15, text_16, text_17, text_19, -- GitLab