Skip to content
22 changes: 17 additions & 5 deletions core/static/core/js/search-results.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@

let num_records = $('#num_records').val();

// If there are records and the fieldset has been toggled to be closed, keep it closed.
// The search fieldset is closed (full view) by default. If there are records
// and the user hasn't explicitly toggled it open, keep it closed.
// otherwise, if there are no results, we have to show the search bar to allow the user to search again.

if (num_records > 0 && localStorage.getItem('fieldset-toggle') === 'false') {
$('#query-fieldset').toggle();
$('#query-result').toggleClass('col--3of4');
if (num_records > 0 && localStorage.getItem('fieldset-toggle') !== 'true') {
$('#query-fieldset').hide();
$('#query-result').removeClass('col--3of4');
}

function toggle_advanced_search_controls() {
Expand Down Expand Up @@ -206,7 +207,7 @@ function setup_fieldset_toggle() {
}
});

if (localStorage.getItem('fieldset-toggle') === 'false') {
if (localStorage.getItem('fieldset-toggle') !== 'true') {
$('footer').hide();
}
}
Expand Down Expand Up @@ -302,6 +303,17 @@ function reset_form(form) {
}

$(function () {
// Keep sticky table header anchored just below the navigation bar.
const siteHeader = document.querySelector('.site-header');
if (siteHeader) {
const updateNavHeight = () => {
document.documentElement.style.setProperty('--nav-height', siteHeader.offsetHeight + 'px');
};
updateNavHeight();
window.addEventListener('resize', updateNavHeight);
window.addEventListener('load', updateNavHeight);
}

emlojs.selectable_service.setup_all()
setup_merge_btn();
setup_fieldset_toggle();
Expand Down
2 changes: 1 addition & 1 deletion core/static/core/scss/base/general.scss
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ thead tr {
th {
font-weight: 700;
position: sticky;
top: 100px;
top: var(--nav-height, 100px);
z-index: 99;
border-bottom: 1px solid $black;
background-color: $white;
Expand Down
94 changes: 81 additions & 13 deletions core/static/core/scss/components/pagination.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,51 @@

.pagination {
padding: $space-sm $space-unit $space-sm 0;
padding: $space-sm 0;
clear: both;
flex: 1 1 auto;
min-width: 0;
}

.pagination-nav ul {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
list-style: none;
margin: 0;
padding: 0;
gap: $space-sm $space-md;
}

// Extra breathing room between the first/previous nav links and the
// numbered pages, and again between the numbered pages and next/last.
.page-item--nav + .page-item:not(.page-item--nav),
.page-item:not(.page-item--nav) + .page-item--nav {
margin-left: $space-sm;
}

// Toolbar row combining the search-options toggle (plus any future
// left-hand buttons) with the pagination. The pagination column takes
// the remaining space and centres itself within it. Wraps to stacked
// rows when the table column is narrower (e.g. search sidebar left open).
.pagination-toolbar {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
gap: $space-sm $space-lg;
padding: 0;
font-size: 16px;
}

.pagination-toolbar__left {
display: flex;
align-items: center;
justify-self: start;
}

.pagination-toolbar__center {
justify-self: center;
min-width: 0;
}

#hidden_columns span {
Expand All @@ -22,23 +66,47 @@

}

// Plain, unboxed page numbers -- only the current page gets a visible
// border. Every item still reserves the same 1px transparent border so
// heights stay identical (numbered pages, nav links, ellipsis and the
// toggle button all line up), it's just invisible until active/hovered.
.page-item {
display: inline-block;
text-align: center;
min-width: 50px;
border: 1px solid $black;
transition: all .15s ease-in-out;
// add small gaps so when pagination wraps to multiple rows there is
// visible spacing between rows and items (helps on half-screen windows)
margin: 0 .4em .4em 0;
// gaps between rows when pagination wraps on narrower (half) views
margin-bottom: $space-xxs;

&:hover {
border-color: $white;
a, .page-link {
display: inline-block;
text-align: center;
padding: $space-xxs $space-xs;
border: 1px solid transparent;
border-radius: $space-xxs;
line-height: inherit;
box-sizing: border-box;
transition: all .15s ease-in-out;
}

&:not(.active-page):hover a, &:not(.active-page):hover .page-link {
border-color: $light-grey;
}
}

.active-page {
background-color: $black;
color: $white;
.active-page .page-link {
border-color: $midnight;
color: $midnight;
font-weight: bold;
}

// Half view: search sidebar is open and the results column is narrower.
// Stack the two sections instead of trying to fit them on one line.
@media (max-width: $mborder-mid) {
.pagination-toolbar {
grid-template-columns: 1fr;
justify-items: center;
}

.pagination-toolbar__left,
.pagination-toolbar__center {
justify-self: center;
}
}
49 changes: 32 additions & 17 deletions core/static/core/scss/components/search-result.scss
Original file line number Diff line number Diff line change
Expand Up @@ -114,20 +114,18 @@ td.text-heavy {
}

#results_table {
/* Size behavior: allow table to be wider than the viewport/container */
min-width: 100%; /* ensure at least full width */
width: max-content; /* expand to fit columns so wrapper can scroll */
max-width: none; /* do not clamp the intrinsic width */
width: 100%;

/* Table visuals */
border-collapse: collapse;
/* Keep auto layout for natural column sizing */
/* border-collapse must stay 'separate' (inherited from the global table rule) —
position:sticky on thead cells is broken when border-collapse:collapse is set */
}

#results_table th {
top: 0px;
top: var(--nav-height, 100px);
background-color: $light-grey;
border: 1px solid $mid-grey;
/* Use directional borders only to avoid doubled borders with border-collapse:separate */
border-right: 1px solid $mid-grey;
border-bottom: 2px solid $mid-grey;
padding-left: 5px;
padding-right: 5px;
}
Expand Down Expand Up @@ -222,18 +220,35 @@ td.text-heavy {
// hyphens: auto;
//}

/* New scroll container placed above/wrapping the table. This holds the scrollbars
so the page itself doesn't move. The table element remains unchanged. */
/* Wrapper for the results table.
No overflow set — keeping this free of any overflow value lets CSS position:sticky
on the thead cells anchor correctly to the page scroll. */
.results-scroll {
height: 70vh; /* match viewport height and adapt on resize */
max-height: 70vh;
width: 100%;
overflow: auto; /* both vertical and horizontal scrolling inside */
-webkit-overflow-scrolling: touch; /* smooth scrolling on iOS */
overscroll-behavior: contain; /* prevent scroll chaining to the page */
border: 1px solid $light-grey;
}

/* On result pages the table can be wider than the viewport, causing the page to scroll
horizontally. The sticky nav (position:sticky) then scrolls with the content and its
background no longer covers the full viewport — white space appears on the right.
Fix: use position:fixed for the nav so it is always anchored to the viewport and is
never affected by horizontal scroll. padding-top on the body compensates for the fixed
element being removed from the document flow.
Scoped via :has(.results-scroll) so only result pages are affected. */
html:has(.results-scroll) .site-header {
position: fixed;
top: 0;
left: 0;
right: 0;
margin: 0;
width: 100%;
z-index: 150;
}

html:has(.results-scroll) body {
padding-top: var(--nav-height, 100px);
}

.img-thumbnail {
width: 60px;
}
Expand All @@ -257,4 +272,4 @@ td.text-heavy {

.alt_names_title {
font-weight: bold;
}
}
17 changes: 9 additions & 8 deletions core/templates/core/basic_search_page.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,9 @@ <h2>
<h2>No results</h2>

{% else %}
<!-- Upper pagination -->
{% include 'core/component/pagination.html' %}

<!-- search function toolbar (e.g. download output, compact, expanded) -->
<aside class="margin-bottom row">
<div class="col col--1of2">
<!-- search function toolbar: search options toggle, pagination -->
<div class="pagination-toolbar">
<div class="pagination-toolbar__left">
{% if query_fieldset_list and paginator.count %}
<button id="fieldset-toggle-btn" class="search-form-btn" type="button">
Toggle
Expand All @@ -125,7 +122,11 @@ <h2>No results</h2>
</button>
{% endif %}
</div>
</aside>

<div class="pagination-toolbar__center">
{% include 'core/component/pagination.html' %}
</div>
</div>

{{ results_renderer | safe }}

Expand Down Expand Up @@ -195,4 +196,4 @@ <h2>No results</h2>
</script>
<script src="{% static 'core/js/search-results.js' %}?v={{ constant.VERSION }}"></script>

{% endblock %}
{% endblock %}
16 changes: 8 additions & 8 deletions core/templates/core/component/pagination.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

{% if page_obj.paginator.num_pages > 1 or page_obj.has_other_pages %}

<div class="row row--centered pagination">
<nav class="pagination-nav row row--centered pagination" aria-label="Pagination">
<ul>
{% if page_obj.has_previous %}
<a href="?{% url_replace request 'page' 1 %}">&laquo; first</a>
<a href="?{% url_replace request 'page' page_obj.previous_page_number %}">previous</a>
<li class="page-item page-item--nav"><a href="?{% url_replace request 'page' 1 %}">&laquo; first</a></li>
<li class="page-item page-item--nav"><a href="?{% url_replace request 'page' page_obj.previous_page_number %}">&lsaquo; previous</a></li>
{% endif %}

{% for i in page_obj|get_elided_page_range %}
Expand All @@ -15,18 +15,18 @@
</li>
{% else %}
{% if i == page_obj.paginator.ELLIPSIS %}
<li class="page-item">{{ i }}</li>
<li class="page-item page-item--ellipsis"><span class="page-link">{{ i }}</span></li>
{% else %}
<a class="page-link" href="?{% url_replace request 'page' i %}"><li class="page-item">{{ i }}</li></a>
<li class="page-item"><a class="page-link" href="?{% url_replace request 'page' i %}">{{ i }}</a></li>
{% endif %}
{% endif %}
{% endfor %}

{% if page_obj.has_next %}
<a href="?{% url_replace request 'page' page_obj.next_page_number %}">next</a>
<a href="?{% url_replace request 'page' page_obj.paginator.num_pages %}">last &raquo;</a>
<li class="page-item page-item--nav"><a href="?{% url_replace request 'page' page_obj.next_page_number %}">next &rsaquo;</a></li>
<li class="page-item page-item--nav"><a href="?{% url_replace request 'page' page_obj.paginator.num_pages %}">last &raquo;</a></li>
{% endif %}
</ul>
</div>
</nav>

{% endif %}
3 changes: 2 additions & 1 deletion work/templates/work/basic_form.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{% extends "core/emlo_common_form.html" %}
{% load static %}
{% load sass_tags %}

{% block head %}
{{ block.super }}
<link rel="stylesheet" href="{% static 'work/scss/work_overview.scss' %}?v={{ constant.VERSION }}">
<link rel="stylesheet" href="{% sass_src 'work/scss/work_overview.scss' %}?v={{ constant.VERSION }}">
<script src="/static/core/js/recref_service.js?v={{ constant.VERSION }}"></script>
<script src="{% static 'core/js/ref_publication_service.js' %}?v={{ constant.VERSION }}" defer></script>
<script src="{% static 'core/js/selectfilter.js' %}?v={{ constant.VERSION }}" defer></script>
Expand Down