2

I am trying to create a custom Webform element that can be added to any webform. It is a select list, but I am providing the options from a remote API call (they cannot be static or hardcoded).

I can get the element to appear in the admin UI with:

use Drupal\webform\Plugin\WebformElement\Select;

/**
 * Provides a 'tour type' element.
 *
 * @WebformElement(
 *   id = "tour_type",
 *   label = @Translation("Tour Type"),
 *   description = @Translation("Provides a form element to list tour types from Funnel."),
 *   category = @Translation("Options elements"),
 * )
 */
class TourType extends Select {

}

I can add it to a form, and give it options like a regular Select in Webform, but nothing renders on the form.

I was trying to follow this here, but don't quite understand what needs to be done: Why do my custom elements not get rendered?

Do I need a WebformElement plugin, or a new Element class? I don't see how the two are correlated.

2 Answers 2

5

You need to create a 'Form Element' to process, validate, and render an input and corresponding 'WebformElement' to integrate the input with the Webform module.

You can use the Webform Example Element module as a starting point.

2
  • 1
    That is what I followed, eventually I got it. Does the WebformElement id property need to match the FormElement you create? I think that is where I got hung up.
    – Kevin
    Jan 5, 2021 at 18:25
  • 4
    Yes, the WebformElement and the FormElement need to have the same id.
    – jrockowitz
    Jan 6, 2021 at 1:20
0

For the record, if you just want to display static or computed data, here's the most basic webform element:

<?php
namespace Drupal\your_module\Plugin\WebformElement;

use Drupal\webform\Plugin\WebformElement\WebformMarkup;
use Drupal\webform\WebformSubmissionInterface;
    

/**
 * Provides a static webform element.
 *
 * @WebformElement(
 *   id = "webform_your_module",
 *   label = @Translation("Human element name"),
 *   description = @Translation("Element description"),
 *   category = @Translation("Choose an existing category or use a new one"),
 *   states_wrapper = TRUE,
 * )
 */
class YourModuleWebformElement extends WebformMarkup {

  /**
   * Optional: only needed if you want to set a human title in the UI
   * {@inheritdoc}
   */
  protected function defineDefaultProperties() {
    return parent::defineDefaultProperties() + [
        'title' => '',
      ];
  }

  public function isInput(array $element) {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function isContainer(array $element) {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
    $element['#title'] = '';
    $element[] = [
      '#markup' => 'My text',
    ];
    parent::prepare($element, $webform_submission);
  }

}

As said above, you need matching element

<?php

namespace Drupal\your_module\Element;

use Drupal\Core\Render\Element;
use Drupal\Core\Render\Element\FormElement;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provides an fake element for 'YourModuleWebformElement'.
 *
 * @FormElement("webform_recapitulatif_rac")
 *
 * @see \Drupal\Core\Render\Element\FormElement
 * @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21FormElement.php/class/FormElement
 * @see \Drupal\Core\Render\Element\RenderElement
 * @see https://api.drupal.org/api/drupal/namespace/Drupal%21Core%21Render%21Element
 * @see \Drupal\your_module\Element\YourModuleWebformElement
 */
class YourModuleWebformElement extends FormElement {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    return [
      '#input' => FALSE
    ];
  }

}

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.