Form.checkbox ViewHelper <f:form.checkbox>
ViewHelper which renders a simple checkbox <input type="checkbox">
.
Go to the source code of this ViewHelper: Form\CheckboxViewHelper.php (GitHub).
Table of contents
Single checkboxes
A single checkbox is usually mapped to a boolean property or controller argument.
However due to how checkboxes work in HTML a non-checked checkbox does not
appear in the request sent by the form submission. Therefore properties and arguments
need to default to false
. They will then be set to true
if the checkbox
was checked.
While the value does not play a role when you are working with a checkbox, the argument must still be supplied.
Single optional checkbox tied to an action argument
Checkboxes in HTML work a little different from other input fields in that multiple or none at all can be checked.
Fluid outputs a normal HTML <input type="checkbox" ...> and some of the pitfalls also apply here. Especially a check box that is not sends no argument to the request.
Then the controller action can then look like this:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Controller;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
class NewsletterController extends ActionController
{
public function orderNewsletterAction(
// If the checkbox is not checked, no argument is provided.
// Default to false
bool $orderNewsletter = false,
): ResponseInterface {
if ($orderNewsletter) {
// TODO: Newsletter ordering
}
return $this->htmlResponse();
}
}
Note
If a checkbox is not checked it sends NO argument as opposed to a text input with no text entered. Therefore in the Extbase action you must supply a default for the argument if non-checked fields should be allowed.
The checkbox should already by checked / preselected
<f:form.checkbox name="accept" value="yes" checked="true" />
You can also use a variable to determine whether the field should be checked:
<f:form.checkbox name="accept" value="yes" checked="{myVariable} == 5" />
Note
When you work with Property mapping
the checkbox is automatically preselected if the model's property evalutes to true
.
Property mapping - domain model property bound to single checkbox
If you are using the form with a model you can use the argument property to map the checkbox to a property of your domain model or data object:
Then the controller action can look like this:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Controller;
use MyVendor\MyExtension\Domain\Model\User;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
class NewsletterController extends ActionController
{
public function orderNewsletterAction(
User $user,
): ResponseInterface {
if ($user->isOrderNewsletter()) {
// TODO: Newsletter ordering
}
return $this->htmlResponse();
}
}
An unchecked checkbox results in the property not being set. It should
therefore default to false
.
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Domain\Model;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
class User extends AbstractEntity
{
protected bool $orderNewsletter = false;
public function isOrderNewsletter(): bool
{
return $this->orderNewsletter;
}
public function setOrderNewsletter(bool $orderNewsletter): void
{
$this->orderNewsletter = $orderNewsletter;
}
}
If the property in the domain model is true
when the form is displayed, the
checkbox is preselected.
Multiple checkboxes for the same property
Unlike other input elements, multiple checkboxes can be used for the same property or action argument.
In this case they share the same name or property binding property but have distinct values.
If you are working with action arguments, multiple must be set.
Multiple checkboxes mapped to an array in a controller action
Multiple checkboxes are usually mapped to an array
. It would however be possible, for example,
to map them to an integer using binaries or such.
Therefore when working with multiple checkboxes and arrays, you have to tell
Extbase how to map the data from the request to your controller action in an
initialize
action.
<f:form action="orderNewsletter" method="post">
<f:for each="{newsletterList}" as="newsletter" iteration="i">
<div>
<f:form.checkbox name="orderNewsletters" id="newsletter{i.cycle}" value="{newsletter.uid}" />
<label for="newsletter{i.cycle}">{newsletter.title}</label>
</div>
</f:for>
<div><f:form.submit value="Submit" /></div>
</f:form>
Then the controller action can look like this:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Controller;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Property\TypeConverter\ArrayConverter;
class NewsletterController extends ActionController
{
public function orderNewsletterAction(
// This argument is mapped in initializeOrderNewsletterAction()
array $orderNewsletters = [],
): ResponseInterface {
if ($orderNewsletters !== []) {
// TODO: Newsletter ordering
}
return $this->htmlResponse();
}
public function initializeOrderNewsletterAction()
{
if ($this->request->hasArgument('orderNewsletters')) {
$this->arguments['orderNewsletters']
->getPropertyMappingConfiguration()
->setTypeConverterOption(
ArrayConverter::class,
ArrayConverter::CONFIGURATION_DELIMITER,
',',
);
}
}
}
Note
See class
\TYPO3\
for details on mapping arrays.
Property mapping of multiple checkboxes
When working with multiple checkboxes mapped to the property of an Extbase model or data object, the same property is used for all checkboxes to be mapped to that property.
Note
An example is still missing. You can help by providing an example.
Click the "report issue" button above and hand in your examples.
Multiple checkboxes for multiple independent properties
When multiple checkboxes should be used independently they must have unique name properties to map to multiple action arguments or unique property values to bind to multiple properties.
Mandatory checkboxes - require a checkbox to be set
On the browser side you can use the HTML 5 "required" Attribute.
As the <f:
ViewHelper allows arbitrary arguments, using
the required
property is possible even though it is not listed.
<f:flashMessages/>
<f:form action="orderNewsletter" method="post" object="user" objectName="user">
<div>
<f:form.checkbox property="consentGiven" id="consentGiven" value="yes" required="required"/>
<label for="consentGiven">I have accepted the terms and conditions</label>
</div>
<div>
<f:form.submit value="Submit" />
</div>
</f:form>
Then the controller action can then look like this:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Controller;
use MyVendor\MyExtension\Domain\Model\User;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
class NewsletterController extends ActionController
{
public function orderNewsletterAction(
User $user,
): ResponseInterface {
if ($user->isOrderNewsletter()) {
// TODO: Newsletter ordering
}
return $this->htmlResponse();
}
}
You should also validate the model for the property to be true:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Domain\Model;
use TYPO3\CMS\Extbase\Annotation\Validate;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
class User extends AbstractEntity
{
#[Validate([
'validator' => 'Boolean',
'options' => ['is' => true],
])]
protected bool $consentGiven = false;
public function isConsentGiven(): bool
{
return $this->consentGiven;
}
public function setConsentGiven(bool $consentGiven): void
{
$this->consentGiven = $consentGiven;
}
}
If the server side validation on the model fails, the request is forwarded to the originating request with an error message.
Arguments
Allows arbitrary arguments
This ViewHelper allows you to pass arbitrary arguments not defined below
directly to the HTML tag created. This includes custom data-
arguments.
additionalAttributes
-
- Type
- array
Additional tag attributes. They will be added directly to the resulting HTML tag.
aria
-
- Type
- array
Additional aria-* attributes. They will each be added with a "aria-" prefix.
checked
-
- Type
- bool
Specifies that the input element should be preselected
data
-
- Type
- array
Additional data-* attributes. They will each be added with a "data-" prefix.
errorClass
-
- Type
- string
- Default
- 'f3-form-error'
CSS class to set if there are errors for this ViewHelper
multiple
-
- Type
- bool
- Default
- false
Specifies whether this checkbox belongs to a multivalue (is part of a checkbox group)
name
-
- Type
- string
Name of input tag
property
-
- Type
- string
Name of Object Property. If used in conjunction with <f:form object="...">, the "name" property will be ignored, while "value" can be used to specify a default field value instead of the object property value.
value
-
- Type
- string
- Required
- 1
Value of input tag. Required for checkboxes