diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 7400017..59c95f2 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -866,6 +866,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;
}
@@ -897,6 +898,7 @@ function template_preprocess_table(&$variables) {
$responsive_classes[$responsive_index] = RESPONSIVE_PRIORITY_LOW;
}
}
+ $cell_label = $cell_content;
tablesort_header($cell_content, $cell, $variables['header'], $ts);
@@ -907,6 +909,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;
@@ -971,6 +976,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 f2ebd18..6b82014 100644
--- a/core/misc/tableresponsive.js
+++ b/core/misc/tableresponsive.js
@@ -55,7 +55,7 @@
// Attach a resize handler to the window.
$(window)
- .on('resize.tableresponsive', $.proxy(this, 'eventhandlerEvaluateColumnVisibility'))
+ .on('resize.tableresponsive', $.proxy(this, 'eventhandlerCollapseColumns'))
.trigger('resize.tableresponsive');
}
@@ -79,6 +79,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 7e6a2d3..2aa6726 100644
--- a/core/modules/filter/src/Tests/FilterAdminTest.php
+++ b/core/modules/filter/src/Tests/FilterAdminTest.php
@@ -377,10 +377,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/css/system.module.css b/core/modules/system/css/system.module.css
index b38c5e5..eba6809 100644
--- a/core/modules/system/css/system.module.css
+++ b/core/modules/system/css/system.module.css
@@ -105,6 +105,11 @@ tr.add-new .tabledrag-changed {
a.tabledrag-handle:hover {
text-decoration: none;
}
+
+/* If inside of a collapsible table, float the handle to the right side */
+.responsive-enabled.is-collapsed a.tabledrag-handle {
+ float: right;
+}
a.tabledrag-handle .handle {
background: url(../../../misc/icons/787878/move.svg) no-repeat 6px 7px;
height: 14px;
diff --git a/core/modules/system/src/Tests/Theme/TableTest.php b/core/modules/system/src/Tests/Theme/TableTest.php
index e65037c..6d54d03 100644
--- a/core/modules/system/src/Tests/Theme/TableTest.php
+++ b/core/modules/system/src/Tests/Theme/TableTest.php
@@ -232,8 +232,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.');
}
@@ -305,7 +305,7 @@ 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 fe6be75..25dcd0d 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 fbe962e..a637b3d 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -558,6 +558,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 18aedbc..c226244 100644
--- a/core/themes/bartik/css/components/table.css
+++ b/core/themes/bartik/css/components/table.css
@@ -59,12 +59,60 @@ 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;
+ }
}
table ul.links {
margin: 0;
diff --git a/core/themes/seven/css/components/tables.css b/core/themes/seven/css/components/tables.css
index afc9301..47f5db9 100644
--- a/core/themes/seven/css/components/tables.css
+++ b/core/themes/seven/css/components/tables.css
@@ -134,10 +134,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;
+ }
}
+