View source
<?php
namespace Drupal\webform\Element;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\Element\Table;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\webform\Plugin\WebformElement\TableSelect;
class WebformTableSort extends Table {
public function getInfo() {
$class = get_class($this);
return [
'#input' => TRUE,
'#js_select' => TRUE,
'#responsive' => TRUE,
'#sticky' => FALSE,
'#pre_render' => [
[
$class,
'preRenderTable',
],
[
$class,
'preRenderWebformTableSort',
],
],
'#process' => [
[
$class,
'processWebformTableSort',
],
],
'#options' => [],
'#empty' => '',
'#theme' => 'table__table_sort',
];
}
public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
if ($input === FALSE) {
$value = [];
$element += [
'#default_value' => [],
];
foreach ($element['#default_value'] as $key => $flag) {
if ($flag) {
$value[$key] = $key;
}
}
return $value;
}
else {
if (is_array($input)) {
uasort($input, [
'Drupal\\Component\\Utility\\SortArray',
'sortByWeightElement',
]);
$values = [];
foreach ($input as $key => $item) {
if (!empty($item['value'])) {
$values[$item['value']] = $item['value'];
}
}
return $values;
}
else {
return [];
}
}
}
public static function preRenderWebformTableSort($element) {
$rows = [];
$header = $element['#header'];
if (!empty($element['#options'])) {
foreach (Element::children($element) as $key) {
$row = [];
$row['data'] = [];
$row['class'] = [
'draggable',
];
if (isset($element['#options'][$key]['#attributes'])) {
$row += $element['#options'][$key]['#attributes'];
}
foreach ($element['#header'] as $fieldname => $title) {
if (isset($element['#options'][$key][$fieldname])) {
if (is_array($element['#options'][$key][$fieldname]) && !isset($element['#options'][$key][$fieldname]['data'])) {
foreach ($element['#options'][$key][$fieldname] as $cell) {
$row['data'][] = $cell;
}
}
else {
$row['data'][] = $element['#options'][$key][$fieldname];
}
}
}
$weight = [
$element[$key]['weight'],
$element[$key]['value'],
];
$row['data'][] = \Drupal::service('renderer')
->render($weight);
$rows[] = $row;
}
}
$header[] = t('Weight');
$element['#header'] = $header;
$element['#rows'] = $rows;
$element['#attributes']['class'][] = 'js-table-sort';
$element['#attributes']['class'][] = 'table-sort';
return $element;
}
public static function processWebformTableSort(&$element, FormStateInterface $form_state, &$complete_form) {
$value = is_array($element['#value']) ? $element['#value'] : [];
$element += [
'#element_validate' => [],
];
array_unshift($element['#element_validate'], [
get_called_class(),
'validateWebformTableSelectOrder',
]);
$element['#tree'] = TRUE;
if (count($element['#options']) > 0) {
if (!isset($element['#default_value']) || $element['#default_value'] === 0) {
$element['#default_value'] = [];
}
$options = [];
foreach ($value as $checked_option_key) {
if (isset($element['#options'][$checked_option_key])) {
$options[$checked_option_key] = $element['#options'][$checked_option_key];
unset($element['#options'][$checked_option_key]);
}
}
$options += $element['#options'];
$element['#options'] = $options;
$delta = count($element['#options']);
$weight = 0;
foreach ($element['#options'] as $key => $choice) {
if (!isset($element[$key])) {
$weight_title = '';
if ($title = TableSelect::getTableSelectOptionTitle($choice)) {
$weight_title = new TranslatableMarkup('Weight for @title', [
'@title' => $title,
]);
}
$element[$key]['value'] = [
'#type' => 'hidden',
'#value' => $key,
];
$element[$key]['weight'] = [
'#type' => 'weight',
'#title' => $weight_title,
'#title_display' => 'invisible',
'#delta' => $delta,
'#default_value' => $weight++,
'#attributes' => [
'class' => [
'table-sort-weight',
],
],
];
}
}
}
else {
$element['#value'] = [];
}
$element['#tabledrag'] = [
[
'action' => 'order',
'relationship' => 'sibling',
'group' => 'table-sort-weight',
],
];
return $element;
}
public static function validateWebformTableSelectOrder(&$element, FormStateInterface $form_state, &$complete_form) {
$checked_values = [];
foreach (Element::children($element) as $key) {
if ($element[$key]['value']['#value']) {
$checked_values[] = [
'value' => $element[$key]['value']['#value'],
'weight' => $element[$key]['weight']['#value'],
];
}
}
uasort($checked_values, [
'Drupal\\Component\\Utility\\SortArray',
'sortByWeightElement',
]);
$values = [];
foreach ($checked_values as $item) {
$values[$item['value']] = $item['value'];
}
$form_state
->setValueForElement($element, NULL);
$element['#value'] = $values;
$form_state
->setValueForElement($element, $values);
}
}