Skip to content

Commit

Permalink
feat(templates): Notes tables are now responsive with accordion in sm…
Browse files Browse the repository at this point in the history
…aller screens
  • Loading branch information
elisa-av committed Sep 13, 2024
1 parent 3a7baf3 commit fb3a1ca
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 3 deletions.
57 changes: 57 additions & 0 deletions cl/assets/static-global/css/override.css
Original file line number Diff line number Diff line change
Expand Up @@ -1723,3 +1723,60 @@ rect.series-segment {
opacity 150ms 150ms ease-in;
transform: translate3d(0, 0, 0);
}

.table-wrapper table {
width: 100%;
}
@media screen and (min-width: 880px) {
.table-wrapper tbody td::before {
display: none;
}
}
/* Hide additional columns on smaller screens */
@media screen and (max-width: 880px) {
.table-wrapper thead tr > *:not(:first-child) {
display: none;
}

.table-wrapper tbody,
.table-wrapper tbody tr,
.table-wrapper tbody td {
display: flex;
flex-direction: column;
word-break: break-word;
white-space: normal !important;
max-width: 100%;
}
.table-wrapper .row-active td:first-child {
margin-bottom: -1rem;
}

.table-wrapper tbody td:not(:first-child) {
padding-block: clamp(1.44rem, calc(0.01rem + 2.49vw), 2.34rem);
}

.table-wrapper tbody td:first-child {
flex-direction: row;
align-items: center;
}

.table-wrapper tbody td:first-child::before {
display: none;
}

.table-wrapper tbody tr:not(.row-active) > *:not(:first-child) {
max-width: 0;
max-height: 0;
overflow: hidden;
padding: 0;
}

.table-wrapper tbody button {
display: inline-block;
}

.table-wrapper tbody td:not(:first-child)::before {
display: block;
font-weight: 600;
}
}
115 changes: 115 additions & 0 deletions cl/users/static/js/responsive-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**
* Adds header labels as `::before` pseudo-elements to table cells for mobile views.
*
* @param {string} elmID The ID of the table to apply the headers to.
*/
function ResponsiveCellHeaders(elmID) {
try {
var THarray = [];
var table = document.getElementById(elmID);
var ths = table.getElementsByTagName('th');
for (var i = 0; i < ths.length; i++) {
var headingText = ths[i].innerHTML;
THarray.push(headingText);
}
var styleElm = document.createElement('style'),
styleSheet;
document.head.appendChild(styleElm);
styleSheet = styleElm.sheet;
for (var i = 0; i < THarray.length; i++) {
styleSheet.insertRule(
'#' + elmID + ' td:nth-child(' + (i + 1) + ')::before {content:"' + THarray[i] + ': ";}',
styleSheet.cssRules.length
);
}
} catch (e) {
console.log('ResponsiveCellHeaders(): ' + e);
}
}

// https://adrianroselli.com/2018/02/tables-css-display-properties-and-aria.html
// https://adrianroselli.com/2018/05/functions-to-add-aria-to-tables-and-lists.html
function AddTableARIA() {
try {
var allTables = document.querySelectorAll('table');
for (var i = 0; i < allTables.length; i++) {
allTables[i].setAttribute('role', 'table');
}
var allRowGroups = document.querySelectorAll('thead, tbody, tfoot');
for (var i = 0; i < allRowGroups.length; i++) {
allRowGroups[i].setAttribute('role', 'rowgroup');
}
var allRows = document.querySelectorAll('tr');
for (var i = 0; i < allRows.length; i++) {
allRows[i].setAttribute('role', 'row');
}
var allCells = document.querySelectorAll('td');
for (var i = 0; i < allCells.length; i++) {
allCells[i].setAttribute('role', 'cell');
}
var allHeaders = document.querySelectorAll('th');
for (var i = 0; i < allHeaders.length; i++) {
allHeaders[i].setAttribute('role', 'columnheader');
}
// this accounts for scoped row headers
var allRowHeaders = document.querySelectorAll('th[scope=row]');
for (var i = 0; i < allRowHeaders.length; i++) {
allRowHeaders[i].setAttribute('role', 'rowheader');
}
// caption role not needed as it is not a real role and
// browsers do not dump their own role with display block
} catch (e) {
console.log('AddTableARIA(): ' + e);
}
}
document.addEventListener('DOMContentLoaded', function () {
ResponsiveCellHeaders('dockets');
AddTableARIA();
});

function toggle() {
const row = window.event.target.closest('tr');
row.classList.toggle('row-active');

const isActive = row.classList.contains('row-active');

if (isActive) {
const activeColumns = row.querySelectorAll('td:not(:first-child)');
activeColumns.forEach(function (col) {
col.setAttribute('aria-hidden', 'false');
});
} else {
const activeColumns = row.querySelectorAll('td[aria-hidden="false"]');
activeColumns.forEach(function (col) {
col.setAttribute('aria-hidden', 'true');
});
}
}

document.querySelectorAll('td').forEach(function (td) {
td.addEventListener('click', toggle);
});

function handleResize() {
const isMobileMode = window.matchMedia('screen and (max-width: 880px)');
const inactiveColumns = document.querySelectorAll('tbody > tr > td:not(:first-child)');

inactiveColumns.forEach(function (col) {
col.setAttribute('aria-hidden', isMobileMode.matches.toString());
});
}

window.addEventListener('resize', handleResize);

handleResize();

document.querySelectorAll('a[data-toggle="tab"]').forEach(function (tab) {
tab.addEventListener('click', function (event) {
// Extract the tab's href attribute (which is the tab pane's ID)
var tabId = event.target.getAttribute('href').substring(1); // Remove the `#` from href
console.log('Tab clicked:', tabId); // Debugging log to check the correct tab ID

// Run ResponsiveCellHeaders to update the table for the selected tab
ResponsiveCellHeaders(tabId); // This assumes each tab corresponds to a table with the same ID
});
});
8 changes: 5 additions & 3 deletions cl/users/templates/profile/notes.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
src="{% static "js/jquery.tablesorter.min.js" %}"></script>
<script defer type="text/javascript"
src="{% static "js/jquery.tablesorter.widgets.min.js" %}"></script>
<script defer type="text/javascript"
src="{% static "js/responsive-table.js" %}"></script>

<script type="text/javascript" nonce="{{ request.csp_nonce }}">
$(document).ready(function(){
Expand Down Expand Up @@ -62,13 +64,13 @@
{% for type, typed_note_forms in note_forms.items %}
<div class="tab-pane {% if forloop.first %}active{% endif %}" id="{{ type|slugify }}">
{% if typed_note_forms %}
<div class="table-responsive">
<table class="table settings-table tablesorter-bootstrap">
<div class="table-responsive table-wrapper">
<table id="{{ type|slugify }}" class="table settings-table tablesorter-bootstrap">
<thead>
<tr>
<th>Name</th>
{% if type == "Dockets" %}
<th>Last&nbsp;Filing</th>
<th>Last Filing</th>
<th class="sorter-false">Docket Number</th>
<th class="sorter-false">Court</th>
{% endif %}
Expand Down

0 comments on commit fb3a1ca

Please sign in to comment.