You are here

class WebformOptions in Webform 6.x

Same name in this branch
  1. 6.x src/Element/WebformOptions.php \Drupal\webform\Element\WebformOptions
  2. 6.x src/Entity/WebformOptions.php \Drupal\webform\Entity\WebformOptions
Same name and namespace in other branches
  1. 8.5 src/Element/WebformOptions.php \Drupal\webform\Element\WebformOptions

Provides a webform element to assist in creation of options.

This provides a nicer interface for non-technical users to add values and labels for options, possible within option groups.

Plugin annotation

@FormElement("webform_options");

Hierarchy

Expanded class hierarchy of WebformOptions

4 #type uses of WebformOptions
WebformElementOptions::processWebformElementOptions in src/Element/WebformElementOptions.php
Processes a webform element options element.
WebformLikert::form in src/Plugin/WebformElement/WebformLikert.php
Gets the actual configuration webform array to be built.
WebformOptionsCustomForm::form in modules/webform_options_custom/src/WebformOptionsCustomForm.php
Gets the actual form array to be built.
WebformUiOptionsForm::editForm in modules/webform_ui/src/WebformUiOptionsForm.php
Edit webform options source code form.

File

src/Element/WebformOptions.php, line 22

Namespace

Drupal\webform\Element
View source
class WebformOptions extends FormElement {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $class = get_class($this);
    return [
      '#input' => TRUE,
      '#yaml' => FALSE,
      '#label' => t('option'),
      '#labels' => t('options'),
      '#min_items' => 3,
      '#empty_items' => 1,
      '#add_more_items' => 1,
      '#options_value_maxlength' => 255,
      '#options_text_maxlength' => 255,
      '#options_description' => FALSE,
      '#options_description_maxlength' => NULL,
      '#process' => [
        [
          $class,
          'processWebformOptions',
        ],
      ],
      '#theme_wrappers' => [
        'form_element',
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
    if ($input === FALSE) {
      if (!isset($element['#default_value'])) {
        return [];
      }
      $options = is_string($element['#default_value']) ? Yaml::decode($element['#default_value']) : $element['#default_value'];
      if (static::hasOptGroup($options)) {
        return $options;
      }
      return static::convertOptionsToValues($options, $element['#options_description']);
    }
    elseif (is_array($input) && isset($input['options'])) {
      return is_string($input['options']) ? Yaml::decode($input['options']) : $input['options'];
    }
    else {
      return NULL;
    }
  }

  /**
   * Process options and build options widget.
   */
  public static function processWebformOptions(&$element, FormStateInterface $form_state, &$complete_form) {
    $element['#tree'] = TRUE;

    // Add validate callback that extracts the associative array of options.
    $element += [
      '#element_validate' => [],
    ];
    array_unshift($element['#element_validate'], [
      get_called_class(),
      'validateWebformOptions',
    ]);

    // Wrap this $element in a <div> that handle #states.
    WebformElementHelper::fixStatesWrapper($element);

    // For options with optgroup display a CodeMirror YAML editor.
    if (!empty($element['#yaml']) || isset($element['#default_value']) && is_array($element['#default_value']) && static::hasOptGroup($element['#default_value'])) {

      // Build table.
      $element['options'] = [
        '#type' => 'webform_codemirror',
        '#mode' => 'yaml',
        '#default_value' => WebformYaml::encode($element['#default_value']),
        '#placeholder' => t('Enter custom options…'),
        '#description' => t('Key-value pairs MUST be specified as "safe_key: \'Some readable options\'". Use of only alphanumeric characters and underscores is recommended in keys. One option per line.') . '<br /><br />' . t('Option groups can be created by using just the group name followed by indented group options.'),
      ];
      return $element;
    }
    else {
      $t_args = [
        '@label' => isset($element['#label']) ? Unicode::ucfirst($element['#label']) : t('Options'),
      ];
      $properties = [
        '#label',
        '#labels',
        '#min_items',
        '#empty_items',
        '#add_more_items',
      ];
      $element['options'] = array_intersect_key($element, array_combine($properties, $properties)) + [
        '#type' => 'webform_multiple',
        '#header' => TRUE,
        '#key' => 'value',
        '#default_value' => isset($element['#default_value']) ? static::convertOptionsToValues($element['#default_value'], $element['#options_description']) : [],
        '#add_more_input_label' => t('more @options', [
          '@options' => $element['#labels'],
        ]),
      ];
      if ($element['#options_description']) {
        $element['options']['#element'] = [
          'option_value' => [
            '#type' => 'container',
            '#title' => t('@label value', $t_args),
            '#help' => t('A unique value stored in the database.'),
            'value' => [
              '#type' => 'textfield',
              '#title' => t('@label value', $t_args),
              '#title_display' => 'invisible',
              '#placeholder' => t('Enter value…'),
              '#attributes' => [
                'class' => [
                  'js-webform-options-sync',
                ],
              ],
              '#maxlength' => $element['#options_value_maxlength'],
              '#error_no_message' => TRUE,
            ],
          ],
          'option_text' => [
            '#type' => 'container',
            '#title' => t('@label text / description', $t_args),
            '#help' => t('Enter text and description to be displayed on the form.'),
            'text' => [
              '#type' => 'textfield',
              '#title' => t('@label text', $t_args),
              '#title_display' => 'invisible',
              '#placeholder' => t('Enter text…'),
              '#maxlength' => $element['#options_text_maxlength'],
              '#error_no_message' => TRUE,
            ],
            'description' => [
              '#type' => 'textarea',
              '#title' => t('@label description', $t_args),
              '#title_display' => 'invisible',
              '#placeholder' => t('Enter description…'),
              '#rows' => 2,
              '#maxlength' => $element['#options_description_maxlength'],
              '#error_no_message' => TRUE,
            ],
          ],
        ];
      }
      else {
        $element['options']['#element'] = [
          'option_value' => [
            '#type' => 'container',
            '#title' => t('@label value', $t_args),
            '#help' => t('A unique value stored in the database.'),
            'value' => [
              '#type' => 'textfield',
              '#title' => t('@label value', $t_args),
              '#title_display' => 'invisible',
              '#placeholder' => t('Enter value…'),
              '#attributes' => [
                'class' => [
                  'js-webform-options-sync',
                ],
              ],
              '#maxlength' => $element['#options_value_maxlength'],
              '#error_no_message' => TRUE,
            ],
          ],
          'option_text' => [
            '#type' => 'container',
            '#title' => t('@label text', $t_args),
            '#help' => t('Text to be displayed on the form.'),
            'text' => [
              '#type' => 'textfield',
              '#title' => t('@label text', $t_args),
              '#title_display' => 'invisible',
              '#placeholder' => t('Enter text…'),
              '#maxlength' => $element['#options_text_maxlength'],
              '#error_no_message' => TRUE,
            ],
          ],
        ];
      }
      $element['#attached']['library'][] = 'webform/webform.element.options.admin';
      return $element;
    }
  }

  /**
   * Validates webform options element.
   */
  public static function validateWebformOptions(&$element, FormStateInterface $form_state, &$complete_form) {
    if ($form_state
      ->hasAnyErrors()) {
      return;
    }
    $options_value = NestedArray::getValue($form_state
      ->getValues(), $element['options']['#parents']);
    if (is_string($options_value)) {
      $options = Yaml::decode($options_value);
    }
    else {
      $options = static::convertValuesToOptions($options_value, $element['#options_description']);
    }

    // Validate required options.
    if (!empty($element['#required']) && empty($options)) {
      WebformElementHelper::setRequiredError($element, $form_state);
      return;
    }
    $element['#value'] = $options;
    $form_state
      ->setValueForElement($element, $options);
  }

  /****************************************************************************/

  // Helper functions.

  /****************************************************************************/

  /**
   * Convert values from yamform_multiple element to options.
   *
   * @param array $values
   *   An array of values.
   * @param bool $options_description
   *   Options has description.
   *
   * @return array
   *   An array of options.
   */
  public static function convertValuesToOptions(array $values = NULL, $options_description = FALSE) {
    $options = [];
    if ($values && is_array($values)) {
      foreach ($values as $option_value => $option) {
        $option_text = $option['text'];
        if ($options_description && !empty($option['description'])) {
          $option_text .= WebformOptionsHelper::DESCRIPTION_DELIMITER . $option['description'];
        }

        // Populate empty option value or option text.
        if ($option_value === '') {
          $option_value = $option_text;
        }
        elseif ($option_text === '') {
          $option_text = $option_value;
        }
        $options[$option_value] = $option_text;
      }
    }
    return $options;
  }

  /**
   * Convert options to values for webform_multiple element.
   *
   * @param array $options
   *   An array of options.
   * @param bool $options_description
   *   Options has description.
   *
   * @return array
   *   An array of values.
   */
  public static function convertOptionsToValues(array $options = [], $options_description = FALSE) {
    $values = [];
    foreach ($options as $value => $text) {
      if ($options_description && WebformOptionsHelper::hasOptionDescription($text)) {
        list($text, $description) = WebformOptionsHelper::splitOption($text);
        $values[$value] = [
          'text' => $text,
          'description' => $description,
        ];
      }
      else {
        $values[$value] = [
          'text' => $text,
        ];
      }
    }
    return $values;
  }

  /**
   * Determine if options array contains an OptGroup.
   *
   * @param array $options
   *   An array of options.
   *
   * @return bool
   *   TRUE if options array contains an OptGroup.
   */
  public static function hasOptGroup(array $options) {
    foreach ($options as $option_text) {
      if (is_array($option_text)) {
        return TRUE;
      }
    }
    return FALSE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property
DependencySerializationTrait::$_serviceIds protected property
DependencySerializationTrait::__sleep public function 2
DependencySerializationTrait::__wakeup public function 2
FormElement::processAutocomplete public static function Adds autocomplete functionality to elements.
FormElement::processPattern public static function #process callback for #pattern form element property.
FormElement::validatePattern public static function #element_validate callback for #pattern form element property.
MessengerTrait::$messenger protected property The messenger. 27
MessengerTrait::messenger public function Gets the messenger. 27
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 2
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginBase::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. 98
RenderElement::preRenderAjaxForm public static function Adds Ajax information about an element to communicate with JavaScript.
RenderElement::preRenderGroup public static function Adds members of this group as actual elements for rendering.
RenderElement::processAjaxForm public static function Form element processing handler for the #ajax form property. 1
RenderElement::processGroup public static function Arranges elements into groups.
RenderElement::setAttributes public static function Sets a form element's class attribute. Overrides ElementInterface::setAttributes
StringTranslationTrait::$stringTranslation protected property The string translation service. 4
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
WebformOptions::convertOptionsToValues public static function Convert options to values for webform_multiple element.
WebformOptions::convertValuesToOptions public static function Convert values from yamform_multiple element to options.
WebformOptions::getInfo public function Returns the element properties for this element. Overrides ElementInterface::getInfo
WebformOptions::hasOptGroup public static function Determine if options array contains an OptGroup.
WebformOptions::processWebformOptions public static function Process options and build options widget.
WebformOptions::validateWebformOptions public static function Validates webform options element.
WebformOptions::valueCallback public static function Determines how user input is mapped to an element's #value property. Overrides FormElement::valueCallback