typo3extbaseview-helpers

Remove submitted value from form if form validation fails


With the following (shortened) form I register new users in TYPO3 v12:

<f:form action="register" name="registration" object="{registration}" id="register-form">

    <f:form.textfield
        property="login"
        id="login" />

    <f:form.textfield
        type="password"
        property="password"
        id="password" />

</f:form>

The validation happens in the model:

class Registration extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
{
    /**
     * @var string
     * @Extbase\Validate("NotEmpty")
     * @Extbase\Validate("StringLength", options={"minimum": 8, "maximum": 30})
     */
    protected string $login = '';

    /**
     * @var string
     * @Extbase\Validate("NotEmpty")
     * @Extbase\Validate("RegularExpression", options={"regularExpression": "/^.*(?=.{8,})(?=.*[a-zA-Z])(?=.*\d).*$/"})
     */
    protected string $password = '';
}

Submitting the form with less the eight characters for the login or password will show the form again. The form fields will show the submmited data and the error messages accordingly. This is the normal behaviour.

Now I don't want to return the password to the form after it was submitted, the field shall be emptied.

I did the following with no luck:


Solution

  • In order to use the normal model validation, you can use a custom viewhelper, which does not show the submitted value for the form field:

    Viewhelper:

    <?php
    
    declare(strict_types=1);
    
    namespace Vendor\Extension\ViewHelpers;
    
    use TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormFieldViewHelper;
    
    /*
     * This is a modified version of `TYPO3\CMS\Fluid\ViewHelpers\Form\TextfieldViewHelper`
     * It removes the value from the password field.
     *
     * Modifications are marked below.
     */
    class PasswordViewHelper extends AbstractFormFieldViewHelper
    {
        /**
         * @var string
         */
        protected $tagName = 'input';
    
        public function initializeArguments(): void
        {
            parent::initializeArguments();
            $this->registerTagAttribute('autofocus', 'string', 'Specifies that an input should automatically get focus when the page loads');
            $this->registerTagAttribute('disabled', 'string', 'Specifies that the input element should be disabled when the page loads');
            $this->registerTagAttribute('maxlength', 'int', 'The maxlength attribute of the input field (will not be validated)');
            $this->registerTagAttribute('readonly', 'string', 'The readonly attribute of the input field');
            $this->registerTagAttribute('size', 'int', 'The size of the input field');
            $this->registerTagAttribute('placeholder', 'string', 'The placeholder of the textfield');
            $this->registerTagAttribute('pattern', 'string', 'HTML5 validation pattern');
            $this->registerArgument('errorClass', 'string', 'CSS class to set if there are errors for this ViewHelper', false, 'f3-form-error');
            $this->registerUniversalTagAttributes();
            $this->registerArgument('required', 'bool', 'If the field is required or not', false, false);
            $this->registerArgument('type', 'string', 'The field type, e.g. "text", "email", "url" etc.', false, 'text');
        }
    
        public function render(): string
        {
            $required = $this->arguments['required'];
            $type = $this->arguments['type'];
    
            $name = $this->getName();
            $this->registerFieldNameForFormTokenGeneration($name);
            $this->setRespectSubmittedDataValue(true);
    
            $this->tag->addAttribute('type', $type);
            $this->tag->addAttribute('name', $name);
    
            $value = $this->getValueAttribute();
    
            // Original of `TextfieldViewHelper`
            /*
            if ($value !== null) {
                $this->tag->addAttribute('value', $value);
            }
            */
    
            // Modification start
            $this->tag->addAttribute('value', '');
            // Modification end
    
            if ($required !== false) {
                $this->tag->addAttribute('required', 'required');
            }
    
            $this->addAdditionalIdentityPropertiesIfNeeded();
            $this->setErrorClassAttribute();
    
            // Modification start
            if ($value !== null) {
                if ($this->hasArgument('class')) {
                    $cssClass = $this->arguments['class'] . ' ';
                } else {
                    $cssClass = '';
                }
                $cssClass .= 'f3-form-error';
                $this->tag->addAttribute('class', $cssClass);
            }
            // Modification end
    
            return $this->tag->render();
        }
    }
    

    No you can use this viewhelper in the view:

    <vendor:password
        type="password"
        property="password"
        id="password"
        class="form-control" />