Drupal 8: Creating a custom field - Part 2: Field drupal widget
Jo Fitzgerald
This is part 2 in my series of articles about Drupal widgets, and specifically creating a custom field. I recommend reading Part 1: Field type first, if you have not done so already.
After creating the field type it is now time to create the field widget.
##a) Create the file
The field widget must be located as follows:
<module_name>/lib/Drupal/<module_name>/Plugin/field/widget/<field_widget_name>.php
N.B. The field widget name should be in CamelCase.
##b) Add Contains
, namespace
and use
In the newly created field type file add a brief comment to explain what it consists of:
/**
* @file
* Contains \Drupal\<module_name>\Plugin\field\widget\<field_widget_name>.
*/
N.B. The "Contains..." line should match the location and name of this file.
Then add the namespace
as follows:
namespace Drupal\<module_name>\Plugin\field\widget;
N.B. I cannot emphasise enough: it is vital that the namespace matches the location of the file otherwise it will not work.
Then add the following use
s:
use Drupal\Core\Entity\Field\FieldItemListInterface;
This provides a variable type required within the field widget class.
use Drupal\field\Plugin\Type\Widget\WidgetBase;
This provides the class that the field widget will extend.
##c) Add widget details annotation
The annotation should appear as follows:
/**
* Plugin implementation of the '<field_widget_id>' widget.
*
* @FieldWidget(
* id = "<field_widget_id>",
* label = @Translation("<field_widget_label>"),
* field_types = {
* "<field_type_id>"
* }
* )
*/
N.B. All text represented by a <placeholder> should be appropriately replaced according to requirements. The field_type_id
must match the id of a field type and the field_widget_id
should match the default widget specified in the field type (see Part 1 of this article).
##d) Add field widget class
Create the field widget class as follows:
class <field_widget_name> extends WidgetBase {
}
N.B. The <field_widget_name> must match the name of this file (case-sensitive).
The field widget class needs to contain the formElement()
function that defines how the field will appear on data input forms:
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
$element['forename'] = array(
'#title' => t('Forename'),
'#type' => 'textfield',
'#default_value' => isset($items[$delta]->forename) ? $items[$delta]->forename : NULL,
);
$element['surname'] = array(
'#title' => t('Surname'),
'#type' => 'textfield',
'#default_value' => isset($items[$delta]->surname) ? $items[$delta]->surname : NULL,
);
$element['age'] = array(
'#title' => t('Age'),
'#type' => 'number',
'#default_value' => isset($items[$delta]->age) ? $items[$delta]->age : NULL,
);
return $element;
}
The above example includes element types of textfield
and number
, other element types include:
-
radios
-
checkboxes
-
email
-
url
I intend to delve into other element types in a future article.
And there we have it: a complete (basic) field widget. Here is a simple example, similar to that described above.
Click Part 3: Field formatter to continue creating a custom field.