Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

πŸ’„ [#3016] Desktop search filters - new design #1632

Open
wants to merge 21 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
{% load i18n icon_tags button_tags form_tags %}

<div>
<fieldset class="filter" aria-label="{% trans "Filter" %}">
{% button href="#" icon="expand_more" icon_position="after" extra_classes="filter__mobile filter--toggle" bordered=False text=field.label %}
<legend class="filter__title">
<span class="filter__legend-label">{{ field.label }}</span>
</legend>
<div class="filter__container">
<details class="filter" aria-label="{% trans "Filter" %}" open>
<summary class="filter__title">
<span class="filter__summary-label">
{{ field.label }}
<span class="filter__counter">({{field.field.choices|length}})</span>
</span>
{% icon icon="expand_more" outlined=icon_outlined %}
</summary>
<div class="filter__list">
{% for option in field.field.choices %}
{% choice_checkbox choice=option name=field.name data=field.data index=forloop.counter form_id=form_id %}
{% choice_checkbox as_tag=True choice=option name=field.name data=field.data index=forloop.counter form_id=form_id %}
{% endfor %}
</div>
</fieldset>
<hr class="divider divider--tiny">
</details>
</div>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% load l10n form_tags %}

<div class="checkbox">
<div class="checkbox {% if as_tag %}checkbox--tag{% endif %}">
<input
class="checkbox__input"
type="checkbox"
Expand Down
33 changes: 0 additions & 33 deletions src/open_inwoner/js/components/search/filter-mobile.js

This file was deleted.

15 changes: 13 additions & 2 deletions src/open_inwoner/js/components/search/filter-options.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
const searchForm = document.getElementById('search-form')
const checkboxes = document.querySelectorAll('.filter .checkbox__input')
const resetButton = document.querySelector('.filter__reset .button')

document.querySelectorAll('.filter .checkbox__input').forEach((checkbox) => {
checkboxes.forEach((checkbox) => {
checkbox.addEventListener('change', (event) => {
searchForm.submit()
searchForm?.submit()
})
})

resetButton?.addEventListener('click', () => {
// Only reset the form when there are some checkboxes selected
if (!Array.from(checkboxes).some((checkbox) => !!checkbox.checked)) return
checkboxes.forEach((checkbox) => {
checkbox.checked = false
})
searchForm?.submit()
})
1 change: 0 additions & 1 deletion src/open_inwoner/js/components/search/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import './filter-mobile'
import './filter-options'

const searchForm = document.getElementById('search-form')
Expand Down
108 changes: 33 additions & 75 deletions src/open_inwoner/scss/components/Filter/Filter.scss
Original file line number Diff line number Diff line change
@@ -1,22 +1,42 @@
.filter {
border: 0 solid transparent;
border-top: 1px solid var(--color-gray);
user-select: none;
margin: 0;
padding: 0;
padding: var(--spacing-large) 0;

&[open] [class*='icons'] {
transform: rotate(180deg);
transition: all 0.3s;
}

@media (min-width: 768px) {
padding: 0 var(--spacing-large) var(--spacing-large) var(--spacing-large);
padding: var(--spacing-extra-large) 0;
}

&__container:last-of-type & {
border-bottom: 1px solid var(--color-gray);
}

&__reset {
display: flex;
justify-content: flex-end;

.button {
height: fit-content;
padding: 0;
margin-bottom: 0.75rem; // 12px
margin-top: 1.125rem; // 18px
}
}

&__list {
padding-top: 0;
padding-bottom: var(--spacing-large);
display: none;
padding-top: var(--spacing-large);
display: grid;
grid-template-columns: 1fr;
gap: var(--spacing-large);

@media (min-width: 768px) {
display: grid;
padding-top: var(--spacing-large);
padding-top: var(--spacing-extra-large);
padding-bottom: 0;
}

Expand All @@ -25,81 +45,19 @@
}
}

.button {
color: var(--font-color-body);
font-weight: bold;
padding: 0;
}

&__title {
color: var(--font-color-heading-4);
color: var(--color-gray-dark);
font-family: var(--font-family-heading);
font-size: var(--font-size-heading-4);
font-weight: bold;
letter-spacing: 0;
line-height: 21px;
display: flex;
justify-content: space-between;
cursor: pointer;
}

&__legend {
&-label {
display: none;
@media (min-width: 768px) {
display: inline;
}
}
}

.divider {
border: red solid 5px !important;
&--small {
display: none;
@media (min-width: 768px) {
display: block;
}
}
&--tiny {
display: block;
@media (min-width: 768px) {
display: none;
}
}
}

&__mobile {
@media (min-width: 768px) {
display: none;
}
}

//toggling dropdows
&.filter--open {
.button {
color: var(--color-secondary);
padding: 0;
}

.button--textless [class*='icons'] {
display: inline-block;
right: var(--spacing-large);
top: 0;
transform: rotate(180deg);
transition: all 0.3s;
}

.filter__list {
display: grid;
}
}
}

.grid__filters {
.utrecht-heading-2 {
border-bottom: 2px solid var(--color-gray-light);
display: block;
padding-bottom: var(--spacing-large);
@media (min-width: 768px) {
display: none;
}
&__counter {
color: var(--color-tinted-mute);
}
}
38 changes: 38 additions & 0 deletions src/open_inwoner/scss/components/Form/Checkbox.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,42 @@
.checkbox {
&--tag {
display: flex;
max-height: 33px;
padding: var(--spacing-small) var(--spacing-medium);
border-radius: var(--border-radius);
color: var(--color-gray-dark);
background: var(--color-gray-lightest);
border: 1px solid var(--color-gray-light);
width: fit-content;

&:has(input:checked) {
color: var(--color-font-primary);
background: var(--color-primary);
border-color: var(--color-primary);

.checkbox__label:after {
content: '';
display: block;
background-image: url("data:image/svg+xml,%3Csvg width='20' height='21' viewBox='0 0 20 21' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0_2541_1098)'%3E%3Cpath d='M15.1263 5.84163L10.8215 10.1464L10.468 10.5L10.8215 10.8535L15.1263 15.1583L14.6584 15.6262L10.3536 11.3214L10.0001 10.9679L9.64653 11.3214L5.34175 15.6262L4.87386 15.1583L9.17863 10.8535L9.53219 10.5L9.17863 10.1464L4.87385 5.84163L5.34175 5.37373L9.64653 9.67851L10.0001 10.0321L10.3536 9.67851L14.6584 5.37373L15.1263 5.84163Z' fill='white' stroke='white'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0_2541_1098'%3E%3Crect width='20' height='20' fill='white' transform='translate(0 0.5)'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A");
width: 1.25rem;
height: 1.25rem;
}
}

& .checkbox__label {
gap: var(--spacing-medium);
align-items: center;
color: inherit !important;
white-space: nowrap;
padding: 0 !important;
display: flex;

&:before {
content: unset !important;
}
}
}

.checkbox__input {
opacity: 0;
width: 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
flex-direction: column;
gap: var(--spacing-large);

@media (min-width: 768px) {
margin-top: 3.375rem; // 54px
}

.grid {
gap: var(--spacing-large);
}
Expand Down
22 changes: 19 additions & 3 deletions src/open_inwoner/search/tests/test_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,23 @@ def test_search_with_filters(self):
expect(checkbox).to_be_enabled()
expect(checkbox).not_to_be_checked()

def _click_checkbox_for_name(page, name):
# our checkbox widget hides the <input> element and styles the <label> and a pseudo-element
# this a problem for playwright accessibility, so we find the label for the checkbox and click on the label like a user would
def _click_checkbox_for_name(page=page, name=''):
# Open het details-element
# Zoek het juiste <details>-element met de opgegeven checkbox naam
details_element = page.locator(
".filter", has=page.get_by_role("checkbox", name=name)
)

# print(details_element.is_visible())

# Open het <details>-element
# details_element.click()


# Wacht tot het specifieke <details>-element open is
# expect(details_element).to_have_attribute("open", "")

# Zoek de checkbox met de juiste naam, filter het via de 'checkbox--tag' class, en klik op de bijbehorende label
page.locator(".checkbox").filter(
has=page.get_by_role("checkbox", name=name)
).locator("label").click()
Expand All @@ -319,6 +333,8 @@ def _test_search(checkbox_name, expected_text):
expected_text
)

print("Tag 1", self.product1.name)

_test_search("Tag 1", self.product1.name)
_test_search("Tag 2", self.product2.name)
_test_search("Organization 1", self.product1.name)
Expand Down
33 changes: 25 additions & 8 deletions src/open_inwoner/templates/pages/search.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% extends 'master.html' %}
{% load i18n form_tags utils icon_tags grid_tags pagination_tags %}
{% load i18n form_tags utils icon_tags grid_tags pagination_tags button_tags %}

{% block main_inner %}
{# search term section #}
Expand All @@ -15,15 +15,32 @@ <h1 class="utrecht-heading-1">{% trans "Zoekresultaten voor " %} "{% firstof sea
{% if paginator.count %}
{% if search_filter_categories or search_filter_tags or search_filter_organizations %}
<aside class="grid__sidebar grid__filters" aria-label="{% trans "Zoekfilters" %}">
<h2 class="utrecht-heading-2">{% trans "Zoekfilters" %}</h2>
{% if search_filter_categories %}
{% include "components/Filter/Filter.html" with field=search_form.categories form_id="search-form" only %}
{% if search_filter_categories and search_form.categories.field.choices|length != 0 %}
{% define 0 as open_index %}
{% elif search_filter_tags and search_form.tags.field.choices|length != 0 %}
{% define 1 as open_index %}
{% elif search_filter_organizations and search_form.organizations.field.choices|length != 0 %}
{% define 2 as open_index %}
{% else %}
{% define 3 as open_index %}
{% endif %}
{% if search_filter_tags %}
{% include "components/Filter/Filter.html" with field=search_form.tags form_id="search-form" only %}

{% if open_index <= 2 %}
<div class='filter__reset'>
{% button transparent=True type='button' inline=True text=_('Wis alle?') %}
</div>
{% endif %}


{% if search_filter_categories and search_form.categories.field.choices|length != 0 %}
{% include "components/Filter/Filter.html" with field=search_form.categories form_id="search-form" initial_open=open_index|is_same:0 only %}
{% endif %}
{% if search_filter_tags and search_form.tags.field.choices|length != 0 %}
TAGS
{% include "components/Filter/Filter.html" with field=search_form.tags form_id="search-form" initial_open=open_index|is_same:1 only %}
{% endif %}
{% if search_filter_organizations %}
{% include "components/Filter/Filter.html" with field=search_form.organizations form_id="search-form" only %}
{% if search_filter_organizations and search_form.organizations.field.choices|length != 0 %}
{% include "components/Filter/Filter.html" with field=search_form.organizations form_id="search-form" initial_open=open_index|is_same:2 only %}
{% endif %}
</aside>
{% endif %}
Expand Down
10 changes: 10 additions & 0 deletions src/open_inwoner/utils/templatetags/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,13 @@ def cookies_accepted(request: HttpRequest) -> bool:
@stringfilter
def markdown(value):
return md.markdown(value, extensions=["markdown.extensions.fenced_code"])


@register.simple_tag
def define(val=None):
return val


@register.filter
def is_same(value, arg):
return value == arg
Loading