Creaci贸n de un widget para campo
Los widgets de campo se utilizan para visualizar un campo dentro de formularios. Los widgets de campo se definen como plugins, por lo que se recomienda revisar la API de plugins antes de comenzar a crear un nuevo tipo de widget para campo.
Para crear un widget de campo en Drupal 8, necesitas una clase con la anotaci贸n FieldWidget.
La ubicaci贸n de la clase del widget debe ser /[NOMBRE_DEL_M脫DULO]/src/Plugin/Field/FieldWidget. Por ejemplo, /foo/src/Plugin/Field/FieldWidget/BarWidget.php.
El namespace de esta clase debe ser [NOMBRE_DEL_M脫DULO]\Plugin\Field\FieldWidget. Por ejemplo, \Drupal\foo\Plugin\Field\FieldWidget.
La anotaci贸n sobre la clase debe incluir un ID 煤nico, etiqueta y un arreglo de IDs de tipos de campo que el widget pueda manejar.
/**
* Un widget bar.
*
* @FieldWidget(
* id = "bar",
* label = @Translation("Widget Bar"),
* field_types = {
* "baz",
* "string"
* }
* )
*/
La clase debe implementar la interfaz WidgetInterface. Puede extender WidgetBase para la implementaci贸n com煤n de la interfaz. El 煤nico m茅todo obligatorio a implementar es ::formElement(), que debe devolver los elementos reales del formulario que representan tu widget.
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
//...
class BarWidget extends WidgetBase {
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = [];
// Construye el array render de elemento.
return $element;
}
}
Configuraciones del widget
Si tu widget necesita configuraciones adicionales, debes hacer tres pasos:
- Sobre-escribir PluginSettingsBase::defaultSettings() para definir valores por defecto
- Crear un esquema de configuraci贸n para esas opciones
- Crear un formulario para permitir que usuarios modifiquen esas configuraciones
Paso 1: Sobre-escribe PluginSettingsBase::defaultSettings() para definir valores por defecto
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
// Crea la configuraci贸n personalizada 'size' con valor por defecto 60
'size' => 60,
] + parent::defaultSettings();
}
Paso 2: Crear esquema de configuraci贸n para las opciones
El esquema se coloca en:
/[NOMBRE_DEL_M脫DULO]/config/schema/[NOMBRE_DEL_M脫DULO].schema.yml
En este archivo defines los tipos de datos de las opciones creadas en defaultSettings():
Por ejemplo, la opci贸n 'size' es un entero, el esquema se ver谩 as铆:
field.widget.settings.[ID_DEL_WIDGET]:
type: mapping
label: 'Configuraciones del widget WIDGET NAME'
mapping:
size:
type: integer
label: 'Tama帽o'
Paso 3: Crear formulario para permitir editar configuraciones
Este formulario se crea sobre-escribiendo WidgetBase::settingsForm().
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$element['size'] = [
'#type' => 'number',
'#title' => $this->t('Tama帽o del campo de texto'),
'#default_value' => $this->getSetting('size'),
'#required' => TRUE,
'#min' => 1,
];
return $element;
}
Tambi茅n puedes mostrar un resumen de las configuraciones elegidas para el widget as铆:
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = [];
$summary[] = $this->t('Tama帽o del campo de texto: @size', ['@size' => $this->getSetting('size')]);
return $summary;
}
Puedes usar el m茅todo getSetting() para obtener la configuraci贸n en el widget:
class BarWidget extends WidgetBase implements WidgetInterface {
class BarWidget extends WidgetBase implements WidgetInterface {
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element['value'] = $element + [
'#type' => 'textfield',
'#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
'#size' => $this->getSetting('size'),
];
return $element;
}
}
Ejemplo de widget
TextWidget del m贸dulo field_example del m贸dulo Examples:
namespace Drupal\field_example\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Implementaci贸n del plugin widget 'field_example_text'.
*
* @FieldWidget(
* id = "field_example_text",
* module = "field_example",
* label = @Translation("Valor RGB como #ffffff"),
* field_types = {
* "field_example_rgb"
* }
* )
*/
class TextWidget extends WidgetBase {
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$value = isset($items[$delta]->value) ? $items[$delta]->value : '';
$element += [
'#type' => 'textfield',
'#default_value' => $value,
'#size' => 7,
'#maxlength' => 7,
'#element_validate' => [
[static::class, 'validate'],
],
];
return ['value' => $element];
}
/**
* Valida el campo de texto para color.
*/
public static function validate($element, FormStateInterface $form_state) {
$value = $element['#value'];
if (strlen($value) == 0) {
$form_state->setValueForElement($element, '');
return;
}
if (!preg_match('/^#([a-f0-9]{6})$/iD', strtolower($value))) {
$form_state->setError($element, t("El color debe ser un valor hexadecimal de 6 d铆gitos, v谩lido para CSS."));
}
}
}