Issue #843708 by mgifford, dawehner: Add option to set caption & remove summary in the html table (Accessibility).
parent
6012988251
commit
2a17837fda
|
@ -94,7 +94,9 @@ class Table extends StylePluginBase {
|
||||||
$options['override'] = array('default' => TRUE, 'bool' => TRUE);
|
$options['override'] = array('default' => TRUE, 'bool' => TRUE);
|
||||||
$options['sticky'] = array('default' => FALSE, 'bool' => TRUE);
|
$options['sticky'] = array('default' => FALSE, 'bool' => TRUE);
|
||||||
$options['order'] = array('default' => 'asc');
|
$options['order'] = array('default' => 'asc');
|
||||||
|
$options['caption'] = array('default' => '', 'translatable' => TRUE);
|
||||||
$options['summary'] = array('default' => '', 'translatable' => TRUE);
|
$options['summary'] = array('default' => '', 'translatable' => TRUE);
|
||||||
|
$options['description'] = array('default' => '', 'translatable' => TRUE);
|
||||||
$options['empty_table'] = array('default' => FALSE, 'bool' => TRUE);
|
$options['empty_table'] = array('default' => FALSE, 'bool' => TRUE);
|
||||||
|
|
||||||
return $options;
|
return $options;
|
||||||
|
@ -242,14 +244,40 @@ class Table extends StylePluginBase {
|
||||||
'#description' => t('(Sticky header effects will not be active for preview below, only on live output.)'),
|
'#description' => t('(Sticky header effects will not be active for preview below, only on live output.)'),
|
||||||
);
|
);
|
||||||
|
|
||||||
$form['summary'] = array(
|
$form['caption'] = array(
|
||||||
'#type' => 'textfield',
|
'#type' => 'textfield',
|
||||||
'#title' => t('Table summary'),
|
'#title' => t('Caption for the table'),
|
||||||
'#description' => t('This value will be displayed as table-summary attribute in the html. Set this for better accessiblity of your site.'),
|
'#description' => t('A title which is semantically associated to your table for increased accessibility.'),
|
||||||
'#default_value' => $this->options['summary'],
|
'#default_value' => $this->options['caption'],
|
||||||
'#maxlength' => 255,
|
'#maxlength' => 255,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$form['accessibility_details'] = array(
|
||||||
|
'#type' => 'details',
|
||||||
|
'#title' => t('Table details'),
|
||||||
|
'#collapsed' => TRUE,
|
||||||
|
);
|
||||||
|
|
||||||
|
$form['summary'] = array(
|
||||||
|
'#title' => t('Summary title'),
|
||||||
|
'#type' => 'textfield',
|
||||||
|
'#default_value' => $this->options['summary'],
|
||||||
|
'#fieldset' => 'accessibility_details',
|
||||||
|
);
|
||||||
|
|
||||||
|
$form['description'] = array(
|
||||||
|
'#title' => t('Table description'),
|
||||||
|
'#type' => 'textarea',
|
||||||
|
'#description' => t('Provide additional details about the table to increase accessibility.'),
|
||||||
|
'#default_value' => $this->options['description'],
|
||||||
|
'#states' => array(
|
||||||
|
'visible' => array(
|
||||||
|
'input[name="style_options[summary]"]' => array('filled' => TRUE),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'#fieldset' => 'accessibility_details',
|
||||||
|
);
|
||||||
|
|
||||||
// Note: views UI registers this theme handler on our behalf. Your module
|
// Note: views UI registers this theme handler on our behalf. Your module
|
||||||
// will have to register your theme handlers if you do stuff like this.
|
// will have to register your theme handlers if you do stuff like this.
|
||||||
$form['#theme'] = 'views_ui_style_plugin_table';
|
$form['#theme'] = 'views_ui_style_plugin_table';
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\views\Tests\Plugin\StyleTableTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\views\Tests\Plugin;
|
||||||
|
|
||||||
|
class StyleTableTest extends PluginTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Views used by this test.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $testViews = array('test_table');
|
||||||
|
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'Style: Table',
|
||||||
|
'description' => 'Tests the table style plugin.',
|
||||||
|
'group' => 'Views Plugins',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->enableViewsTestModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test table caption/summary/description.
|
||||||
|
*/
|
||||||
|
public function testAccessibilitySettings() {
|
||||||
|
$this->drupalGet('test-table');
|
||||||
|
|
||||||
|
$result = $this->xpath('//caption');
|
||||||
|
$this->assertTrue(count($result), 'The caption appears on the table.');
|
||||||
|
$this->assertEqual(trim((string) $result[0]), 'caption-text');
|
||||||
|
|
||||||
|
$result = $this->xpath('//summary');
|
||||||
|
$this->assertTrue(count($result), 'The summary appears on the table.');
|
||||||
|
$this->assertEqual(trim((string) $result[0]), 'summary-text');
|
||||||
|
|
||||||
|
$result = $this->xpath('//caption/details');
|
||||||
|
$this->assertTrue(count($result), 'The table description appears on the table.');
|
||||||
|
$this->assertEqual(trim((string) $result[0]), 'description-text');
|
||||||
|
|
||||||
|
// Remove the caption and ensure the caption is not displayed anymore.
|
||||||
|
$view = entity_load('view', 'test_table');
|
||||||
|
$display = &$view->getDisplay('default');
|
||||||
|
$display['display_options']['style']['options']['caption'] = '';
|
||||||
|
$view->save();
|
||||||
|
|
||||||
|
$this->drupalGet('test-table');
|
||||||
|
$result = $this->xpath('//caption');
|
||||||
|
$this->assertFalse(trim((string) $result[0]), 'Ensure that the caption disappears.');
|
||||||
|
|
||||||
|
// Remove the table summary.
|
||||||
|
$display = &$view->getDisplay('default');
|
||||||
|
$display['display_options']['style']['options']['summary'] = '';
|
||||||
|
$view->save();
|
||||||
|
|
||||||
|
$this->drupalGet('test-table');
|
||||||
|
$result = $this->xpath('//summary');
|
||||||
|
$this->assertFalse(count($result), 'Ensure that the summary disappears.');
|
||||||
|
|
||||||
|
// Remove the table description.
|
||||||
|
$display = &$view->getDisplay('default');
|
||||||
|
$display['display_options']['style']['options']['description'] = '';
|
||||||
|
$view->save();
|
||||||
|
|
||||||
|
$this->drupalGet('test-table');
|
||||||
|
$result = $this->xpath('//caption/details');
|
||||||
|
$this->assertFalse(count($result), 'Ensure that the description disappears.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -10,6 +10,10 @@
|
||||||
* - header: Header labels.
|
* - header: Header labels.
|
||||||
* - header_classes: HTML classes to apply to each header cell, indexed by
|
* - header_classes: HTML classes to apply to each header cell, indexed by
|
||||||
* the header's key.
|
* the header's key.
|
||||||
|
* - caption_needed: Is the caption tag needed.
|
||||||
|
* - caption: The caption for this table.
|
||||||
|
* - accessibility_description: Extended description for the table details.
|
||||||
|
* - accessibility_summary: Summary for the table details.
|
||||||
* - rows: Table row items. Rows are keyed by row number, fields within rows
|
* - rows: Table row items. Rows are keyed by row number, fields within rows
|
||||||
* are keyed by field ID.
|
* are keyed by field ID.
|
||||||
* - field: Table data field ID.
|
* - field: Table data field ID.
|
||||||
|
@ -26,8 +30,24 @@
|
||||||
*/
|
*/
|
||||||
#}
|
#}
|
||||||
<table{{ attributes }}>
|
<table{{ attributes }}>
|
||||||
{% if title is not empty %}
|
{% if caption_needed %}
|
||||||
<caption>{{ title }}</caption>
|
<caption>
|
||||||
|
{% if caption %}
|
||||||
|
{{ caption }}
|
||||||
|
{% else %}
|
||||||
|
{{ title }}
|
||||||
|
{% endif %}
|
||||||
|
{% if (summary is not empty) or (description is not empty) %}
|
||||||
|
<details>
|
||||||
|
{% if summary is not empty %}
|
||||||
|
<summary>{{ summary }}</summary>
|
||||||
|
{% endif %}
|
||||||
|
{% if description is not empty %}
|
||||||
|
{{ description }}
|
||||||
|
{% endif %}
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
</caption>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if header %}
|
{% if header %}
|
||||||
<thead>
|
<thead>
|
||||||
|
|
|
@ -80,6 +80,9 @@ display:
|
||||||
responsive: ''
|
responsive: ''
|
||||||
default: 'id'
|
default: 'id'
|
||||||
empty_table: '1'
|
empty_table: '1'
|
||||||
|
caption: caption-text
|
||||||
|
summary: summary-text
|
||||||
|
description: description-text
|
||||||
row:
|
row:
|
||||||
type: fields
|
type: fields
|
||||||
empty:
|
empty:
|
||||||
|
@ -99,6 +102,13 @@ display:
|
||||||
display_title: Master
|
display_title: Master
|
||||||
id: default
|
id: default
|
||||||
position: '0'
|
position: '0'
|
||||||
|
page_1:
|
||||||
|
display_options:
|
||||||
|
path: 'test-table'
|
||||||
|
display_plugin: page
|
||||||
|
display_title: 'Page display'
|
||||||
|
id: page_1
|
||||||
|
position: '1'
|
||||||
label: ''
|
label: ''
|
||||||
id: test_table
|
id: test_table
|
||||||
tag: ''
|
tag: ''
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* Preprocessors and helper functions to make theming easier.
|
* Preprocessors and helper functions to make theming easier.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Drupal\Component\Utility\Xss;
|
||||||
use Drupal\Core\Language\Language;
|
use Drupal\Core\Language\Language;
|
||||||
use Drupal\Core\Template\Attribute;
|
use Drupal\Core\Template\Attribute;
|
||||||
use Drupal\views\ViewExecutable;
|
use Drupal\views\ViewExecutable;
|
||||||
|
@ -740,13 +741,24 @@ function template_preprocess_views_view_table(&$vars) {
|
||||||
}
|
}
|
||||||
$vars['attributes']['class'][] = 'cols-' . count($vars['header']);
|
$vars['attributes']['class'][] = 'cols-' . count($vars['header']);
|
||||||
|
|
||||||
if (!empty($handler->options['summary'])) {
|
// Add the caption to the list if set.
|
||||||
$vars['attributes']['summary'] = $handler->options['summary'];
|
if (!empty($handler->options['caption'])) {
|
||||||
|
$vars['caption'] = Xss::filterAdmin($handler->options['caption']);
|
||||||
|
$vars['caption_needed'] = TRUE;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$vars['caption'] = '';
|
||||||
|
$vars['caption_needed'] = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars['summary'] = $handler->options['summary'];
|
||||||
|
$vars['description'] = $handler->options['description'];
|
||||||
|
$vars['caption_needed'] |= !empty($vars['summary']) || !empty($vars['description']);
|
||||||
|
|
||||||
// If the table has headers and it should react responsively to columns hidden
|
// If the table has headers and it should react responsively to columns hidden
|
||||||
// with the classes represented by the constants RESPONSIVE_PRIORITY_MEDIUM
|
// with the classes represented by the constants RESPONSIVE_PRIORITY_MEDIUM
|
||||||
// and RESPONSIVE_PRIORITY_LOW, add the tableresponsive behaviors.
|
// and RESPONSIVE_PRIORITY_LOW, add the tableresponsive behaviors.
|
||||||
if (count($vars['header']) && $responsive) {
|
if (isset($vars['header']) && $responsive) {
|
||||||
$vars['view']->element['#attached']['library'][] = array('system', 'drupal.tableresponsive');
|
$vars['view']->element['#attached']['library'][] = array('system', 'drupal.tableresponsive');
|
||||||
// Add 'responsive-enabled' class to the table to identify it for JS.
|
// Add 'responsive-enabled' class to the table to identify it for JS.
|
||||||
// This is needed to target tables constructed by this function.
|
// This is needed to target tables constructed by this function.
|
||||||
|
|
Loading…
Reference in New Issue