TYPO3: Rendering selectMultipleSideBySide element with ext_conf_template.txt

85 Views Asked by At

TYPO3 version: 10.4.6

In my project I have a custom extension that has a ext_conf_template.txt file.

According to the TYPO3 documentation it should be possible to use an user option type that is linked to a custom user function.(https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/ExtConfTemplate.html)

I tried to use it but I did not work.

Is there another way to create a selectMultipleSideBySide field in the extension configuration without editing the ext_conf_template.txt file?

This is my falsy apprach so far:

# cat=basic/enable; type=user[My\Path\UserFunctions\ExtConfUserFunctions->renderCategories]; label=Kategorien ausschließen
excluded =
<?php

namespace My\Path\UserFunctions;

use TYPO3\CMS\Backend\Form\Element\SelectMultipleSideBySideElement;
use TYPO3\CMS\Backend\Form\NodeFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class ExtConfUserFunctions
{
    /**
     * @return string
     */
    public function renderCategories(): string
    {
        /** @var NodeFactory $nodeFactory */
        $nodeFactory = GeneralUtility::makeInstance(NodeFactory::class);
        /** @var SelectMultipleSideBySideElement $element */
        $element = GeneralUtility::makeInstance(
            SelectMultipleSideBySideElement::class,
            $nodeFactory,
            [
                'config' => [
                    'type'       => 'select',
                    'renderType' => 'selectMultipleSideBySide',
                    'items'      => [
                        ['Option 1', '1'],
                        ['Option 2', '2'],
                        ['Option 3', '3'],
                    ]
                ]
            ]
        );

        $elementArray = $element->render();
    }
}
1

There are 1 best solutions below

0
Mogens On

Got this partly to work. As Julian Hoffmann described you must change the parameters passed to the SelectMultipleSideBySideElement class.

To avoid the error with the missing BackendUser you must then implement a custom child class for the SelectMultipleSideBySideElement class and override the appendValueToLabelInDebugMode method. To keep it simple i just added the child class in the UserFunctions folder. Here is the code:

<?php
namespace My\Path\UserFunctions;

use \TYPO3\CMS\Backend\Form\Element\SelectMultipleSideBySideElement as OrigSelectMultipleSideBySideElement;

class SelectMultipleSideBySideElement extends OrigSelectMultipleSideBySideElement
{
    protected function appendValueToLabelInDebugMode($label, $value): string
    {
        return (string)$label;
    }
}

Now the SelectMultipleSideBySideElement is rendered. But still not working proper because of two missing things.

The first missing thing is a field in the html to save the selected config. This is easy. You just add a hidden field to the rendered html. The UserFunc at this point looks like this:

    <?php
namespace My\Path\UserFunctions;

use TYPO3\CMS\Backend\Form\NodeFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class ExtConfUserFunction
{
    /**
     * @return string
     */
    public function renderCategories(): string
    {

        /** @var NodeFactory $nodeFactory */
        $nodeFactory = GeneralUtility::makeInstance(NodeFactory::class);
        /** @var SelectMultipleSideBySideElement $element */
        $element = GeneralUtility::makeInstance(
            SelectMultipleSideBySideElement::class,
            $nodeFactory,
            [
                'parameterArray' => [
                    'fieldConf' => [
                        'config' => [
                            'type'       => 'select',
                            'renderType' => 'selectMultipleSideBySide',
                            'items'      => [
                                ['Option 1', '1'],
                                ['Option 2', '2'],
                                ['Option 3', '3'],
                            ]
                        ]
                    ]
                ]

            ]
        );
        $elementArray = $element->render();
        $elementArray['html'] .= '<input type="hidden" id="em-extkey-excluded" name="excluded" class="form-control" value="">';
        return $elementArray['html'];

    }
}

Now the harder one. The JS for the element functionality is missing. I don't have a solution for that one. Here is what i tried until now:

$elementArray = $element->render();

$pageRenderer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Page\PageRenderer::class);
$pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/FormEngine/RequestUpdate');
$pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/FormEngine/Element/SelectMultipleSideBySideElement');
$js = $pageRenderer->getJavaScriptRenderer()->render();

$elementArray['html'] .= '<input type="hidden" id="em-extkey-excluded" name="excluded" class="form-control" value="">';
$elementArray['html'] .= $js;


return $elementArray['html'];

The JavaScriptHandler is loaded then. But i'm not sure if the JS for the SelectMultipleSideBySideElement is loaded proper. Also not sure, if the PageRenderer can be used like this at this point. Fact is that the JS is not working. Even if you get the JS to work somehow, you must then implement custom JS code to save the selected category uids as comma separated list in the hidden field. Maybe it's easier to implement custom JS code for the complete functionality of the element.

Hope this helps you to get it working. Maybe you could edit the Answer with the custom JS solution if you get it running.