Tabel: bepaal regelvolgorde

Drupal 8

Sinds Drupal 8 bestaat een formulier element type table. Hiermee kan ook tabledrag en tableselect worden ingeschakeld in een zelf te maken formulier. Hieronder wordt tabledrag uitgelegd.
Tabledrag maakt een tabel waarvan de volgorde van de regels kan worden vastgelegd / gewijzigd door deze te verschuiven of het regelvolgordernummer aan te passen.

Het resultaat van onderstaande code is:

Het resultaat bij instelling: Gewicht van rijen tonen
Het resultaat bij instelling: Gewicht van rij verbergen

De code

use Drupal\Component\Utility\String;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
 
 
/**
 * Form constructor for the administrative listing/overview form.
 */
function mymodule_admin_overview_form($form, FormStateInterface $form_state) {
  // Zorg ervoor dat de opties gesorteerd zijn op het
  // gewicht.
  // Zo niet, dan kan het resultaat verrassen.
  $options = [
    'field_rood' => ['label' => 'Rood', 'weight' => 1],
    'field_groen' => ['label' => 'Groen', 'weight' => 2],
    'field_wit' => ['label' => 'Wit', 'weight' => 5],
    'field_zwart' => ['label' => 'Zwart', 'weight' => 7],
  ];
 
  $form['mytable'] = [
    '#type' => 'table',
    '#header' => [$this->t('Label'), $this->t('Machine name'), $this->t('Weight')],
    '#empty' => $this->t('There are no items yet. <a href="@add-url">Add an item.</a>', [
      '@add-url' => Url::fromRoute('mymodule.manage_add'),
    ]),
    '#tabledrag' => [
      [
        'action' => 'order',
        'relationship' => 'sibling',
        'group' => 'mytable-order-weight',
      ],
    ],
  ];
  // Vul de tabel rijen en kolommen.
  // Het eerste niveau in de render array is de tabel rij, waarop
  // meestal de #attributes en #weight worden gezet.
  // Ieder kind element op het tweede niveau geeft een kolom cel van
  // de respectievelijke tabel rij, die zelf weer render elements
  // zijn. Staat er maar één output element in, gebruik dan de
  // waarde van de tabel cel zelf. Als er meerdere elementen in de
  // cel moeten komen, gebruik dan geneste sub-keys om de render
  // element structure te bouwen voor drupal_render() zoals
  // gebruikelijk.
  foreach ($options as $id => $option) {
    // Geef aan dat de rij van de tabel draggable is.
    $form['mytable'][$id]['#attributes']['class'][] = 'draggable';
    // Geef het huidige gewicht.
    $form['mytable'][$id]['#weight'] = $option['weight'];
 
    // De enkelvoudige inhoud van de de diverse rijen.
    $form['mytable'][$id]['label'] = [
      '#plain_text' => $option['label'],
    ];
    $form['mytable'][$id]['name'] = [
      '#plain_text' => $id,
    ];
 
    // Het kolom element: Gewicht.
    // OPMERKING: Via javascript wordt de kolom Gewicht verborgen.
    // Met de optie 'Gewicht van rij...' boven de tabel wordt de
    // kolom Gewicht (on-)zichtbaar.
    $form['mytable'][$id]['weight'] = [
      '#type' => 'weight',
      '#title' => $this->t('Weight for @title',
        ['@title' => $option['label']]),
      '#title_display' => 'invisible',
      '#default_value' => $option['weight'],
      // Maak een class voor het gewicht element voor #tabledrag.
      '#attributes' => ['class' => ['mytable-order-weight']],
    ];
  }
  $form['actions'] = ['#type' => 'actions'];
  $form['actions']['submit'] = [
    '#type' => 'submit',
    '#value' => $this->t('Save changes'),
  ];
  return $form;
}

 

Uitbreiding

Er kunnen ook meervoudige elementen in een tabel cel worden geplaatst. Gebruik de extra code fragmenten als voorbeeld.

Wijzig de #header in:

'#header' => [$this->t('Label'), $this->t('Machine name'), $this->t('Operations')],

Zet boven: ‘$form[‘actions’] …’ de volgende code:

    // Operations (dropbutton) kolom.
    $form['mytable'][$id]['operations'] = [
      '#type' => 'operations',
      '#links' => [],
    ];
    $form['mytable'][$id]['operations']['#links']['edit'] = [
      'title' => $this->t('Edit'),
      'url' => Url::fromRoute('mymodule.manage_edit', ['id' => $id]),
    ];
    $form['mytable'][$id]['operations']['#links']['delete'] = [
      'title' => $this->t('Delete'),
      'url' => Url::fromRoute('mymodule.manage_delete', ['id' => $id]),
    ];
  }

Handig

Een tabel kent geen ‘#title’ en geen ‘#description’ onderdelen. Deze zijn toch aan te maken met behulp van ‘#prefix’ en ‘#suffix’, ofwel tekst vóór het aangemaakte element en erna. Gebruik het onderstaande als idee.

    '#prefix' => '<legend><strong>' . $this->t($title) . '</strong></legend><br>',
    '#suffix' => '<div class="description">' . $this->t($description)</div>',