Skip to content

Commit 406c4a1

Browse files
authored
Merge pull request #1006 from thecourseforum/mvp-enhanced-search
Mvp enhanced search
2 parents 8b1c42d + 72558de commit 406c4a1

File tree

6 files changed

+65
-19
lines changed

6 files changed

+65
-19
lines changed

tcf_core/context_processors.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,17 @@ def searchbar_context(request):
5050
number__gte=latest_semester.number - 50 # 50 = 5 years * 10 semesters
5151
).order_by("-number")
5252

53-
# Get weekdays from request, defaulting to all days if not specified
54-
weekdays = request.GET.get("weekdays", "MON-TUE-WED-THU-FRI").split("-")
53+
# Get saved filters from the session (or use defaults)
54+
saved_filters = request.session.get("search_filters", {})
5555

5656
context = {
5757
"disciplines": Discipline.objects.all().order_by("name"),
5858
"subdepartments": Subdepartment.objects.all().order_by("mnemonic"),
5959
"semesters": recent_semesters,
60-
"selected_disciplines": request.GET.getlist("discipline"),
61-
"selected_subdepartments": request.GET.getlist("subdepartment"),
62-
"selected_weekdays": weekdays,
63-
"from_time": request.GET.get("from_time", ""),
64-
"to_time": request.GET.get("to_time", ""),
60+
"selected_disciplines": saved_filters.get("disciplines", []),
61+
"selected_subdepartments": saved_filters.get("subdepartments", []),
62+
"selected_weekdays": saved_filters.get("weekdays", ["MON", "TUE", "WED", "THU", "FRI"]),
63+
"from_time": saved_filters.get("from_time", ""),
64+
"to_time": saved_filters.get("to_time", ""),
6565
}
6666
return context

tcf_website/templates/course/course.html

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
{% include "common/toolbar.html" with breadcrumbs=breadcrumbs sorting=True %}
1919
</div>
2020

21-
<div class="instructors container-lg mt-3">
21+
<div class="instructors container-lg mt-3 px-0">
2222
<div class="d-md-flex align-items-baseline my-3">
2323
<h1 class="mr-md-3 text-nowrap">{{ course.code }}</h1>
2424
<h2>{{ course.title }}</h2>
@@ -41,15 +41,14 @@ <h4 class="card-title">
4141
</div>
4242
{% endif %}
4343
{% if course.disciplines.exists %}
44-
<div>
44+
<div class="mb-4">
4545
<small class="mb-0 text-uppercase" style="font-size: 15px;">
4646
<i class="fa-fw" aria-hidden="true"></i>Discipline(s):
4747
</small>
48-
<ul>
49-
{% for discipline in course.disciplines.all %}
50-
<li>{{ discipline.name }}</li>
51-
{% endfor %}
52-
</ul>
48+
{% for discipline in course.disciplines.all %}
49+
{{ discipline.name }}
50+
{% if not forloop.last %} / {% endif %}
51+
{% endfor %}
5352
</div>
5453
{% endif %}
5554
<p class="card-text">

tcf_website/templates/department/department.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
{% include "common/toolbar.html" with active_course_recency=active_course_recency latest_semester=latest_semester last_five_years=last_five_years dept_id=dept_id breadcrumbs=breadcrumbs sorting=True %}
2020
</div>
2121
<div class="subdepartments mt-3">
22-
<div class="subdepartment container-lg">
22+
<div class="subdepartment container-lg px-0">
2323
{% if courses|length == 0 %}
2424
<div class="new card col p-5 text-center">
2525
<div class="card-body">

tcf_website/templates/search/searchbar.html

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,47 @@ <h6 class="filter-header">
237237
});
238238
});
239239

240-
// Add clear all functionality
240+
// Reordering function to pin selected checkboxes to the top
241+
function reorderList(containerSelector, checkboxSelector) {
242+
const container = document.querySelector(containerSelector);
243+
if (!container) return;
244+
const items = Array.from(container.children);
245+
items.sort((a, b) => {
246+
const aCheckbox = a.querySelector(checkboxSelector);
247+
const bCheckbox = b.querySelector(checkboxSelector);
248+
249+
// Check if one is selected and the other is not
250+
if (aCheckbox.checked && !bCheckbox.checked) return -1;
251+
if (!aCheckbox.checked && bCheckbox.checked) return 1;
252+
253+
// If both are either checked or unchecked, sort alphabetically by label text
254+
const aLabelText = a.querySelector('label').textContent.trim().toLowerCase();
255+
const bLabelText = b.querySelector('label').textContent.trim().toLowerCase();
256+
return aLabelText.localeCompare(bLabelText);
257+
});
258+
// Clear and reappend in new order
259+
container.innerHTML = '';
260+
items.forEach(item => container.appendChild(item));
261+
}
262+
263+
// Add event listeners to re-sort subjects whenever a subject checkbox changes
264+
document.querySelectorAll('.form-check-subjects').forEach(checkbox => {
265+
checkbox.addEventListener('change', () => {
266+
reorderList('.subject-list', '.form-check-subjects');
267+
});
268+
});
269+
270+
// Add event listeners to re-sort disciplines whenever a discipline checkbox changes
271+
document.querySelectorAll('.form-check-disciplines').forEach(checkbox => {
272+
checkbox.addEventListener('change', () => {
273+
reorderList('.discipline-list', '.form-check-disciplines');
274+
});
275+
});
276+
277+
// Call reorder on page load in case some items are selected by default
278+
reorderList('.subject-list', '.form-check-subjects');
279+
reorderList('.discipline-list', '.form-check-disciplines');
280+
241281
const resetButton = document.querySelector('button[type="reset"]');
242282
resetButton.addEventListener('click', function(e) {
243283
e.preventDefault(); // Prevent default reset behavior
@@ -261,7 +301,10 @@ <h6 class="filter-header">
261301
document.getElementById('to_time').value = '';
262302

263303
updateButtonState();
264-
304+
305+
// Reorder lists after clearing filters (so any selected items, if any, are sorted correctly)
306+
reorderList('.subject-list', '.form-check-subjects');
307+
reorderList('.discipline-list', '.form-check-disciplines');
265308
});
266309

267310
// Add weekdays handling
@@ -276,7 +319,7 @@ <h6 class="filter-header">
276319
document.querySelectorAll('.day-checkbox').forEach(checkbox => {
277320
checkbox.addEventListener('change', () => {
278321
updateWeekdays();
279-
updateFilterSummary();
322+
updateButtonState();
280323
});
281324
});
282325

tcf_website/views/browse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def department(request, dept_id: int, course_recency=None):
8282
request,
8383
"department/department.html",
8484
{
85-
"subdepartments": dept.subdepartment_set.all(),
85+
# "subdepartments": dept.subdepartment_set.all(),
8686
"dept_id": dept_id,
8787
"latest_semester": str(latest_semester),
8888
"breadcrumbs": breadcrumbs,

tcf_website/views/search.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ def search(request):
4747
"to_time": request.GET.get("to_time"),
4848
}
4949

50+
# Save filters to session
51+
request.session["search_filters"] = filters
52+
5053
if query:
5154
courses = fetch_courses(query, filters)
5255
instructors = fetch_instructors(query)
@@ -113,6 +116,7 @@ def fetch_instructors(query) -> list[dict]:
113116

114117
return instructors
115118

119+
116120
def fetch_courses(query, filters):
117121
"""Get course data using Django Trigram similarity"""
118122
# lower similarity threshold for partial searches of course titles

0 commit comments

Comments
 (0)