Entity view (Content)

Creating a custom field widget

By stran
Nov. 4, 2016

We're going to create a custom widget for the text field to allow users to pick a color from a color picker, rather than having to know the color codes.

Start by creating a file (let's call it ColorPickerWidget.php) inside your module directory, like so {module_name}/src/Plugin/FieldWidget/ColorPickerWIdget.php

<?php

namespace Drupal\hello\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Plugin implementation of the 'color_picker_widget' widget.
 *
 * @FieldWidget(
 *   id = "color_picker_widget",
 *   label = @Translation("Color picker widget"),
 *   field_types = {
 *     "string"
 *   }
 * )
 */
class ColorPickerWidget extends WidgetBase {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element['value'] = $element +
      [
        '#type' => 'color',
        '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
      ];

    return $element;
  }

}

The annotation

/**
 * @FieldWidget(
 *   id = "color_picker_widget",
 *   label = @Translation("Color picker widget"),
 *   field_types = {
 *     "string"
 *   }
 * )
 */

tells Drupal about our widget as well as which field types this widget belongs to. In our case, it's the plain text field type.

This class only has to implement one method (formElement) which returns the color picker we wanted 

'#type' => 'color'

If we want to allow the administrator to specify a default color, we'll need to let Drupal know what the variable names are with this

/**
 * {@inheritdoc}
 */
public static function defaultSettings() {
  return [
    'default_color' => '',
  ] + parent::defaultSettings();
}

Then show that setting on the widget configuration form

/**
 * {@inheritdoc}
 */
public function settingsForm(array $form, FormStateInterface $form_state) {
  $elements = [];

  $elements['default_color'] = [
    '#type' => 'textfield',
    '#title' => t('Default color'),
    '#default_value' => $this->getSetting('default_color'),
  ];

  return $elements;
}

and display the summary on the form display admin page

/**
 * {@inheritdoc}
 */
public function settingsSummary() {
  $summary = [];

  if (!empty($this->getSetting('default_color'))) {
    $summary[] = t('Default color: @placeholder', [
      '@placeholder' => $this->getSetting('default_color'),
    ]);
  }

  return $summary;
}
Post Tags: