Drupal Form alter; Creating conditional form elements in Drupal 8/9
Today’s topic is about how a couple of examples to create a conditional form element programmatically in Drupal and to use form alter to change the default form behaviour.
Example 1 — Conditional fields
The example shown above are two radio buttons and we need to make sure only when Yes is selected the Project types radio button is displayed.
You can use any
For this task, we can use Drupal’s HOOK_form_alter()
in a custom module.
/**
* Implements hook_form_alter().
*/
function mymodule_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Add conditional properties to fields.
$form["field_project_type"]['#states'] = [
'visible' => [
':input[data-drupal-selector="edit-field-create-project"]' => [
'checked' => '1',
],
],
'required' => [
':input[data-drupal-selector="edit-field-create-project"]' => [
'checked' => '1',
],
],
];
return $form;
}
Code Explanation
It is important to know that if you want to target a specific form you must validate using
$form_id
or use hook_form_id_alter() instead.
#states
is the array key in a form that registers conditional statements.
edit-field-create-project
is the value of data-drupal-selector
attribute in Display project field.
field_project_type
is the field name of Project Type field in the $form
Don’t mistake :input
for the type of field because it’s just a CSS selector.
You can always use :input
or any other CSS selector here, no matter whether your source is a select, radio or checkbox element.
You can use element ID or a class name instead.
i.e.
:input[id="edit-field-create-project"]
or
:input[name="create_project"]
etc..
Example 2 — Disable a field
Let's try to disable a country field so that the user will not be able to make a different selection.
if (isset($form["field_address"]["widget"][0]["subform"]["field_address_country"])) {
$form["field_address"]["widget"][0]["subform"]["field_address_country"]['#disabled'] = TRUE;
}
Example 3 — Remove an option from a radio button
// Copy existing options to a variable.
$programPageOptions = $form["field_program_page"]['widget']["#options"];// If options exists in the field, find and remove '_none'
if (array_key_exists('_none', $form["field_program_page"]['widget']["#options"])) {
unset($programPageOptions['_none']); // Re assign the updated options list.
$form["field_program_page"]['widget']["#options"] = $programPageOptions;
}
As you can see, there are a lot of possibilities to alter a form. You can show, hide, enable, disable fields or try to combine form fields to create a wizard like experience using form #states is possible.
Below are some resources with useful examples that may come in handy for you.
Happy coding !
Resources
https://www.drupal.org/docs/drupal-apis/form-api/conditional-form-fields
https://www.codimth.com/blog/web/drupal/drupal-8-disable-form-field
https://www.codimth.com/blog/web/drupal/alter-existing-form-drupal-8