Skip to content

Commit 09f11b9

Browse files
authored
Merge pull request #763 from maykinmedia/feature/1711-hide-filters-when-unused
[#1711] [#1710] Make search filters conditional and add mobile toggle
2 parents 1503f78 + b41bf06 commit 09f11b9

File tree

11 files changed

+252
-44
lines changed

11 files changed

+252
-44
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
{% load i18n filter_tags icon_tags form_tags %}
1+
{% load i18n filter_tags icon_tags button_tags form_tags %}
22

33
<div>
4-
<fieldset class="filter filter--open" aria-label="{% trans "Filter" %}">
4+
<fieldset class="filter" aria-label="{% trans "Filter" %}">
5+
{% button href="#" icon="expand_more" icon_position="after" extra_classes="filter__mobile filter--toggle" bordered=False text=field.label %}
56
<legend class="filter__title">
6-
{{ field.label }}
7+
<span class="filter__legend-label">{{ field.label }}</span>
78
</legend>
89
<div class="filter__list">
910
{% for option in field.field.choices %}
1011
{% choice_checkbox choice=option name=field.name data=field.data index=forloop.counter %}
1112
{% endfor %}
1213
</div>
1314
</fieldset>
14-
<hr class="divider divider--small">
15+
<hr class="divider divider--tiny">
1516
</div>

src/open_inwoner/configurations/admin.py

+10
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ class SiteConfigurarionAdmin(OrderedInlineModelAdminMixin, SingletonModelAdmin):
162162
),
163163
},
164164
),
165+
(
166+
_("Search filter options"),
167+
{
168+
"fields": (
169+
"search_filter_categories",
170+
"search_filter_tags",
171+
"search_filter_organizations",
172+
)
173+
},
174+
),
165175
(_("Emails"), {"fields": ("email_new_message",)}),
166176
(
167177
_("Openid Connect"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Generated by Django 3.2.20 on 2023-09-18 10:09
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("configurations", "0051_merge_20230907_1800"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="siteconfiguration",
15+
name="search_filter_categories",
16+
field=models.BooleanField(
17+
default=True,
18+
help_text="Whether to show category-checkboxes in order to filter the search result.",
19+
verbose_name="Add category filter for search results",
20+
),
21+
),
22+
migrations.AddField(
23+
model_name="siteconfiguration",
24+
name="search_filter_organizations",
25+
field=models.BooleanField(
26+
default=True,
27+
help_text="Whether to show organization-checkboxes in order to filter the search result.",
28+
verbose_name="Add organization filter for search results",
29+
),
30+
),
31+
migrations.AddField(
32+
model_name="siteconfiguration",
33+
name="search_filter_tags",
34+
field=models.BooleanField(
35+
default=True,
36+
help_text="Whether to show tag-checkboxes in order to filter the search result.",
37+
verbose_name="Add tag filter for search results",
38+
),
39+
),
40+
]

src/open_inwoner/configurations/models.py

+25
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,31 @@ class SiteConfiguration(SingletonModel):
316316
verbose_name=_("Plan help"),
317317
help_text=_("The help text for the plan page."),
318318
)
319+
320+
# search filters
321+
search_filter_categories = models.BooleanField(
322+
verbose_name=_("Add category filter for search results"),
323+
default=True,
324+
help_text=_(
325+
"Whether to show category-checkboxes in order to filter the search result."
326+
),
327+
)
328+
search_filter_tags = models.BooleanField(
329+
verbose_name=_("Add tag filter for search results"),
330+
default=True,
331+
help_text=_(
332+
"Whether to show tag-checkboxes in order to filter the search result."
333+
),
334+
)
335+
search_filter_organizations = models.BooleanField(
336+
verbose_name=_("Add organization filter for search results"),
337+
default=True,
338+
help_text=_(
339+
"Whether to show organization-checkboxes in order to filter the search result."
340+
),
341+
)
342+
343+
# email notifications
319344
email_new_message = models.BooleanField(
320345
verbose_name=_("Send email about a new message"),
321346
default=True,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
export class FilterMobile {
2+
static selector = '.filter--toggle'
3+
4+
constructor(node) {
5+
this.node = node
6+
this.node.addEventListener('click', this.toggleOpen.bind(this))
7+
document.addEventListener('keydown', this.filterClosing.bind(this), false)
8+
}
9+
10+
toggleOpen(event) {
11+
event.preventDefault()
12+
console.log('this is mobile')
13+
const filterParent = this.node.parentElement
14+
if (filterParent) {
15+
filterParent.classList.toggle('filter--open')
16+
}
17+
}
18+
19+
filterClosing(event) {
20+
if (event.type === 'keydown' && event.key === 'Escape') {
21+
const filterParent = this.node.parentElement
22+
if (filterParent) {
23+
filterParent.classList.remove('filter--open')
24+
}
25+
}
26+
}
27+
}
28+
29+
/**
30+
* Controls the toggling of filter lists on mobile to view more
31+
*/
32+
document
33+
.querySelectorAll(FilterMobile.selector)
34+
.forEach((filterToggle) => new FilterMobile(filterToggle))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const radioButtons = document.querySelectorAll(
2+
'.feedback__options .button-radio__input'
3+
)
4+
5+
;[...radioButtons].forEach((radioButton) => {
6+
radioButton.addEventListener('click', (event) => {
7+
const feedbackRemarks = document.querySelectorAll('.feedback__remark')
8+
;[...feedbackRemarks].forEach((feedbackRemark) =>
9+
feedbackRemark.classList.add('feedback__remark--show')
10+
)
11+
})
12+
})
13+
14+
let timerId = null
15+
16+
const searchForm = document.getElementById('search-form')
17+
18+
const filterButtons = document.querySelectorAll('.filter .checkbox__input')
19+
;[...filterButtons].forEach((checkbox) => {
20+
checkbox.addEventListener('change', (event) => {
21+
clearTimeout(timerId)
22+
23+
// Set a new interval
24+
timerId = setTimeout(() => {
25+
searchForm.submit()
26+
}, 250)
27+
})
28+
})
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,2 @@
1-
const radioButtons = document.querySelectorAll(
2-
'.feedback__options .button-radio__input'
3-
)
4-
5-
;[...radioButtons].forEach((radioButton) => {
6-
radioButton.addEventListener('click', (event) => {
7-
const feedbackRemarks = document.querySelectorAll('.feedback__remark')
8-
;[...feedbackRemarks].forEach((feedbackRemark) =>
9-
feedbackRemark.classList.add('feedback__remark--show')
10-
)
11-
})
12-
})
13-
14-
let timerId = null
15-
16-
const searchForm = document.getElementById('search-form')
17-
18-
const filterButtons = document.querySelectorAll('.filter .checkbox__input')
19-
;[...filterButtons].forEach((checkbox) => {
20-
checkbox.addEventListener('change', (event) => {
21-
clearTimeout(timerId)
22-
23-
// Set a new timeout
24-
timerId = setTimeout(() => {
25-
searchForm.submit()
26-
}, 250)
27-
})
28-
})
1+
import './filter-mobile'
2+
import './filter-options'

src/open_inwoner/scss/components/Divider/Divider.scss

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
margin: var(--spacing-large) 0;
77
}
88

9+
&--tiny {
10+
margin: var(--spacing-medium) 0;
11+
}
12+
913
@media (min-width: 768px) {
1014
margin: var(--spacing-giant) 0;
1115
}
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,106 @@
11
.filter {
22
border: 0 solid transparent;
3+
margin: 0;
4+
padding: 0;
35

4-
&--open {
5-
.filter__list {
6+
@media (min-width: 768px) {
7+
padding: 0 var(--spacing-large) var(--spacing-large) var(--spacing-large);
8+
}
9+
10+
&__list {
11+
padding-top: 0;
12+
padding-bottom: var(--spacing-large);
13+
display: none;
14+
grid-template-columns: 1fr;
15+
gap: var(--spacing-large);
16+
17+
@media (min-width: 768px) {
618
display: grid;
19+
padding-top: var(--spacing-large);
20+
padding-bottom: 0;
21+
}
22+
23+
.checkbox .checkbox__label {
24+
cursor: pointer;
725
}
826
}
927

28+
.button {
29+
color: var(--font-color-body);
30+
font-weight: bold;
31+
padding: 0;
32+
}
33+
1034
&__title {
1135
color: var(--font-color-heading-4);
1236
font-family: var(--font-family-heading);
1337
font-size: var(--font-size-heading-4);
1438
font-weight: bold;
1539
letter-spacing: 0;
1640
line-height: 21px;
17-
cursor: pointer;
1841
display: flex;
1942
}
2043

21-
&__list {
22-
padding-top: var(--spacing-large);
23-
display: none;
24-
grid-template-columns: 1fr;
25-
gap: var(--spacing-large);
44+
&__legend {
45+
&-label {
46+
display: none;
47+
@media (min-width: 768px) {
48+
display: inline;
49+
}
50+
}
51+
}
52+
53+
.divider {
54+
background-color: yellow;
55+
border: red solid 5px !important;
56+
&--small {
57+
display: none;
58+
@media (min-width: 768px) {
59+
display: block;
60+
}
61+
}
62+
&--tiny {
63+
display: block;
64+
@media (min-width: 768px) {
65+
display: none;
66+
}
67+
}
68+
}
69+
70+
&__mobile {
71+
@media (min-width: 768px) {
72+
display: none;
73+
}
74+
}
75+
76+
//toggling dropdows
77+
&.filter--open {
78+
.button {
79+
color: var(--color-secondary);
80+
padding: 0;
81+
}
82+
83+
.button--textless [class*='icon'] {
84+
display: inline-block;
85+
right: var(--spacing-large);
86+
top: 0;
87+
transform: rotate(180deg);
88+
transition: all 0.3s;
89+
}
90+
91+
.filter__list {
92+
display: grid;
93+
}
94+
}
95+
}
96+
97+
.grid__filters {
98+
.h2 {
99+
border-bottom: 2px solid var(--color-gray-light);
100+
display: block;
101+
padding-bottom: var(--spacing-large);
102+
@media (min-width: 768px) {
103+
display: none;
104+
}
26105
}
27106
}

src/open_inwoner/templates/pages/search.html

+14-4
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,20 @@ <h1 class="h1">{% trans "Zoeken naar " %} "{{ form.query.value }}"</h1>
1818
{# facets and results section #}
1919
{% if paginator.count %}
2020
<div class="grid">
21-
<aside class="grid__sidebar" aria-label="{% trans "Zoekfilters" %}">
22-
{% filter field=form.categories %}
23-
{% filter field=form.tags %}
24-
{% filter field=form.organizations %}
21+
<aside class="grid__sidebar grid__filters" aria-label="{% trans "Zoekfilters" %}">
22+
{% if search_filter_categories or search_filter_tags or search_filter_organizations %}
23+
<h2 class="h2">{% trans "Zoekfilters" %}</h2>
24+
{% if search_filter_categories %}
25+
{% filter field=form.categories %}
26+
{% endif %}
27+
{% if search_filter_tags %}
28+
{% filter field=form.tags %}
29+
{% endif %}
30+
{% if search_filter_organizations %}
31+
{% filter field=form.organizations %}
32+
{% endif %}
33+
{% endif %}
34+
{# end search filters #}
2535
</aside>
2636

2737
<div class="grid__main">

src/open_inwoner/utils/context_processors.py

+3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ def settings(request):
8080
"extra_css": config.extra_css,
8181
"menu_categories": Category.get_root_nodes().published(),
8282
"search_form": SearchForm(auto_id=False),
83+
"search_filter_categories": config.search_filter_categories,
84+
"search_filter_tags": config.search_filter_tags,
85+
"search_filter_organizations": config.search_filter_organizations,
8386
"has_general_faq_questions": Question.objects.general().exists(),
8487
"settings": dict(
8588
[(k, getattr(django_settings, k, None)) for k in public_settings]

0 commit comments

Comments
 (0)