1<?php 2 3namespace Drupal\tabledrag_test\Form; 4 5use Drupal\Core\Form\FormBase; 6use Drupal\Core\Form\FormStateInterface; 7use Drupal\Core\State\StateInterface; 8use Symfony\Component\DependencyInjection\ContainerInterface; 9 10/** 11 * Provides a form for draggable table testing. 12 */ 13class TableDragTestForm extends FormBase { 14 15 /** 16 * The state service. 17 * 18 * @var \Drupal\Core\State\StateInterface 19 */ 20 protected $state; 21 22 /** 23 * Constructs a TableDragTestForm object. 24 * 25 * @param \Drupal\Core\State\StateInterface $state 26 * The state service. 27 */ 28 public function __construct(StateInterface $state) { 29 $this->state = $state; 30 } 31 32 /** 33 * {@inheritdoc} 34 */ 35 public static function create(ContainerInterface $container) { 36 return new static($container->get('state')); 37 } 38 39 /** 40 * {@inheritdoc} 41 */ 42 public function getFormId() { 43 return 'tabledrag_test_form'; 44 } 45 46 /** 47 * Builds the draggable test table. 48 * 49 * @param array $rows 50 * (optional) Rows that should be shown on the table. Default value is an 51 * empty array. 52 * @param string $table_id 53 * (optional) An HTML ID for the table, defaults to 'tabledrag-test-table'. 54 * @param string $group_prefix 55 * (optional) A prefix for HTML classes generated in the method, defaults to 56 * 'tabledrag-test'. 57 * @param bool $indentation 58 * (optional) A boolean indicating whether the rows can be indented, 59 * defaults to TRUE. 60 * 61 * @return array 62 * The renderable array of the draggable table used for testing. 63 */ 64 protected function buildTestTable(array $rows = [], $table_id = 'tabledrag-test-table', $group_prefix = 'tabledrag-test', $indentation = TRUE) { 65 $tabledrag = [ 66 [ 67 'action' => 'order', 68 'relationship' => 'sibling', 69 'group' => "$group_prefix-weight", 70 ], 71 ]; 72 73 if ($indentation) { 74 $tabledrag[] = [ 75 'action' => 'match', 76 'relationship' => 'parent', 77 'group' => "$group_prefix-parent", 78 'subgroup' => "$group_prefix-parent", 79 'source' => "$group_prefix-id", 80 'hidden' => TRUE, 81 'limit' => 2, 82 ]; 83 $tabledrag[] = [ 84 'action' => 'depth', 85 'relationship' => 'group', 86 'group' => "$group_prefix-depth", 87 'hidden' => TRUE, 88 ]; 89 } 90 91 $table = [ 92 '#type' => 'table', 93 '#header' => [ 94 [ 95 'data' => $this->t('Text'), 96 'colspan' => $indentation ? 4 : 2, 97 ], 98 $this->t('Weight'), 99 ], 100 '#tabledrag' => $tabledrag, 101 '#attributes' => ['id' => $table_id], 102 '#attached' => ['library' => ['tabledrag_test/tabledrag']], 103 ]; 104 105 // Provide a default set of five rows. 106 $rows = !empty($rows) ? $rows : 107 $this->state->get('tabledrag_test_table', array_flip(range(1, 5))); 108 109 foreach ($rows as $id => $row) { 110 if (!is_array($row)) { 111 $row = []; 112 } 113 114 $row += [ 115 'parent' => '', 116 'weight' => 0, 117 'depth' => 0, 118 'classes' => [], 119 'draggable' => TRUE, 120 ]; 121 122 if (!empty($row['draggable'])) { 123 $row['classes'][] = 'draggable'; 124 } 125 126 $table[$id] = [ 127 'title' => [ 128 'indentation' => [ 129 '#theme' => 'indentation', 130 '#size' => $indentation ? $row['depth'] : 0, 131 ], 132 '#plain_text' => "Row with id $id", 133 ], 134 'id' => [ 135 '#type' => 'hidden', 136 '#value' => $id, 137 '#parents' => ['table', $id, 'id'], 138 '#attributes' => ['class' => ["$group_prefix-id"]], 139 ], 140 '#attributes' => ['class' => $row['classes']], 141 ]; 142 143 if ($indentation) { 144 $table[$id]['parent'] = [ 145 '#type' => 'hidden', 146 '#default_value' => $row['parent'], 147 '#parents' => ['table', $id, 'parent'], 148 '#attributes' => ['class' => ["$group_prefix-parent"]], 149 ]; 150 $table[$id]['depth'] = [ 151 '#type' => 'hidden', 152 '#default_value' => $row['depth'], 153 '#parents' => ['table', $id, 'depth'], 154 '#attributes' => ['class' => ["$group_prefix-depth"]], 155 ]; 156 } 157 158 $table[$id]['weight'] = [ 159 '#type' => 'weight', 160 '#default_value' => $row['weight'], 161 '#parents' => ['table', $id, 'weight'], 162 '#attributes' => ['class' => ["$group_prefix-weight"]], 163 ]; 164 } 165 166 return $table; 167 } 168 169 /** 170 * {@inheritdoc} 171 */ 172 public function buildForm(array $form, FormStateInterface $form_state) { 173 // Provide a default set of five rows. 174 $form['table'] = $this->buildTestTable(); 175 $form['actions'] = $this->buildFormActions(); 176 177 return $form; 178 } 179 180 /** 181 * {@inheritdoc} 182 */ 183 public function submitForm(array &$form, FormStateInterface $form_state) { 184 $operation = isset($form_state->getTriggeringElement()['#op']) ? 185 $form_state->getTriggeringElement()['#op'] : 186 'save'; 187 188 switch ($operation) { 189 case 'reset': 190 $this->state->set('tabledrag_test_table', array_flip(range(1, 5))); 191 break; 192 193 default: 194 $test_table = []; 195 foreach ($form_state->getValue('table') as $row) { 196 $test_table[$row['id']] = $row; 197 } 198 $this->state->set('tabledrag_test_table', $test_table); 199 break; 200 } 201 } 202 203 /** 204 * Builds the test table form actions. 205 * 206 * @return array 207 * The renderable array of form actions. 208 */ 209 protected function buildFormActions() { 210 return [ 211 '#type' => 'actions', 212 'save' => [ 213 '#type' => 'submit', 214 '#value' => $this->t('Save'), 215 ], 216 'reset' => [ 217 '#type' => 'submit', 218 '#op' => 'reset', 219 '#value' => $this->t('Reset'), 220 ], 221 ]; 222 } 223 224} 225