diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 54b038b..f9d010d 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -922,6 +922,7 @@ function template_preprocess_table(&$variables) {
if (!is_array($cell)) {
$header_columns++;
$cell_content = $cell;
+ $cell_label = $cell;
$cell_attributes = new Attribute();
$is_header = TRUE;
}
@@ -953,6 +954,12 @@ function template_preprocess_table(&$variables) {
$responsive_classes[$responsive_index] = RESPONSIVE_PRIORITY_LOW;
}
}
+ if (is_array($cell_content)) {
+ $cell_label = strip_tags(\Drupal::service('renderer')->render($cell_content));
+ }
+ else {
+ $cell_label = $cell_content;
+ }
tablesort_header($cell_content, $cell, $variables['header'], $ts);
@@ -963,6 +970,9 @@ function template_preprocess_table(&$variables) {
$variables['header'][$col_key]['tag'] = $is_header ? 'th' : 'td';
$variables['header'][$col_key]['attributes'] = $cell_attributes;
$variables['header'][$col_key]['content'] = $cell_content;
+ if (!empty($cell_label)) {
+ $variables['header'][$col_key]['label'] = $cell_label;
+ }
}
}
$variables['header_columns'] = $header_columns;
@@ -1027,6 +1037,10 @@ function template_preprocess_table(&$variables) {
$variables[$section][$row_key]['cells'][$col_key]['tag'] = $is_header ? 'th' : 'td';
$variables[$section][$row_key]['cells'][$col_key]['attributes'] = new Attribute($cell_attributes);
$variables[$section][$row_key]['cells'][$col_key]['content'] = $cell_content;
+ if (!empty($variables['header'][$col_key]['label'])) {
+ $variables[$section][$row_key]['cells'][$col_key]['label'] = $variables['header'][$col_key]['label'];
+ $variables[$section][$row_key]['cells'][$col_key]['attributes']->setAttribute('data-th', $variables['header'][$col_key]['label']);
+ }
}
}
}
diff --git a/core/misc/tableresponsive.js b/core/misc/tableresponsive.js
index 0127ec8..41b2615 100644
--- a/core/misc/tableresponsive.js
+++ b/core/misc/tableresponsive.js
@@ -59,7 +59,7 @@
// Attach a resize handler to the window.
$(window)
- .on('resize.tableresponsive', $.proxy(this, 'eventhandlerEvaluateColumnVisibility'))
+ .on('resize.tableresponsive', $.proxy(this, 'eventhandlerCollapseColumns'))
.trigger('resize.tableresponsive');
}
@@ -83,6 +83,17 @@
* or priority-medium.
*/
$.extend(TableResponsive.prototype, /** @lends Drupal.TableResponsive# */{
+ eventhandlerCollapseColumns: function (e) {
+ var $table = this.$table;
+ var $parent = $table.parent();
+ var parentWidth = $parent.width();
+ var tableWidth = $table.width();
+ // If table is wider than or equal to its parent element width,
+ // add class is-collapsed to avoid overflowing.
+ if (parentWidth <= tableWidth) {
+ $table.addClass('is-collapsed');
+ }
+ },
/**
* @param {jQuery.Event} e
diff --git a/core/modules/filter/src/Tests/FilterAdminTest.php b/core/modules/filter/src/Tests/FilterAdminTest.php
index bcc8c57..b6bef77 100644
--- a/core/modules/filter/src/Tests/FilterAdminTest.php
+++ b/core/modules/filter/src/Tests/FilterAdminTest.php
@@ -385,10 +385,10 @@ function testFilterTipHtmlEscape() {
$this->drupalGet('filter/tips');
- $this->assertRaw('
' . $link_as_code . ' | ');
- $this->assertRaw('' . $link . ' | ');
- $this->assertRaw('' . $ampersand_as_code . ' | ');
- $this->assertRaw('' . $ampersand . ' | ');
+ $this->assertRaw('' . $link_as_code . ' | ');
+ $this->assertRaw('' . $link . ' | ');
+ $this->assertRaw('' . $ampersand_as_code . ' | ');
+ $this->assertRaw('' . $ampersand . ' | ');
}
/**
diff --git a/core/modules/system/src/Tests/Render/Element/TableTest.php b/core/modules/system/src/Tests/Render/Element/TableTest.php
index 827b55a..ac4c777 100644
--- a/core/modules/system/src/Tests/Render/Element/TableTest.php
+++ b/core/modules/system/src/Tests/Render/Element/TableTest.php
@@ -235,8 +235,8 @@ public function testThemeTableResponsivePriority() {
$this->assertRaw('1 | ', 'Header 1: the priority-medium class was applied correctly.');
$this->assertRaw('2 | ', 'Header 2: the priority-low class was applied correctly.');
$this->assertRaw('3 | ', 'Header 3: no priority classes were applied.');
- $this->assertRaw('4 | ', 'Cell 1: the priority-medium class was applied correctly.');
- $this->assertRaw('5 | ', 'Cell 2: the priority-low class was applied correctly.');
+ $this->assertRaw('4 | ', 'Cell 1: the priority-medium class was applied correctly.');
+ $this->assertRaw('5 | ', 'Cell 2: the priority-low class was applied correctly.');
$this->assertRaw('6 | ', 'Cell 3: no priority classes were applied.');
}
@@ -308,8 +308,8 @@ public function testThemeTableRowRenderArray() {
);
$this->render($table);
$this->removeWhiteSpace();
- $this->assertRaw('1-one | 1-two | 1-three |
', 'Table row 1 found.');
- $this->assertRaw('2-one | 2-two | 2-three |
', 'Table row 2 found.');
+ $this->assertRaw('1-one | 1-two | 1-three |
', 'Table row 1 found.');
+ $this->assertRaw('2-one | 2-two | 2-three |
', 'Table row 2 found.');
}
/**
diff --git a/core/modules/system/templates/table.html.twig b/core/modules/system/templates/table.html.twig
index f6b32e4..4ac9639 100644
--- a/core/modules/system/templates/table.html.twig
+++ b/core/modules/system/templates/table.html.twig
@@ -30,6 +30,7 @@
* - content: The string to display in the table cell.
* - active_table_sort: A boolean indicating whether the cell is the active
table sort.
+ - label: The value of the related table header of this column.
* - footer: Table footer rows, in the same format as the rows variable.
* - empty: The message to display in an extra row if table does not have
* any rows.
diff --git a/core/modules/views/templates/views-view-table.html.twig b/core/modules/views/templates/views-view-table.html.twig
index 0c0b445..149a0ab 100644
--- a/core/modules/views/templates/views-view-table.html.twig
+++ b/core/modules/views/templates/views-view-table.html.twig
@@ -22,6 +22,7 @@
* - columns: Row column items. Columns are keyed by column number.
* - attributes: HTML classes to apply to each column.
* - content: The column content.
+ * - label: The value of the related table header of this column.
* - default_classes: A flag indicating whether default classes should be
* used.
* - responsive: A flag indicating whether table is responsive.
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index c14416f..b52938f 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -511,6 +511,11 @@ function template_preprocess_views_view_table(&$variables) {
$column_reference['attributes'] = array();
}
+ if (!empty($label)) {
+ $data_th = SafeMarkup::checkPlain(!empty($fields[$field]) ? $fields[$field]->label() : '');
+ $column_reference['label'] = $data_th;
+ }
+
if ($classes = $fields[$field]->elementClasses($num)) {
$column_reference['attributes']['class'][] = $classes;
}
diff --git a/core/themes/bartik/css/components/table.css b/core/themes/bartik/css/components/table.css
index 561c74a..20cb6a3 100644
--- a/core/themes/bartik/css/components/table.css
+++ b/core/themes/bartik/css/components/table.css
@@ -63,10 +63,58 @@ tr th {
td.priority-medium {
display: none;
}
+ .mobile-table {
+ width: 100%;
+ border-collapse: collapse;
+ table-layout: fixed;
+ }
+ .mobile-table th {
+ display: none;
+ }
+ .mobile-table td {
+ display: block;
+ border: none;
+ }
+ .mobile-table td:before {
+ content: attr(data-th)" ";
+ font-weight: bold;
+ width: 8em;
+ display: inline-block;
+ }
}
@media screen and (max-width: 60em) { /* 920px */
th.priority-low,
td.priority-low {
display: none;
}
+ .responsive-enabled.is-collapsed {
+ width: 100%;
+ border-collapse: collapse;
+ table-layout: fixed;
+ }
+ .responsive-enabled.is-collapsed th {
+ display: none;
+ }
+ .responsive-enabled.is-collapsed td {
+ display: block;
+ border: none;
+ }
+ .responsive-enabled.is-collapsed td:before {
+ content: attr(data-th)" ";
+ font-weight: bold;
+ width: 8em;
+ display: inline-block;
+ }
+
+ /* A few overrides to cover some edge cases. */
+ .responsive-enabled.is-collapsed .form-item {
+ display: inline-block;
+ }
+ .responsive-enabled.is-collapsed .dropbutton-wrapper {
+ width: auto;
+ display: inline-block
+ }
+ .touch .responsive-enabled.is-collapsed .draggable td {
+ padding: 10px 12px;
+ }
}
diff --git a/core/themes/seven/css/components/tables.css b/core/themes/seven/css/components/tables.css
index 3bdf7cc..8b525d9 100644
--- a/core/themes/seven/css/components/tables.css
+++ b/core/themes/seven/css/components/tables.css
@@ -138,10 +138,59 @@ th.select-all {
td.priority-medium {
display: none;
}
+ .mobile-table {
+ width: 100%;
+ border-collapse: collapse;
+ table-layout: fixed;
+ }
+ .mobile-table th {
+ display: none;
+ }
+ .mobile-table td {
+ display: block;
+ border: none;
+ }
+ .mobile-table td:before {
+ content: attr(data-th)" ";
+ font-weight: bold;
+ width: 8em;
+ display: inline-block;
+ }
}
@media screen and (max-width: 60em) { /* 920px */
th.priority-low,
td.priority-low {
display: none;
}
+ .responsive-enabled.is-collapsed {
+ width: 100%;
+ border-collapse: collapse;
+ table-layout: fixed;
+ }
+ .responsive-enabled.is-collapsed th {
+ display: none;
+ }
+ .responsive-enabled.is-collapsed td {
+ display: block;
+ border: none;
+ }
+ .responsive-enabled.is-collapsed td:before {
+ content: attr(data-th)" ";
+ font-weight: bold;
+ width: 8em;
+ display: inline-block;
+ }
+
+ /* A few overrides to cover some edge cases. */
+ .responsive-enabled.is-collapsed .form-item {
+ display: inline-block;
+ }
+ .responsive-enabled.is-collapsed .dropbutton-wrapper {
+ width: auto;
+ display: inline-block
+ }
+ .touch .responsive-enabled.is-collapsed .draggable td {
+ padding: 10px 12px;
+ }
}
+