Form Render Elements
When to Use
Form elements can be used outside of forms as render-only elements when you need their HTML structure but not their input functionality. Inside forms, they become interactive with validation and submission handling.
Decision: Form Element Context
| Context | Behavior | Example Use |
|---|---|---|
| Inside a form (via FormBuilderInterface) | Full form functionality: validation, submission, CSRF, states | User registration, node edit, admin config |
| Outside a form (in render array) | Renders HTML only, no interactivity | Display-only representation, documentation examples |
| Tableselect pattern | Special hybrid -- table + checkboxes with bulk operations | Views bulk operations, admin lists |
Common Form Elements (Render-Only)
Note: These examples show render-only usage. For full form functionality, use Form API's buildForm().
textfield
// Render-only (display purposes)
$build['name_display'] = [
'#type' => 'textfield',
'#title' => $this->t('Username'),
'#value' => 'example_user',
'#disabled' => TRUE,
'#attributes' => ['readonly' => 'readonly'],
];
Properties: #title, #default_value, #size, #maxlength, #placeholder, #required, #disabled
select
// Render-only dropdown
$build['role_display'] = [
'#type' => 'select',
'#title' => $this->t('User Role'),
'#options' => [
'admin' => $this->t('Administrator'),
'editor' => $this->t('Editor'),
'viewer' => $this->t('Viewer'),
],
'#value' => 'editor',
'#disabled' => TRUE,
];
Properties: #options (required), #empty_option, #empty_value, #multiple
checkbox / checkboxes
// Single checkbox
$build['agree_display'] = [
'#type' => 'checkbox',
'#title' => $this->t('I agree'),
'#return_value' => '1',
'#disabled' => TRUE,
];
// Multiple checkboxes
$build['permissions'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Permissions'),
'#options' => [
'create' => $this->t('Create content'),
'edit' => $this->t('Edit content'),
'delete' => $this->t('Delete content'),
],
'#default_value' => ['create', 'edit'],
'#disabled' => TRUE,
];
radios
$build['choice'] = [
'#type' => 'radios',
'#title' => $this->t('Select One'),
'#options' => ['yes' => $this->t('Yes'), 'no' => $this->t('No')],
'#default_value' => 'yes',
'#disabled' => TRUE,
];
Pattern: Table with Form Elements (Tableselect)
// Inside a form
$form['users'] = [
'#type' => 'tableselect',
'#header' => [
'name' => $this->t('Name'),
'role' => $this->t('Role'),
],
'#options' => [
1 => ['name' => 'Alice', 'role' => 'Admin'],
2 => ['name' => 'Bob', 'role' => 'Editor'],
],
'#empty' => $this->t('No users found.'),
];
Reference: core/lib/Drupal/Core/Render/Element/Tableselect.php
Common Mistakes
- Using form elements outside forms and expecting them to work -- They render HTML but won't process submissions
- Forgetting
#disabled => TRUEin render-only context -- User might think they can interact with it - Not setting
#default_valueor#value-- Elements render empty even in display mode - Mixing
#valueand#default_value-- Use#default_valuein forms,#valuefor render-only
See Also
- Core Render Elements for non-form elements
- Reference: Drupal Form API Guide (separate guide)
- Reference: Form Render Elements