Skip to content

Listing pages filtering - #451

Open
jhancock532 wants to merge 19 commits into
migration-2026from
feature/listing-filters
Open

Listing pages filtering#451
jhancock532 wants to merge 19 commits into
migration-2026from
feature/listing-filters

Conversation

@jhancock532

@jhancock532 jhancock532 commented Aug 24, 2026

Copy link
Copy Markdown

Description of Changes Made

Adds sector / service filtering to the news and work listing pages, as well as timing / event type for the event listing page.

  • Shared listing-filter form and context helpers (tbx/core/listing/)
  • Shared filter UI: dropdowns, active-filter pills, clear-all, JS component and styles
  • slug field added on the EventType snippet, used in event-filter URLs

How to Test

Test locally by confirming news, work and event listing pages filter correctly. By default, the event listing page should only show upcoming events.

Confirm that the user can select multiple filter options from the drop-down checkboxes, and apply their filter choices with the filter button.

Confirm that when the page loads with filters applied, these filters are shown in the active filters session. Dismissing one of the active filters causes the page to reload with that filter no longer applied.

Confirm that with active filters applied, pressing the "Clear all filters" button then removes all the active filters from the page.

Check out the listing filters component in the pattern library: http://localhost:8000/pattern-library/pattern/patterns/molecules/listing-filters/listing-filters.html

Screenshots

Expand to see more

Event page, dark mode with event type filters.

image

New page, light mode with multiple filters

image

Work page, light mode with multiple filters, mobile

image

Pattern library component

image

MR Checklist

  • Add a description of your pull request and instructions for the reviewer to verify your work.
  • If your pull request is for a specific ticket, link to it in the description.
  • Stay on point and keep it small so the merge request can be easily reviewed.
  • Tests and linting passes.

Unit tests

  • Added
  • Not required

Documentation

Browser testing

  • I have tested in the following browsers and environments (edit the list as required)
    • Latest version of Chrome on mac
    • Latest version of Firefox on mac
    • Latest version of Safari on mac
    • Safari on last two versions of iOS
    • Chrome on last two versions of Android
  • Not required

Data protection

  • Not relevant
  • This adds new sources of PII and documents it and modifies Birdbath processors accordingly

Light and dark mode

  • I have tested the changes in both light and dark mode
  • The change is not relevant to dark and light mode

Accessibility

  • Automated WCAG 2.1 tests pass
  • HTML validation passes
  • Manual WCAG 2.1 tests completed
  • I have tested in a screen reader
  • I have tested in high-contrast mode
  • Any animations removed for prefers-reduced-motion
  • Not required

Sustainability

  • Images are optimised and lazy-loading used where appropriate
  • SVGs have been optimised
  • Performance and transfer of data considered
  • If JavaScript is needed alternatives have been considered
  • Not required

Pattern library

  • The pattern library component for this template displays correctly, and does not break parent templates
  • The styleguide is updated if relevant
  • Changes are not relevant the pattern library

jhancock532 and others added 14 commits August 24, 2026 09:27
Reusable backend core for validating listing query params and building
the shared filter UI context, used by the blog, work and events listings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Filter dropdowns, active-filter pills and the clear-all control shared by
the listing pages, plus the JS component and styles that drive them.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The slug is used as the value in event-filter URLs. Includes a factory
for test data.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Filters match both WorkPage and HistoricalWorkPage subtypes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Improve high contrast mode accessibility for submit button
- Remove excess comments
- Standardise use of SCSS styles for listing filters component
@jhancock532 jhancock532 changed the title Draft: Listing pages filtering Listing pages filtering Aug 24, 2026
@jhancock532
jhancock532 marked this pull request as ready for review August 24, 2026 10:21
@jhancock532
jhancock532 requested a review from helenb August 24, 2026 10:21
@jhancock532 jhancock532 self-assigned this Aug 24, 2026
@jhancock532
jhancock532 requested a review from tm-kn August 24, 2026 10:21

@helenb helenb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jhancock532 this is looking really good. Most of my comments are pretty minor. Note I think my comments may come in two reviews as I had another tab open to look a the CSS and markup changes in tandem.

@@ -0,0 +1,6 @@
<div class="listing-header grid__listing-header mb-spacerSmallPlus lg:mb-spacerMedium">
<h1 class="heading heading--mega">{{ item.title }}</h1>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder - do we need to include the heading 1 and strapline in a special component here? The title-filters.html component needs to include the heading 1 because of the layout, but as the filters are laid out below the heading then we could just render the heading and strapline in the page template, and include the listing filters below. If we do need to keep it, can we add a yaml file for it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this in just to reduce a bit of code duplication, so we don't necessarily need this - I've reverted the change here - 4805d19

progressive enhancement.
{% endcomment %}
<form method="get" class="listing-filters" data-listing-filters>
<div class="listing-filters__groups">

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nitpick: I believe we only have one group per page? So could name this listing-filters__group

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this here: 7889473

@include media-query(medium) {
flex-direction: row;
flex-wrap: wrap;
align-items: center;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: I'm not sure the align-items: center is necessary here as the dropdown text never wraps.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, I've fixed this here ee1020c


&__dropdown {
position: relative;
flex: 0 1 auto;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Query: what do the flex and min-width rules add here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These don't meaningfully change the styles, I think they were copied from the previous MR unnecessarily - removed here ee1020c

</li>
{% empty %}
<li class="listing-filters__option listing-filters__option--empty">
No options available.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Query: what's the logic for having this text rather than just hiding the whole drop-down if there are no options?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't good logic for this, it's much better UX to hide the whole drop-down instead - I've corrected this here - ee1020c#diff-bcf5b9fd7ffbe3ca1c03c6eec959269d99c16129f435e7b9c7a02a3545e12d4bR12

<li class="grid__paragraph rich-text">
{% if request.GET.filter == "past" %}
<p>There are no past events.</p>
{% if has_active_filters %}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small improvement here might be to check if the current active filter is only to show upcoming events and nothing else - in that scenario we could display the no_events_message rather than "No events match the selected filters".

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good recommendation, I've implemented this here - 8b4c69b

Comment thread tbx/static_src/javascript/components/listing-filters.js

constructor(node) {
this.node = node;
this.dropdowns = Array.from(node.querySelectorAll('details'));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: it might be nice to add a data-attribute rather than querying the details element.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, I've corrected this here - 4805d19

<form method="get" class="listing-filters" data-listing-filters>
<div class="listing-filters__groups">
{% for dropdown in filter_dropdowns %}
<details class="listing-filters__dropdown">

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest adding a comment here to say the dropdowns jest test will need updating if this markup structure changes.

@jhancock532 jhancock532 Aug 26, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the comment - 4805d19 - I also managed to immediately forget to update my Jest test since I updated the data attribute for this dropdown, so I corrected it in bf75e9b when I saw the pipeline failure

@helenb helenb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remaining review comments.

@zerolab

zerolab commented Aug 26, 2026

Copy link
Copy Markdown
Member

Q: does this supersede #438 ?

- Make focus styles for buttons consistent.
- Use data attribute instead of matching on details element
- Add comment reminder to update Jest markup
- Revert change moving minor duplicate code to shared component
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants