Commit a1969bb5 authored by Jacob Rockowitz's avatar Jacob Rockowitz Committed by Jacob Rockowitz
Browse files

Issue #2854879 by jrockowitz: Ability to limit the number of allowed values

parent b3c237e5
Loading
Loading
Loading
Loading
+3 −3
Changes for modules/webform_ui/src/Tests/WebformUiElementTest.php: 3 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -52,14 +52,14 @@ class WebformUiElementTest extends WebformTestBase {

    // Check multiple enabled before submission.
    $this->drupalGet('admin/structure/webform/manage/contact/element/name/edit');
    $this->assertRaw('<input data-drupal-selector="edit-properties-multiple" aria-describedby="edit-properties-multiple--description" type="checkbox" id="edit-properties-multiple" name="properties[multiple]" value class="form-checkbox" />');
    $this->assertRaw('<select data-drupal-selector="edit-properties-multiple-container-cardinality" id="edit-properties-multiple-container-cardinality" name="properties[multiple][container][cardinality]" class="form-select">');
    $this->assertNoRaw('<em>There is data for this element in the database. This settings can no longer be changed.</em>');

    // Check multiple disabled after submission.
    $this->postSubmissionTest($webform_contact);
    $this->drupalGet('admin/structure/webform/manage/contact/element/name/edit');
    $this->assertNoRaw('<input data-drupal-selector="edit-properties-multiple" aria-describedby="edit-properties-multiple--description" type="checkbox" id="edit-properties-multiple" name="properties[multiple]" value class="form-checkbox" />');
    $this->assertRaw('<input data-drupal-selector="edit-properties-multiple" aria-describedby="edit-properties-multiple--description" disabled="disabled" type="checkbox" id="edit-properties-multiple" name="properties[multiple]" value class="form-checkbox" />');
    $this->assertNoRaw('<select data-drupal-selector="edit-properties-multiple-container-cardinality" id="edit-properties-multiple-container-cardinality" name="properties[multiple][container][cardinality]" class="form-select">');
    $this->assertRaw('<select data-drupal-selector="edit-properties-multiple-container-cardinality" disabled="disabled" id="edit-properties-multiple-container-cardinality" name="properties[multiple][container][cardinality]" class="form-select">');
    $this->assertRaw('<em>There is data for this element in the database. This settings can no longer be changed.</em>');

    /**************************************************************************/
+2 −2
Changes for src/Ajax/ScrollTopCommand.php: 2 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -32,10 +32,10 @@ class ScrollTopCommand implements CommandInterface {
   * {@inheritdoc}
   */
  public function render() {
    return array(
    return [
      'command' => 'webformScrollTop',
      'selector' => $this->selector,
    );
    ];
  }

}
+140 −0
Changes for src/Element/WebformElementMultiple.php: 140 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

namespace Drupal\webform\Element;

use Drupal\Component\Utility\Unicode;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\FormElement;
use Drupal\Core\Serialization\Yaml;
use Drupal\webform\Utility\WebformYaml;

/**
 * Provides a webform element for element multiple property.
 *
 * This element displays the #multiple property so that it looks like
 * the cardinality setting included in the Field API.
 *
 * @FormElement("webform_element_multiple")
 *
 * @see \Drupal\field_ui\Form\FieldStorageConfigEditForm::form
 */
class WebformElementMultiple extends FormElement {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $class = get_class($this);
    return [
      '#input' => TRUE,
      '#min' => 1,
      '#process' => [
        [$class, 'processWebformElementMultiple'],
      ],
      '#theme_wrappers' => ['form_element'],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
    if ($input === FALSE) {
      if (empty($element['#default_value'])) {
        return 1;
      }
      elseif ($element['#default_value'] === TRUE) {
        return WebformMultiple::CARDINALITY_UNLIMITED;
      }
      else {
        return $element['#default_value'];
      }
    }

    return NULL;
  }

  /**
   * Processes element multiple.
   */
  public static function processWebformElementMultiple(&$element, FormStateInterface $form_state, &$complete_form) {
    $cardinality = $element['#value'];

    $element['#tree'] = TRUE;
    
    $element['container'] = [
      '#type' => 'container',
      '#attributes' => ['class' => [
        'container-inline',
      ]],
    ];

    $element['container']['cardinality'] = [
      '#type' => 'select',
      '#title' => t('Allowed number of values'),
      '#title_display' => 'invisible',
      '#options' => [
        'number' => t('Limited'),
        WebformMultiple::CARDINALITY_UNLIMITED => t('Unlimited'),
      ],
      '#default_value' => ($cardinality == WebformMultiple::CARDINALITY_UNLIMITED) ? WebformMultiple::CARDINALITY_UNLIMITED : 'number',
    ];
    $element['container']['cardinality_number'] = [
      '#type' => 'number',
      '#default_value' => $cardinality != WebformMultiple::CARDINALITY_UNLIMITED ? $cardinality : $element['#min'],
      '#min' => $element['#min'],
      '#title' => t('Limit'),
      '#title_display' => 'invisible',
      '#size' => 2,
      '#states' => [
        'visible' => [
          ':input[data-drupal-selector="edit-' . implode('-', $element['#parents']) . '-container-cardinality"]' => ['value' => 'number'],
        ],
      ],
    ];

    // Set disabled
    if (!empty($element['#disabled'])) {
      $element['container']['cardinality']['#disabled'] = TRUE;
      $element['container']['cardinality_number']['#disabled'] = TRUE;
    }

    // Set validation.
    if (isset($element['#element_validate'])) {
      $element['#element_validate'] = array_merge([[get_called_class(), 'validateWebformElementMultiple']], $element['#element_validate']);
    }
    else {
      $element['#element_validate'] = [[get_called_class(), 'validateWebformElementMultiple']];
    }

    return $element;
  }

  /**
   * Validates element multiple.
   */
  public static function validateWebformElementMultiple(&$element, FormStateInterface $form_state, &$complete_form) {
    if (!empty($element['#disabled'])) {
      $multiple = $element['#default_value'];
    }
    else {
      $cardinality = $element['#value']['container']['cardinality'];
      $cardinality_number = (int) $element['#value']['container']['cardinality_number'];

      if ($cardinality == WebformMultiple::CARDINALITY_UNLIMITED) {
        $multiple = TRUE;
      }
      elseif ($cardinality_number === 1) {
        $multiple = FALSE;
      }
      else {
        $multiple = $cardinality_number;
      }
    }

    $form_state->setValueForElement($element['container']['cardinality'], NULL);
    $form_state->setValueForElement($element['container']['cardinality_number'], NULL);
    $form_state->setValueForElement($element, $multiple);
  }

}
+5 −0
Changes for src/Element/WebformMultiple.php: 5 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -15,6 +15,11 @@ use Drupal\webform\Utility\WebformElementHelper;
 */
class WebformMultiple extends FormElement {

  /**
   * Value indicating a element accepts an unlimited number of values.
   */
  const CARDINALITY_UNLIMITED = -1;

  /**
   * {@inheritdoc}
   */
+6 −6
Changes for src/Plugin/Condition/Webform.php: 6 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -67,12 +67,12 @@ class Webform extends ConditionPluginBase implements ContainerFactoryPluginInter
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $options = array();
    $options = [];
    $webforms = $this->entityStorage->loadMultiple();
    foreach ($webforms as $webform) {
      $options[$webform->id()] = $webform->label();
    }
    $form['webforms'] = array(
    $form['webforms'] = [
      '#title' => $this->t('Webform'),
      '#description' => $this->t('Select which webforms this block should be displayed on.'),
      '#type' => 'select',
@@ -81,7 +81,7 @@ class Webform extends ConditionPluginBase implements ContainerFactoryPluginInter
      '#default_value' => $this->configuration['webforms'],
      '#attached' => ['library' => ['webform/webform.element.select2']],
      '#attributes' => ['class' => ['js-webform-select2', 'webform-select2']],
    );
    ];

    if (empty($this->configuration['context_mapping'])) {
      $form['message'] = [
@@ -136,10 +136,10 @@ class Webform extends ConditionPluginBase implements ContainerFactoryPluginInter
      $webforms = $this->configuration['webforms'];
      $last = array_pop($webforms);
      $webforms = implode(', ', $webforms);
      return $this->t('The webform is @webforms or @last', array('@webforms' => $webforms, '@last' => $last));
      return $this->t('The webform is @webforms or @last', ['@webforms' => $webforms, '@last' => $last]);
    }
    $webform = reset($this->configuration['webforms']);
    return $this->t('The webform is @webform', array('@webform' => $webform));
    return $this->t('The webform is @webform', ['@webform' => $webform]);
  }

  /**
@@ -161,7 +161,7 @@ class Webform extends ConditionPluginBase implements ContainerFactoryPluginInter
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return array('webforms' => array()) + parent::defaultConfiguration();
    return ['webforms' => []] + parent::defaultConfiguration();
  }

  /**
Loading