Listing pages filtering - #451
Conversation
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
helenb
left a comment
There was a problem hiding this comment.
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> | |||
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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"> |
There was a problem hiding this comment.
Super nitpick: I believe we only have one group per page? So could name this listing-filters__group
| @include media-query(medium) { | ||
| flex-direction: row; | ||
| flex-wrap: wrap; | ||
| align-items: center; |
There was a problem hiding this comment.
Nitpick: I'm not sure the align-items: center is necessary here as the dropdown text never wraps.
|
|
||
| &__dropdown { | ||
| position: relative; | ||
| flex: 0 1 auto; |
There was a problem hiding this comment.
Query: what do the flex and min-width rules add here?
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
Query: what's the logic for having this text rather than just hiding the whole drop-down if there are no options?
There was a problem hiding this comment.
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 %} |
There was a problem hiding this comment.
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".
There was a problem hiding this comment.
That's a good recommendation, I've implemented this here - 8b4c69b
|
|
||
| constructor(node) { | ||
| this.node = node; | ||
| this.dropdowns = Array.from(node.querySelectorAll('details')); |
There was a problem hiding this comment.
Nitpick: it might be nice to add a data-attribute rather than querying the details element.
| <form method="get" class="listing-filters" data-listing-filters> | ||
| <div class="listing-filters__groups"> | ||
| {% for dropdown in filter_dropdowns %} | ||
| <details class="listing-filters__dropdown"> |
There was a problem hiding this comment.
I would suggest adding a comment here to say the dropdowns jest test will need updating if this markup structure changes.
|
Q: does this supersede #438 ? |
…of generic no results text
- 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
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.
tbx/core/listing/)slugfield added on theEventTypesnippet, used in event-filter URLsHow 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.
New page, light mode with multiple filters
Work page, light mode with multiple filters, mobile
Pattern library component
MR Checklist
Unit tests
Documentation
Browser testing
Data protection
Light and dark mode
Accessibility
Sustainability
Pattern library