4

I'm creating a new field in Drupal 8. I've created a class for the widget, extending WidgetBase and implementing WidgetInterface, and added the functions defaultSettings(), settingsForm() and settingsSummary().

I want/need to validate the element I'm adding in settingsForm(), but I can't seem to figure out how to add validation to this. I tried adding a function settingsFormValidate(), but that doesn't seem to be called. I also tried adding #element_validate to the element I'm adding in settingsForm(), but that also does not seem to be called.

Note that I'm not looking to validate the widget (that is shown to the user), I'm looking to validate the element added in settingsForm() for the widget, that is on the Manage Form Display tab, when adding the field to Entities/content types.

Does anyone know how or whether it's even possible to add validation to the widget settings form?

2 Answers 2

7

Once again, I've found the solution to my issue. Although I said that I had tried #element_validate in my original post, I must have messed something up, because that turned out to be the solution. Here is the code:

class SomeWidget extends WidgetBase implements WidgetInterface
{
  public function settingsForm(array $form, FormStateInterface $form_state)
  {
    $element['my_field'] = [
      '#type' => 'textfield',
      '#title' => t('My Field'),
      '#default_value' => $this->getSetting('my_field'),
      '#required' => TRUE,
      // Add your validation here
      '#element_validate' => [
        // settingsFormMyFieldValidate() is arbitrary. Choose something descriptive
        [$this, 'settingsFormMyFieldValidate'],
      ],
    ];

    return $element;
  }

  public function settingsFormMyFieldValidate($element, FormStateInterface $form_state)
  {
    $submitted_value = $form_state->getValue($element['#parents']);
    if($submitted_value != 'something it should equal')
    {
      $form_state->setError($element, t('You submitted a bad value'));
    }
  }
}
2
  • I think the validator is executed within an asynchronous callback when submitting the widget settings form. As a result, use '#element_validate' => [[static::class, 'validate']], and public static function validate
    – Jason
    Feb 29 at 15:14
  • Also, be aware of "A field widget that fails validation in settingsForm() does not display an error message without inline_form_errors" issue @ drupal.org/project/drupal/issues/3407134
    – Jason
    Feb 29 at 15:23
4

There is a field_example module in the examples module. It includes a TextWidget and Text3Widget, both of which have a validation function on their formElement.

/**
 * Plugin implementation of the 'field_example_text' widget.
 *
 * @FieldWidget(
 *   id = "field_example_text",
 *   module = "field_example",
 *   label = @Translation("RGB value as #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 += array(
      '#type' => 'textfield',
      '#default_value' => $value,
      '#size' => 7,
      '#maxlength' => 7,
      '#element_validate' => array(
        array($this, 'validate'),
      ),
    );
    return array('value' => $element);
  }

  /**
   * Validate the color text field.
   */
  public 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("Color must be a 6-digit hexadecimal value, suitable for CSS."));
    }
  }
}

I hope this points you to the right direction.

3
  • Thanks, but that's for the form element itself. I need to validate the settings form of the Field - I've already handled the element level validation.
    – Jaypan
    Jan 8, 2017 at 0:48
  • I think the validator is executed within an asynchronous callback when submitting the widget settings form. As a result, use '#element_validate' => [[static::class, 'validate']], and public static function validate
    – Jason
    Feb 29 at 15:14
  • Also, be aware of "A field widget that fails validation in settingsForm() does not display an error message without inline_form_errors" issue @ drupal.org/project/drupal/issues/3407134
    – Jason
    Feb 29 at 15:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.