Enum Form Field
The enum form field type provides a drop down list or a list box whose entries are generated from the cases of a PHP enum. Instead of repeating the same set of values in an enum and again as <option> elements in the XML, you declare them once in PHP and point the field at the enum class. If the field has a saved value this is selected when the page is first loaded. If not, the default value (if any) is selected.
This field extends ListField, so the attributes of the list form field are available as well.
The enum form field is available from Joomla 6.2 onwards. It was introduced with the Pull Request #48113.
- type (mandatory) must be enum.
- name (mandatory) is the unique name of the field.
- enum (mandatory) is the fully qualified class name of the PHP enum which provides the entries, for example
Joomla\Component\Content\Administrator\Enum\StateType. The class has to be autoloadable and has to be a PHP enum, otherwise an\InvalidArgumentExceptionis thrown when the field is rendered. - label (mandatory) (translatable) is the field html label.
- description (optional) (translatable) is the field description.
- prefix (optional) is a language key prefix used to translate the entries. Without it, the case names are displayed as they are written in the PHP enum.
- default (optional) (not translatable) is the default list item value.
- class (optional) is a CSS class name for the HTML form field.
- multiple (optional) if set to true allows multiple items to be selected at the same time. Set to false to allow single selection.
- required (optional) if set to true, the first field option should be empty, see the example with an additional option below.
- validate (optional) set to options to reject values which are not part of the list, see validate.
- useglobal (optional) if set to true, it will show the value that is set in the global configuration if found in the database.
Implemented by: libraries/src/Form/Field/EnumField.php
How the entries are built
The field calls cases() on the given enum and builds one entry per case.
The value which is saved for an entry is:
- the backing value of the case for a backed enum, so
1forcase Published = 1; - the name of the case for a pure enum, so
Publishedforcase Published;
The text which is displayed for an entry is:
- the name of the case, if no prefix attribute is given
- the translation of the language key
PREFIX_CASENAME, if a prefix attribute is given
The language key is built by joining the prefix and the case name with an underscore and converting the result to upper case. A case Published with prefix="COM_EXAMPLE_STATE" therefore uses the key COM_EXAMPLE_STATE_PUBLISHED. Note that the case name is not split up into words, so a case InProgress results in the key COM_EXAMPLE_STATE_INPROGRESS and not in COM_EXAMPLE_STATE_IN_PROGRESS.
If the language key is not defined, then the key itself is displayed in the drop down list, which makes a missing translation easy to spot.
Example enum
The examples below use this enum, stored in administrator/components/com_example/src/Enum/StateType.php:
<?php
namespace Joomla\Component\Example\Administrator\Enum;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
enum StateType: int
{
case Published = 1;
case Archived = 2;
}
Example XML parameter definition
<field
name="mystate"
type="enum"
enum="Joomla\Component\Example\Administrator\Enum\StateType"
label="Select a state"
description=""
/>
This creates a drop down list with the entries Published (value 1) and Archived (value 2).
Example XML parameter definition with translated entries
<field
name="mystate"
type="enum"
enum="Joomla\Component\Example\Administrator\Enum\StateType"
prefix="COM_EXAMPLE_STATE"
label="COM_EXAMPLE_FIELD_MYSTATE_LABEL"
description="COM_EXAMPLE_FIELD_MYSTATE_DESC"
/>
with these language strings in administrator/language/en-GB/com_example.ini:
COM_EXAMPLE_FIELD_MYSTATE_LABEL="State"
COM_EXAMPLE_FIELD_MYSTATE_DESC="The state of the item."
COM_EXAMPLE_STATE_PUBLISHED="Published"
COM_EXAMPLE_STATE_ARCHIVED="Archived"
Example XML parameter definition with an additional option
<option> elements are still taken into account and are displayed before the entries of the enum. This is the usual way to add an empty entry or a "Please Select" entry:
<field
name="mystate"
type="enum"
enum="Joomla\Component\Example\Administrator\Enum\StateType"
prefix="COM_EXAMPLE_STATE"
label="COM_EXAMPLE_FIELD_MYSTATE_LABEL"
default="0">
<option value="0">COM_EXAMPLE_STATE_NONE</option>
</field>
This creates a drop down list with three entries, None, Published and Archived, with None preselected.
The same applies to the header and useglobal attributes which are inherited from the list field: those entries are also displayed before the entries of the enum.
The entries are not checked for duplicates. If an <option> element uses a value which one of the enum cases also produces, then that value is displayed twice in the drop down list.
Validation
The field only builds the list of entries, it does not restrict what the browser may submit. Add validate="options" if the submitted value should be checked against the entries of the enum:
<field
name="mystate"
type="enum"
enum="Joomla\Component\Example\Administrator\Enum\StateType"
validate="options"
label="COM_EXAMPLE_FIELD_MYSTATE_LABEL"
/>
The options rule asks the field for its entries, so the cases of the enum are covered without having to repeat them in the XML.
Using the value in your code
The value arrives as a string from the request, so it has to be converted back into a case of the enum, for example in the model or in the table class:
use Joomla\Component\Example\Administrator\Enum\StateType;
// Backed enum: from() throws an exception for an unknown value, tryFrom() returns null.
$state = StateType::tryFrom((int) $data['mystate']);
// Pure enum: look the case up by its name.
$state = \constant(StateType::class . '::' . $data['mystate']);
When the value is saved, use $state->value for a backed enum and $state->name for a pure enum, so that the stored value matches the entry which the field displays the next time the form is loaded.