Skip to content

Commit

Permalink
Merge pull request #4453 from elisa-a-v/responsive-tables
Browse files Browse the repository at this point in the history
feat(templates): Profile tables are now responsive with accordion in smaller screens
  • Loading branch information
ERosendo authored Nov 5, 2024
2 parents d64017c + faafa78 commit 417a674
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 28 deletions.
8 changes: 4 additions & 4 deletions cl/alerts/templates/includes/search_alerts/table_header.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<thead>
<tr>
<th>Alert&nbsp;Type</th>
<th>Name and Query</th>
<th>Frequency</th>
<th data-label="Name and Query">Name and Query</th>
<th data-label="Alert&nbsp;Type">Alert&nbsp;Type</th>
<th data-label="Frequency">Frequency</th>
{% if is_profile_dashboard %}
<th colspan="2">Last&nbsp;Hit</th>
<th data-label="Last&nbsp;Hit" colspan="2">Last&nbsp;Hit</th>
{% endif %}
</tr>
</thead>
10 changes: 5 additions & 5 deletions cl/alerts/templates/includes/search_alerts/table_row.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
<tr id='alert-row-{{ alert.id }}' {% if hx_swap %} hx-swap-oob="true" {% endif %}>
<td>
<p class="bottom">
<a href="/?{{ alert.query }}" rel="nofollow">{{ alert.name }}</a>
</p>
</td>
<td>
<p class="bottom">
{% if alert.alert_type == SEARCH_TYPES.OPINION %}
Expand All @@ -10,11 +15,6 @@
{% endif %}
</p>
</td>
<td>
<p class="bottom">
<a href="/?{{ alert.query }}" rel="nofollow">{{ alert.name }}</a>
</p>
</td>
{% if is_profile_dashboard %}
<td>{{ alert.date_last_hit|date:"M j, Y"|default:"Never" }}</td>
{% endif %}
Expand Down
79 changes: 79 additions & 0 deletions cl/assets/static-global/css/override.css
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,10 @@ emphasis {
margin-right: 0.25em;
}

.mr-2 {
margin-right: 0.5em;
}

[data-loading] {
display: none;
}
Expand Down Expand Up @@ -1724,6 +1728,81 @@ rect.series-segment {
transform: translate3d(0, 0, 0);
}

/* CSS for responsive tables with stacked columns */
/* requires responsive-table.js */
.responsive-table-wrapper table {
width: 100%;
color: #555555;
}
@media screen and (min-width: 767px) {
.responsive-table-wrapper tbody td::before {
display: none;
}
}

@media screen and (max-width: 767px) {
.responsive-table-wrapper thead tr > *:not(:first-child) {
display: none;
}

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

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

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

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

.responsive-table-wrapper tbody tr > *:not(:first-child) {
transition: padding 0.3s ease;
overflow: hidden;
}

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

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

.responsive-table-wrapper tbody td:not(:first-child)::before {
display: block;
font-weight: 600;
}

.responsive-table-wrapper tbody td:first-child::after {
content: '\25BC'; /* Down arrow */
margin-left: 0.5rem;
transition: transform 0.3s;
}

.responsive-table-wrapper tbody tr.row-active td:first-child::after {
transform: rotate(180deg); /* Rotate to point up when expanded */
}
}

.prayer-button[data-gap-size="small"] {
margin-left: 8px;
}
Expand Down
80 changes: 80 additions & 0 deletions cl/users/static/js/responsive-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* To make a table responsive, add the class `responsive-table-wrapper` to the parent of the <table> element.
* To add the header labels to the stacked columns, include the attribute `data-label` in the <th> elements (optional)
* */

/**
* Adds header labels as `::before` pseudo-elements to table cells for mobile views.
*/
function ResponsiveCellHeaders() {
try {
var styleElm = document.createElement('style'),
styleSheet;
document.head.appendChild(styleElm);
styleSheet = styleElm.sheet;

// Select all tables within elements that have the class 'table-wrapper'
var tables = document.querySelectorAll('.responsive-table-wrapper table');

tables.forEach(function (table, tableIndex) {
var ths = table.querySelectorAll('th');
var tableClass = 'responsive-table-' + tableIndex;
table.classList.add(tableClass);

ths.forEach(function (th, index) {
var headingText = th.getAttribute('data-label');

if (headingText) {
// Create a CSS rule that adds the header text as a ::before pseudo-element
var rule =
'.' + tableClass + ' td:nth-child(' + (index + 1) + ')::before { content: "' + headingText + ': "; }';

// Insert the CSS rule into the stylesheet
styleSheet.insertRule(rule, styleSheet.cssRules.length);
}
});
});
} catch (e) {
console.log('ResponsiveCellHeaders(): ' + e);
}
}

document.addEventListener('DOMContentLoaded', function () {
ResponsiveCellHeaders();
});

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: 767px)');
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();
8 changes: 4 additions & 4 deletions cl/users/templates/includes/notes-row.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@
<td id="name-{{ note_form.instance.id }}">
{% if note_form.instance.cluster_id %}
{% with instance=note_form.instance.cluster_id %}
<i class="fa-book fa gray" title="{{ type }}"></i>
<i class="fa-book fa gray mr-2" title="{{ type }}"></i>
<a href="{% url 'view_case' instance.pk instance.slug %}">
{{note_form.instance.name }}
</a>
{% endwith %}
{% elif note_form.instance.audio_id %}
{% with instance=note_form.instance.audio_id %}
<i class="fa-volume-up fa grey" title="{{ type }}"></i>
<i class="fa-volume-up fa grey mr-2" title="{{ type }}"></i>
<a href="{% url 'view_audio_file' instance.pk instance.docket.slug %}">
{{ note_form.instance.name }}
</a>
{% endwith %}
{% elif note_form.instance.docket_id %}
{% with instance=note_form.instance.docket_id %}
<i class="fa-list fa grey"
<i class="fa-list fa grey mr-2"
title="{{ type }}"></i>
<a href="{% url 'view_docket' instance.pk instance.slug %}?order_by=desc">
{{ note_form.instance.name }}
</a>
{% endwith %}
{% elif note_form.instance.recap_doc_id %}
{% with instance=note_form.instance.recap_doc_id %}
<i class="fa-file-text-o fa grey"
<i class="fa-file-text-o fa grey mr-2"
title="{{ type }}"></i>
<a href="{% url 'view_recap_document' instance.docket_entry.docket.pk instance.document_number instance.docket_entry.docket.slug %}">
{{ note_form.instance.name }}
Expand Down
18 changes: 10 additions & 8 deletions cl/users/templates/profile/alerts.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
{% endif %}
<script defer type="text/javascript"
src="{% static "js/toggle_settings.js" %}"></script>
<script defer type="text/javascript"
src="{% static "js/responsive-table.js" %}"></script>
{% endblock %}


Expand Down Expand Up @@ -40,7 +42,7 @@ <h3 class="caps gray">You have not made any {% if page == "docket_alerts" %} REC
<h2>Search Alerts for Case Law and Oral Arguments</h2>
</div>
<div class="col-xs-12">
<div class="table-responsive">
<div class="table-responsive responsive-table-wrapper">
<table class="table settings-table">
{% include "includes/search_alerts/table_header.html" with is_profile_dashboard=True%}
<tbody>
Expand All @@ -64,15 +66,15 @@ <h3 class="gray caps">🎉 Your email address provides you unlimited docket aler
<h3 class="gray caps">🎉 Being a member provides you unlimited docket alerts</h3>
{% endif %}

<div class="table-responsive">
<table class="table settings-table">
<div class="table-responsive responsive-table-wrapper">
<table id="dockets-table" class="table settings-table">
<thead>
<tr>
<th><a class="no-underline black-link" href="?{% url_replace request 'name' %}">Case Name{% sort_caret request 'name' %}</a></th>
<th><a class="no-underline black-link" href="?{% url_replace request 'court' %}">Court{% sort_caret request 'court' %}</a></th>
<th><a class="no-underline black-link" href="?{% url_replace request 'docket_number' %}">Docket Number{% sort_caret request 'docket_number' %}</a></th>
<th><a class="no-underline black-link" href="?{% url_replace request 'date_filed' %}">Date Filed{% sort_caret request 'date_filed' %}</a></th>
<th colspan="2"><a class="no-underline black-link" href="?{% url_replace request 'hit' %}"> Last&nbsp;Hit{% sort_caret request 'hit' %}</a></th>
<th data-label="Case Name"><a class="no-underline black-link" href="?{% url_replace request 'name' %}">Case Name{% sort_caret request 'name' %}</a></th>
<th data-label="Court"><a class="no-underline black-link" href="?{% url_replace request 'court' %}">Court{% sort_caret request 'court' %}</a></th>
<th data-label="Docket Number"><a class="no-underline black-link" href="?{% url_replace request 'docket_number' %}">Docket Number{% sort_caret request 'docket_number' %}</a></th>
<th data-label="Date Filed"><a class="no-underline black-link" href="?{% url_replace request 'date_filed' %}">Date Filed{% sort_caret request 'date_filed' %}</a></th>
<th data-label="Last&nbsp;Hit" colspan="2"><a class="no-underline black-link" href="?{% url_replace request 'hit' %}"> Last&nbsp;Hit{% sort_caret request 'hit' %}</a></th>
</tr>
</thead>
<tbody>
Expand Down
16 changes: 9 additions & 7 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,17 +64,17 @@
{% 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 responsive-table-wrapper">
<table id="{{ type|slugify }}-table" class="table settings-table tablesorter-bootstrap">
<thead>
<tr>
<th>Name</th>
<th data-label="Name">Name</th>
{% if type == "Dockets" %}
<th>Last&nbsp;Filing</th>
<th class="sorter-false">Docket Number</th>
<th class="sorter-false">Court</th>
<th data-label="Last Filing">Last Filing</th>
<th data-label="Docket Number" class="sorter-false">Docket Number</th>
<th data-label="Court" class="sorter-false">Court</th>
{% endif %}
<th class="sorter-false">Notes</th>
<th data-label="Notes" class="sorter-false">Notes</th>
<th class="sorter-false">
{% if type == "Dockets" %}
<a class="btn btn-default" href="{{ docket_search_url }}" role="button">
Expand Down

0 comments on commit 417a674

Please sign in to comment.