View source
<?php
namespace Drupal\views\Plugin\views\style;
use Drupal\Component\Utility\Html;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\wizard\WizardInterface;
class Table extends StylePluginBase implements CacheableDependencyInterface {
protected $usesFields = TRUE;
protected $usesRowPlugin = FALSE;
protected $usesRowClass = TRUE;
protected $defaultFieldLabels = TRUE;
public $active;
public $order;
protected function defineOptions() {
$options = parent::defineOptions();
$options['columns'] = [
'default' => [],
];
$options['default'] = [
'default' => '',
];
$options['info'] = [
'default' => [],
];
$options['override'] = [
'default' => TRUE,
];
$options['sticky'] = [
'default' => FALSE,
];
$options['order'] = [
'default' => 'asc',
];
$options['caption'] = [
'default' => '',
];
$options['summary'] = [
'default' => '',
];
$options['description'] = [
'default' => '',
];
$options['empty_table'] = [
'default' => FALSE,
];
return $options;
}
public function buildSort() {
$order = $this->view
->getRequest()->query
->get('order');
if (!isset($order) && ($this->options['default'] == -1 || empty($this->view->field[$this->options['default']]))) {
return TRUE;
}
if (isset($order) && empty($this->view->field[$order])) {
return TRUE;
}
return empty($this->options['override']);
}
public function buildSortPost() {
$query = $this->view
->getRequest()->query;
$order = $query
->get('order');
if (!isset($order)) {
if (empty($this->options['default'])) {
return;
}
$sort = $this->options['default'];
if (!empty($this->options['info'][$sort]['default_sort_order'])) {
$this->order = $this->options['info'][$sort]['default_sort_order'];
}
else {
$this->order = !empty($this->options['order']) ? $this->options['order'] : 'asc';
}
}
else {
$sort = $order;
$request_sort = $query
->get('sort');
$this->order = !empty($request_sort) ? strtolower($request_sort) : 'asc';
}
if (empty($this->view->field[$sort])) {
return;
}
if ($this->order != 'asc' && $this->order != 'desc') {
$this->order = 'asc';
}
$this->active = $sort;
$this->view->field[$sort]
->clickSort($this->order);
}
public function sanitizeColumns($columns, $fields = NULL) {
$sanitized = [];
if ($fields === NULL) {
$fields = $this->displayHandler
->getOption('fields');
}
foreach ($fields as $field => $info) {
$sanitized[$field] = $field;
}
foreach ($columns as $field => $column) {
if (!isset($sanitized[$field])) {
continue;
}
if ($field == $column || $columns[$column] == $column && !empty($sanitized[$column])) {
$sanitized[$field] = $column;
}
}
return $sanitized;
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$handlers = $this->displayHandler
->getHandlers('field');
if (empty($handlers)) {
$form['error_markup'] = [
'#markup' => '<div class="messages messages--error">' . $this
->t('You need at least one field before you can configure your table settings') . '</div>',
];
return;
}
$form['override'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Override normal sorting if click sorting is used'),
'#default_value' => !empty($this->options['override']),
];
$form['sticky'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Enable Drupal style "sticky" table headers (Javascript)'),
'#default_value' => !empty($this->options['sticky']),
'#description' => $this
->t('(Sticky header effects will not be active for preview below, only on live output.)'),
];
$form['caption'] = [
'#type' => 'textfield',
'#title' => $this
->t('Caption for the table'),
'#description' => $this
->t('A title semantically associated with your table for increased accessibility.'),
'#default_value' => $this->options['caption'],
'#maxlength' => 255,
];
$form['accessibility_details'] = [
'#type' => 'details',
'#title' => $this
->t('Table details'),
];
$form['summary'] = [
'#title' => $this
->t('Summary title'),
'#type' => 'textfield',
'#default_value' => $this->options['summary'],
'#fieldset' => 'accessibility_details',
];
$form['description'] = [
'#title' => $this
->t('Table description'),
'#type' => 'textarea',
'#description' => $this
->t('Provide additional details about the table to increase accessibility.'),
'#default_value' => $this->options['description'],
'#states' => [
'visible' => [
'input[name="style_options[summary]"]' => [
'filled' => TRUE,
],
],
],
'#fieldset' => 'accessibility_details',
];
$form['#theme'] = 'views_ui_style_plugin_table';
$columns = $this
->sanitizeColumns($this->options['columns']);
$field_names = $this->displayHandler
->getFieldLabels();
if (isset($this->options['default'])) {
$default = $this->options['default'];
if (!isset($columns[$default])) {
$default = -1;
}
}
else {
$default = -1;
}
foreach ($columns as $field => $column) {
$column_selector = ':input[name="style_options[columns][' . $field . ']"]';
$form['columns'][$field] = [
'#title' => $this
->t('Columns for @field', [
'@field' => $field,
]),
'#title_display' => 'invisible',
'#type' => 'select',
'#options' => $field_names,
'#default_value' => $column,
];
if ($handlers[$field]
->clickSortable()) {
$form['info'][$field]['sortable'] = [
'#title' => $this
->t('Sortable for @field', [
'@field' => $field,
]),
'#title_display' => 'invisible',
'#type' => 'checkbox',
'#default_value' => !empty($this->options['info'][$field]['sortable']),
'#states' => [
'visible' => [
$column_selector => [
'value' => $field,
],
],
],
];
$form['info'][$field]['default_sort_order'] = [
'#title' => $this
->t('Default sort order for @field', [
'@field' => $field,
]),
'#title_display' => 'invisible',
'#type' => 'select',
'#options' => [
'asc' => $this
->t('Ascending'),
'desc' => $this
->t('Descending'),
],
'#default_value' => !empty($this->options['info'][$field]['default_sort_order']) ? $this->options['info'][$field]['default_sort_order'] : 'asc',
'#states' => [
'visible' => [
$column_selector => [
'value' => $field,
],
':input[name="style_options[info][' . $field . '][sortable]"]' => [
'checked' => TRUE,
],
],
],
];
$radio_id = Html::getUniqueId('edit-default-' . $field);
$form['default'][$field] = [
'#title' => $this
->t('Default sort for @field', [
'@field' => $field,
]),
'#title_display' => 'invisible',
'#type' => 'radio',
'#return_value' => $field,
'#parents' => [
'style_options',
'default',
],
'#id' => $radio_id,
'#attributes' => [
'id' => $radio_id,
],
'#default_value' => $default,
'#states' => [
'visible' => [
$column_selector => [
'value' => $field,
],
],
],
];
}
$form['info'][$field]['align'] = [
'#title' => $this
->t('Alignment for @field', [
'@field' => $field,
]),
'#title_display' => 'invisible',
'#type' => 'select',
'#default_value' => !empty($this->options['info'][$field]['align']) ? $this->options['info'][$field]['align'] : '',
'#options' => [
'' => $this
->t('None'),
'views-align-left' => $this
->t('Left', [], [
'context' => 'Text alignment',
]),
'views-align-center' => $this
->t('Center', [], [
'context' => 'Text alignment',
]),
'views-align-right' => $this
->t('Right', [], [
'context' => 'Text alignment',
]),
],
'#states' => [
'visible' => [
$column_selector => [
'value' => $field,
],
],
],
];
$form['info'][$field]['separator'] = [
'#title' => $this
->t('Separator for @field', [
'@field' => $field,
]),
'#title_display' => 'invisible',
'#type' => 'textfield',
'#size' => 10,
'#default_value' => isset($this->options['info'][$field]['separator']) ? $this->options['info'][$field]['separator'] : '',
'#states' => [
'visible' => [
$column_selector => [
'value' => $field,
],
],
],
];
$form['info'][$field]['empty_column'] = [
'#title' => $this
->t('Hide empty column for @field', [
'@field' => $field,
]),
'#title_display' => 'invisible',
'#type' => 'checkbox',
'#default_value' => isset($this->options['info'][$field]['empty_column']) ? $this->options['info'][$field]['empty_column'] : FALSE,
'#states' => [
'visible' => [
$column_selector => [
'value' => $field,
],
],
],
];
$form['info'][$field]['responsive'] = [
'#title' => $this
->t('Responsive setting for @field', [
'@field' => $field,
]),
'#title_display' => 'invisible',
'#type' => 'select',
'#default_value' => isset($this->options['info'][$field]['responsive']) ? $this->options['info'][$field]['responsive'] : '',
'#options' => [
'' => $this
->t('High'),
RESPONSIVE_PRIORITY_MEDIUM => $this
->t('Medium'),
RESPONSIVE_PRIORITY_LOW => $this
->t('Low'),
],
'#states' => [
'visible' => [
$column_selector => [
'value' => $field,
],
],
],
];
$form['info'][$field]['name'] = [
'#markup' => $field_names[$field],
];
}
$form['default'][-1] = [
'#title' => $this
->t('No default sort'),
'#title_display' => 'invisible',
'#type' => 'radio',
'#return_value' => -1,
'#parents' => [
'style_options',
'default',
],
'#id' => 'edit-default-0',
'#default_value' => $default,
];
$form['empty_table'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Show the empty text in the table'),
'#default_value' => $this->options['empty_table'],
'#description' => $this
->t('Per default the table is hidden for an empty view. With this option it is possible to show an empty table with the text in it.'),
];
$form['description_markup'] = [
'#markup' => '<div class="js-form-item form-item description">' . $this
->t('Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column click sortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section.') . '</div>',
];
}
public function evenEmpty() {
return parent::evenEmpty() || !empty($this->options['empty_table']);
}
public function wizardSubmit(&$form, FormStateInterface $form_state, WizardInterface $wizard, &$display_options, $display_type) {
foreach ($display_options['default']['fields'] as &$field) {
unset($field['label']);
}
}
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
public function getCacheContexts() {
$contexts = [];
foreach ($this->options['info'] as $field_id => $info) {
if (!empty($info['sortable'])) {
$contexts[] = 'url.query_args';
break;
}
}
return $contexts;
}
public function getCacheTags() {
return [];
}
}