You are here

public static function YamlFormElementStates::processYamlFormStates in YAML Form 8

Expand an email confirm field into two HTML5 email elements.

File

src/Element/YamlFormElementStates.php, line 65

Class

YamlFormElementStates
Provides a form element to edit an element's #states.

Namespace

Drupal\yamlform\Element

Code

public static function processYamlFormStates(&$element, FormStateInterface $form_state, &$complete_form) {

  // Define default #state_options and #trigger_options.
  // There are also defined by \Drupal\yamlform\YamlFormElementBase::form.
  $element += [
    '#state_options' => [
      'enabled' => t('Enabled'),
      'disabled' => t('Disabled'),
      'required' => t('Required'),
      'optional' => t('Optional'),
      'visible' => t('Visible'),
      'invisible' => t('Invisible'),
      'checked' => t('Checked'),
      'unchecked' => t('Unchecked'),
      'expanded' => t('Expanded'),
      'collapsed' => t('Collapsed'),
    ],
    '#trigger_options' => [
      'empty' => t('Empty'),
      'filled' => t('Filled'),
      'checked' => t('Checked'),
      'unchecked' => t('Unchecked'),
      'expanded' => t('Expanded'),
      'collapsed' => t('Collapsed'),
      'value' => t('Value is'),
    ],
  ];
  $element['#tree'] = TRUE;

  // Add validate callback that extracts the associative array of states.
  $element['#element_validate'] = [
    [
      get_called_class(),
      'validateYamlFormElementStates',
    ],
  ];

  // For customized #states display a CodeMirror YAML editor.
  if ($warning_message = self::isDefaultValueCustomizedFormApiStates($element)) {
    $warning_message .= ' ' . t('Form API #states must be manually entered.');
    $element['messages'] = [
      '#type' => 'yamlform_message',
      '#message_type' => 'warning',
      '#message_message' => $warning_message,
    ];
    $element['states'] = [
      '#type' => 'yamlform_codemirror',
      '#mode' => 'yaml',
      '#default_value' => YamlFormTidy::tidy(Yaml::encode($element['#default_value'])),
      '#description' => t('Learn more about Drupal\'s <a href=":href">Form API #states</a>.', [
        ':href' => 'https://www.lullabot.com/articles/form-api-states',
      ]),
    ];
    return $element;
  }
  $table_id = implode('_', $element['#parents']) . '_table';

  // Store the number of rows.
  $storage_key = self::getStorageKey($element, 'number_of_rows');
  if ($form_state
    ->get($storage_key) === NULL) {
    if (empty($element['#default_value']) || !is_array($element['#default_value'])) {
      $number_of_rows = 2;
    }
    else {
      $number_of_rows = count($element['#default_value']);
    }
    $form_state
      ->set($storage_key, $number_of_rows);
  }
  $number_of_rows = $form_state
    ->get($storage_key);

  // DEBUG: Disable AJAX callback by commenting out the below callback and
  // wrapper.
  $ajax_settings = [
    'callback' => [
      get_called_class(),
      'ajaxCallback',
    ],
    'wrapper' => $table_id,
  ];

  // Build header.
  $header = [
    [
      'data' => t('State'),
      'width' => '20%',
    ],
    [
      'data' => t('Element/Selector'),
      'width' => '45%',
    ],
    [
      'data' => t('Trigger'),
      'width' => '20%',
    ],
    [
      'data' => t('Value'),
      'width' => '10%',
    ],
    [
      'data' => '',
    ],
  ];

  // Get states and number of rows.
  if ($form_state
    ->isRebuilding()) {
    $states = $element['#value'];
  }
  else {
    $states = isset($element['#default_value']) ? self::convertFormApiStatesToStatesArray($element['#default_value']) : [];
  }

  // Build state and conditions rows.
  $row_index = 0;
  $rows = [];
  foreach ($states as $state_settings) {
    $rows[$row_index] = self::buildStateRow($element, $state_settings, $table_id, $row_index, $ajax_settings);
    $row_index++;
    foreach ($state_settings['conditions'] as $condition) {
      $rows[$row_index] = self::buildConditionRow($element, $condition, $table_id, $row_index, $ajax_settings);
      $row_index++;
    }
  }

  // Generator empty state with conditions rows.
  if ($row_index < $number_of_rows) {
    $rows[$row_index] = self::buildStateRow($element, [], $table_id, $row_index, $ajax_settings);
    $row_index++;
    while ($row_index < $number_of_rows) {
      $rows[$row_index] = self::buildConditionRow($element, [], $table_id, $row_index, $ajax_settings);
      $row_index++;
    }
  }

  // Build table.
  $element['states'] = [
    '#prefix' => '<div id="' . $table_id . '" class="yamlform-states-table">',
    '#suffix' => '</div>',
    '#type' => 'table',
    '#header' => $header,
  ] + $rows;

  // Build add state action.
  $element['add'] = [
    '#type' => 'submit',
    '#value' => t('Add another state'),
    '#limit_validation_errors' => [],
    '#submit' => [
      [
        get_called_class(),
        'addStateSubmit',
      ],
    ],
    '#ajax' => $ajax_settings,
    '#name' => $table_id . '_add',
  ];
  $element['#attached']['library'][] = 'yamlform/yamlform.element.states';
  $element['#attached']['library'][] = 'yamlform/yamlform.element.select2';
  return $element;
}