Add category filtering options to search functionality
This commit is contained in:
@@ -20,12 +20,60 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<form method="get" class="d-flex align-items-center" action="" id="category-search-form">
|
<form method="get" class="d-flex align-items-center" action="" id="category-search-form">
|
||||||
|
<div class="me-3">
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" type="checkbox" id="type-conditions" name="types" value="conditions" checked
|
||||||
|
hx-get="{% url 'atlas:categories_search_partial' %}"
|
||||||
|
hx-target="#category-search-results"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-include="#category-search-form"
|
||||||
|
hx-indicator="#category-search-loading" />
|
||||||
|
<label class="form-check-label" for="type-conditions">Conditions</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" type="checkbox" id="type-findings" name="types" value="findings" checked
|
||||||
|
hx-get="{% url 'atlas:categories_search_partial' %}"
|
||||||
|
hx-target="#category-search-results"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-include="#category-search-form"
|
||||||
|
hx-indicator="#category-search-loading" />
|
||||||
|
<label class="form-check-label" for="type-findings">Findings</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" type="checkbox" id="type-structures" name="types" value="structures" checked
|
||||||
|
hx-get="{% url 'atlas:categories_search_partial' %}"
|
||||||
|
hx-target="#category-search-results"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-include="#category-search-form"
|
||||||
|
hx-indicator="#category-search-loading" />
|
||||||
|
<label class="form-check-label" for="type-structures">Structures</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" type="checkbox" id="type-subspecialties" name="types" value="subspecialties" checked
|
||||||
|
hx-get="{% url 'atlas:categories_search_partial' %}"
|
||||||
|
hx-target="#category-search-results"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-include="#category-search-form"
|
||||||
|
hx-indicator="#category-search-loading" />
|
||||||
|
<label class="form-check-label" for="type-subspecialties">Subspecialties</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" type="checkbox" id="type-presentations" name="types" value="presentations" checked
|
||||||
|
hx-get="{% url 'atlas:categories_search_partial' %}"
|
||||||
|
hx-target="#category-search-results"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-include="#category-search-form"
|
||||||
|
hx-indicator="#category-search-loading" />
|
||||||
|
<label class="form-check-label" for="type-presentations">Presentations</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<input id="category-search-input" type="search" name="q" placeholder="Search all categories (conditions, findings, structures...)" value="{{ query|default:'' }}" class="form-control me-2"
|
<input id="category-search-input" type="search" name="q" placeholder="Search all categories (conditions, findings, structures...)" value="{{ query|default:'' }}" class="form-control me-2"
|
||||||
hx-get="{% url 'atlas:categories_search_partial' %}"
|
hx-get="{% url 'atlas:categories_search_partial' %}"
|
||||||
hx-trigger="keyup changed delay:500ms"
|
hx-trigger="keyup changed delay:500ms"
|
||||||
hx-target="#category-search-results"
|
hx-target="#category-search-results"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-include="#category-search-input"
|
hx-include="#category-search-form"
|
||||||
hx-indicator="#category-search-loading" />
|
hx-indicator="#category-search-loading" />
|
||||||
|
|
||||||
{# Spinner shown while HTMX request is in-flight (selector matched by hx-indicator) #}
|
{# Spinner shown while HTMX request is in-flight (selector matched by hx-indicator) #}
|
||||||
|
|||||||
+22
-16
@@ -2001,24 +2001,26 @@ class SubspecialtyAutocomplete(autocomplete.Select2QuerySetView):
|
|||||||
def categories_list(request):
|
def categories_list(request):
|
||||||
# Allow an optional global search across category models via GET `q`.
|
# Allow an optional global search across category models via GET `q`.
|
||||||
query = request.GET.get("q", "").strip()
|
query = request.GET.get("q", "").strip()
|
||||||
|
# Optional `types` GET parameter (can be repeated) to restrict which category
|
||||||
|
# models to search. Expected values: 'conditions','findings','structures',
|
||||||
|
# 'subspecialties','presentations'. If omitted, search all.
|
||||||
|
types = request.GET.getlist("types")
|
||||||
|
|
||||||
results = None
|
results = None
|
||||||
if query:
|
if query:
|
||||||
from .models import Condition, Finding, Structure, Subspecialty, Presentation
|
from .models import Condition, Finding, Structure, Subspecialty, Presentation
|
||||||
|
|
||||||
# Simple case-insensitive contains search on `name` field for each model
|
# Helper to conditionally populate each result list only when the
|
||||||
conditions = Condition.objects.filter(name__icontains=query).order_by("name")
|
# corresponding type is requested (or when no types filter provided).
|
||||||
findings = Finding.objects.filter(name__icontains=query).order_by("name")
|
def include(name: str) -> bool:
|
||||||
structures = Structure.objects.filter(name__icontains=query).order_by("name")
|
return not types or name in types
|
||||||
subspecialties = Subspecialty.objects.filter(name__icontains=query).order_by("name")
|
|
||||||
presentations = Presentation.objects.filter(name__icontains=query).order_by("name")
|
|
||||||
|
|
||||||
results = {
|
results = {
|
||||||
"conditions": conditions,
|
"conditions": Condition.objects.filter(name__icontains=query).order_by("name") if include("conditions") else (),
|
||||||
"findings": findings,
|
"findings": Finding.objects.filter(name__icontains=query).order_by("name") if include("findings") else (),
|
||||||
"structures": structures,
|
"structures": Structure.objects.filter(name__icontains=query).order_by("name") if include("structures") else (),
|
||||||
"subspecialties": subspecialties,
|
"subspecialties": Subspecialty.objects.filter(name__icontains=query).order_by("name") if include("subspecialties") else (),
|
||||||
"presentations": presentations,
|
"presentations": Presentation.objects.filter(name__icontains=query).order_by("name") if include("presentations") else (),
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, "atlas/categories_list.html", {"query": query, "results": results})
|
return render(request, "atlas/categories_list.html", {"query": query, "results": results})
|
||||||
@@ -2031,16 +2033,20 @@ def categories_search_partial(request):
|
|||||||
Expects GET param `q`.
|
Expects GET param `q`.
|
||||||
"""
|
"""
|
||||||
query = request.GET.get("q", "").strip()
|
query = request.GET.get("q", "").strip()
|
||||||
|
types = request.GET.getlist("types")
|
||||||
results = {"conditions": (), "findings": (), "structures": (), "subspecialties": (), "presentations": ()}
|
results = {"conditions": (), "findings": (), "structures": (), "subspecialties": (), "presentations": ()}
|
||||||
if query:
|
if query:
|
||||||
from .models import Condition, Finding, Structure, Subspecialty, Presentation
|
from .models import Condition, Finding, Structure, Subspecialty, Presentation
|
||||||
|
|
||||||
|
def include(name: str) -> bool:
|
||||||
|
return not types or name in types
|
||||||
|
|
||||||
results = {
|
results = {
|
||||||
"conditions": Condition.objects.filter(name__icontains=query).order_by("name"),
|
"conditions": Condition.objects.filter(name__icontains=query).order_by("name") if include("conditions") else (),
|
||||||
"findings": Finding.objects.filter(name__icontains=query).order_by("name"),
|
"findings": Finding.objects.filter(name__icontains=query).order_by("name") if include("findings") else (),
|
||||||
"structures": Structure.objects.filter(name__icontains=query).order_by("name"),
|
"structures": Structure.objects.filter(name__icontains=query).order_by("name") if include("structures") else (),
|
||||||
"subspecialties": Subspecialty.objects.filter(name__icontains=query).order_by("name"),
|
"subspecialties": Subspecialty.objects.filter(name__icontains=query).order_by("name") if include("subspecialties") else (),
|
||||||
"presentations": Presentation.objects.filter(name__icontains=query).order_by("name"),
|
"presentations": Presentation.objects.filter(name__icontains=query).order_by("name") if include("presentations") else (),
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, "atlas/_categories_search_results.html", {"query": query, "results": results})
|
return render(request, "atlas/_categories_search_results.html", {"query": query, "results": results})
|
||||||
|
|||||||
Reference in New Issue
Block a user