0

I've tried to create custom Webform elements, either radios or check-boxes. The elements are available in the Webform UI for administrator users; I can add them to webforms from the build section, but they are not getting rendered in the webform. I have no idea what I'm missing.

(Note: I have created custom elements whose type is textfield, selectbox, and autocomplete; they all work fine.)

The following is my custom src/Element and src/Plugin/WebformElement code.

src/Element/MyCustomRadio.php

namespace Drupal\my_custom_element\Element;

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

/**
 * @FormElement("my_custom_element")
 *
 */
class MyCustomRadio extends Radios {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $class = get_class($this);
    return [
      '#input' => TRUE,
      '#size' => 60,
      '#process' => [
        [$class, 'processMyCustomRadio'],
        [$class, 'processAjaxForm'],
      ],
      '#element_validate' => [
        [$class, 'validateMyCustomRadio'],
      ],
      '#pre_render' => [
        [$class, 'preRenderMyCustomRadio'],
      ],
      '#theme' => 'input__my_custom_element',
      '#theme_wrappers' => ['form_element'],
    ];
  }

  public static function processMyCustomRadio(&$element, FormStateInterface $form_state, &$complete_form) {
    // Here you can add and manipulate your element's properties and callbacks.
    return $element;
  }

  public static function validateMyCustomRadio(&$element, FormStateInterface $form_state, &$complete_form) {
    // Here you can add custom validation logic.
  }

  /**
   * @param array $element
   * @return array
   */
  public static function preRenderMyCustomRadio(array $element) {
    $element['#attributes']['type'] = 'checkboxes';
    Element::setAttributes($element, ['id', 'name','value']);
    static::setAttributes($element, ['form-text', 'my-custom-element']);
    return $element;
  }

}

src/Plugin/WebformElement/MyCustomRadio.php

namespace Drupal\my_custom_element\Plugin\WebformElement;

use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Plugin\WebformElement\Radios;
use Drupal\webform\Plugin\WebformElementBase;
use Drupal\webform\WebformSubmissionInterface;

/**
 * Provides a 'my_custom_element' element.
 *
 * @WebformElement(
 *   id = "my_custom_radio_element",
 *   label = @Translation("My Custom Radio"),
 *   description = @Translation("Provides a webform radio element."),
 *   category = @Translation("My Custom elements"),
 * )
 */
class MyCustomRadio extends Radios {

  /**
   * {@inheritdoc}
   */
  protected function defineDefaultProperties() {

    return [
      'multiple' => '',
      'size' => '',
      'minlength' => '',
      'maxlength' => '',
      'placeholder' => '',
    ] + parent::defineDefaultProperties();
  }

  /**
   * {@inheritdoc}
   */
  public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
    parent::prepare($element, $webform_submission);
    
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    $form = parent::form($form, $form_state);
    return $form;
  }

}

In the administrator panel, I have the option to add custom radios in my form.

screenshot

In the front-end, custom radios are not rendered; only default radios and checkboxes are rendered.

screenshot

1 Answer 1

3

For radios or checkboxes to work you need to call

\Drupal\Core\Render\Element\Checkboxes::processCheckboxes

or

\Drupal\Core\Render\Element\Radios::processRadios

Your example code, is extending Radios but trying to render checkboxes. I recommend extending Checkboxes and gradually override the default methods including \Drupal\Core\Render\Element\Checkboxes::processCheckboxes.

Below is an example

<?php

namespace Drupal\my_custom_element\Element;

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

/**
 * Provides a form element for a set of My custom element.
 *
 * @FormElement("my_custom_element")
 */
class MyCustomElement extends Checkboxes {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $properties = parent::getInfo();
    // My custom properties.
    $class = get_class($this);
    $properties['#process'][] = [$class, 'processMyCustomElement'];
    $properties['#element_validate'] = [[$class, 'validateMyCustomRadio']];
    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public static function processCheckboxes(&$element, FormStateInterface $form_state, &$complete_form) {
    // You can override and extend this method.
    $element = parent::processCheckboxes($element, $form_state, $complete_form)
    return $element;
  }

  public static function processMyCustomRadio(&$element, FormStateInterface $form_state, &$complete_form) {
    // Here you can add and manipulate your element's properties and callbacks.
    return $element;
  }

  public static function validateMyCustomRadio(&$element, FormStateInterface $form_state, &$complete_form) {
    // Here you can add custom validation logic.
  }
}

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.