Skip to content

Commit cb31d87

Browse files
Fatima-Tahirihalaij1
authored andcommitted
Implement search for courses on A+ frontpage
Fixes #579
1 parent cefd417 commit cb31d87

9 files changed

Lines changed: 134 additions & 43 deletions

File tree

assets/css/main.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

assets/sass/components/_frontpage-cards.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
padding-left: 10px;
1212
padding-right: 10px;
1313
width: 100%;
14-
> .action {
14+
.action {
1515
display: flex;
1616
flex-direction: row;
1717
justify-content: center;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function initCourseSearchClear() {
2+
const clearButton = document.getElementById("clear-search");
3+
const input = document.getElementById("search-input");
4+
const form = document.getElementById("course-search-form");
5+
6+
if (clearButton && input && form) {
7+
clearButton.addEventListener("click", function () {
8+
input.value = "";
9+
form.submit();
10+
});
11+
}
12+
}
13+
14+
document.addEventListener("DOMContentLoaded", initCourseSearchClear);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{% load i18n %}
2+
{% load course %}
3+
4+
{% load static %}
5+
{% block scripts %}
6+
7+
<script src="{% static 'course/course_search.js' %}"></script>
8+
9+
{% endblock %}
10+
11+
<form method="get" class="form-inline" id="course-search-form">
12+
<div class="d-flex gap-2">
13+
<div class="form-group position-relative">
14+
<input type="text"
15+
name="search"
16+
id="search-input"
17+
class="form-control"
18+
placeholder="{% translate 'SEARCH_COURSES' %}"
19+
value="{{ request.GET.search }}"
20+
autocomplete="off"
21+
style="{% if request.GET.search %}padding-right: 2em;{% endif %}"
22+
/>
23+
{% if request.GET.search %}
24+
<a
25+
id="clear-search"
26+
class="btn btn-link position-absolute top-50 end-0 translate-middle-y px-2"
27+
aria-label="{% translate 'CLEAR_SEARCH' %}"
28+
href="#"
29+
>
30+
<i class="bi-x-lg" aria-hidden="true"></i>
31+
</a>
32+
{% endif %}
33+
</div>
34+
<button type="submit" class="aplus-button--default aplus-button--md">{% translate 'SEARCH' %}</button>
35+
</div>
36+
</form>

course/templates/course/archive.html

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77

88
{% block content %}
99
<div class="frontpage-panel">
10-
<div class="page-header">
11-
<h1>{% translate "COURSE_ARCHIVE" %}
10+
<div class="page-header d-flex justify-content-between align-items-center">
11+
<h1>{% translate "COURSE_ARCHIVE" %}</h1>
12+
<div class="mt-4">{% include "course/_search_courses_form.html" %}</div>
1213
</div>
1314
{% regroup instances by starting_time|date:"Y" as instances_by_year %}
1415

@@ -20,7 +21,15 @@ <h2>{{ year }}</h2>
2021
<div class="cards">
2122
{% include "course/_course_cards.html" with instances=year_instances condensed=True %}
2223
</div>
23-
</section>
24+
</section>
2425
{% endfor %}
26+
27+
{% if not instances and not siteadvert %}
28+
<div class="panel-body">
29+
<p class="panel-default-text">
30+
{% translate "NO_COURSES_FOUND" %}
31+
</p>
32+
</div>
33+
{% endif %}
2534
</div>
2635
{% endblock %}

course/templates/course/index.html

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,12 @@ <h2>{% translate "MY_COURSES" %}</h2>
3434
<section class="frontpage frontpage-section">
3535
<div class="section-heading">
3636
<h2>{% translate "ALL_ONGOING_COURSES" %}</h2>
37-
<div class="action">
38-
{% url 'archive' as url %}
39-
<a href="{{ url }}">{% translate "SEE_ALL_COURSES" %}</a>
37+
<div class="d-flex gap-4">
38+
<div class="action">
39+
{% url 'archive' as url %}
40+
<a href="{{ url }}">{% translate "SEE_ALL_COURSES" %}</a>
41+
</div>
42+
<div style="margin-top: 20px; margin-bottom: 10px;">{% include "course/_search_courses_form.html" %}</div>
4043
</div>
4144
</div>
4245
<div class="cards">
@@ -62,12 +65,12 @@ <h3 class="card-title">{{ advert.title }}</h3>
6265
{% endif %}
6366
{% if all_instances %}
6467
{% include "course/_course_cards.html" with instances=all_instances condensed=False %}
65-
{% endif %}
68+
{% endif %}
6669
</div>
6770
{% if not all_instances and not siteadvert %}
6871
<div class="panel-body">
6972
<p class="panel-default-text">
70-
{% translate "NO_ACTIVE_COURSES" %}
73+
{% translate "NO_COURSES_FOUND" %}
7174
</p>
7275
</div>
7376
{% endif %}

course/views.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from django.conf import settings
77
from django.contrib import messages
88
from django.core.exceptions import PermissionDenied
9-
from django.db.models import Prefetch
9+
from django.db.models import Prefetch, Q
1010
from django.http import Http404
1111
from django.http.response import HttpResponse, HttpResponseRedirect
1212
from django.shortcuts import get_object_or_404
@@ -74,7 +74,11 @@ def get_common_objects(self):
7474
if instance not in my_instances:
7575
my_instances.append(instance)
7676

77+
query = self.request.GET.get("search", "").strip()
7778
all_instances = CourseInstance.objects.get_visible(user).filter(ending_time__gte=end_threshold)
79+
if query:
80+
all_instances = all_instances.filter(Q(course__name__icontains=query) | Q(course__code__icontains=query))
81+
7882
all_instances = [c for c in all_instances if c not in my_instances]
7983

8084
self.all_instances = all_instances
@@ -97,7 +101,10 @@ class ArchiveView(UserProfileView):
97101

98102
def get_common_objects(self):
99103
super().get_common_objects()
104+
query = self.request.GET.get("search", "").strip()
100105
self.instances = CourseInstance.objects.get_visible(self.request.user)
106+
if query:
107+
self.instances = self.instances.filter(Q(course__name__icontains=query) | Q(course__code__icontains=query))
101108
self.show_language_toggle = True
102109
self.note("instances", "show_language_toggle")
103110

locale/en/LC_MESSAGES/django.po

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -953,13 +953,18 @@ msgstr "Skip course navigation"
953953
msgid "COURSE"
954954
msgstr "Course"
955955

956+
#: course/templates/course/_course_menu.html
957+
msgid "MINIMISE_SIDEBAR"
958+
msgstr "Minimise sidebar"
959+
956960
#: course/templates/course/_course_menu.html
957961
msgid "CHANGE_LANGUAGE"
958962
msgstr "Change language"
959963

960-
#: course/templates/course/_course_menu.html
961-
msgid "MINIMISE_SIDEBAR"
962-
msgstr "Minimise sidebar"
964+
#: course/templates/course/_course_menu.html news/models.py
965+
#: news/templates/news/list.html userprofile/templates/userprofile/profile.html
966+
msgid "LANGUAGE"
967+
msgstr "Language"
963968

964969
#: course/templates/course/_course_menu.html
965970
#: course/templates/course/_siblings.html exercise/templates/exercise/toc.html
@@ -1035,6 +1040,7 @@ msgstr "Edit course"
10351040

10361041
#: course/templates/course/_course_menu.html
10371042
#: deviations/templates/deviations/list_dl.html
1043+
#: exercise/templates/exercise/staff/user_results.html
10381044
msgid "DEADLINE_DEVIATIONS"
10391045
msgstr "Deadline deviations"
10401046

@@ -1129,6 +1135,19 @@ msgstr "Submit alone"
11291135
msgid "SUBMIT_WITH -- %(collaborators)s"
11301136
msgstr "Submit with %(collaborators)s "
11311137

1138+
#: course/templates/course/_search_courses_form.html
1139+
msgid "SEARCH_COURSES"
1140+
msgstr "Search courses"
1141+
1142+
#: course/templates/course/_search_courses_form.html
1143+
msgid "CLEAR_SEARCH"
1144+
msgstr "Clear selection"
1145+
1146+
#: course/templates/course/_search_courses_form.html
1147+
#: templates/ajax_search_select.html
1148+
msgid "SEARCH"
1149+
msgstr "Search"
1150+
11321151
#: course/templates/course/_siblings.html
11331152
msgid "PAGINATION"
11341153
msgstr "Pagination"
@@ -1145,6 +1164,10 @@ msgstr "Early access"
11451164
msgid "COURSE_ARCHIVE"
11461165
msgstr "Course archive"
11471166

1167+
#: course/templates/course/archive.html course/templates/course/index.html
1168+
msgid "NO_COURSES_FOUND"
1169+
msgstr "No courses found."
1170+
11481171
#: course/templates/course/course.html
11491172
msgid "LEFT_OFF_REMINDER"
11501173
msgstr "Continue where you left off"
@@ -1267,10 +1290,6 @@ msgstr "All ongoing courses"
12671290
msgid "SEE_ALL_COURSES"
12681291
msgstr "See all courses"
12691292

1270-
#: course/templates/course/index.html
1271-
msgid "NO_ACTIVE_COURSES"
1272-
msgstr "There are currently no ongoing courses."
1273-
12741293
#: course/templates/course/module.html
12751294
#: exercise/templates/exercise/_user_results.html
12761295
#: lti_tool/templates/lti_tool/lti_module.html
@@ -5656,11 +5675,6 @@ msgstr "Send email to course staff"
56565675
msgid "LABEL_PUBLISH"
56575676
msgstr "publish"
56585677

5659-
#: news/models.py news/templates/news/list.html
5660-
#: userprofile/templates/userprofile/profile.html
5661-
msgid "LANGUAGE"
5662-
msgstr "Language"
5663-
56645678
#: news/models.py
56655679
msgid "LABEL_PIN"
56665680
msgstr "pin"
@@ -5819,10 +5833,6 @@ msgstr ""
58195833
msgid "INTERNAL_SERVER_ERROR_500"
58205834
msgstr "Internal server error"
58215835

5822-
#: templates/ajax_search_select.html
5823-
msgid "SEARCH"
5824-
msgstr "Search"
5825-
58265836
#: templates/ajax_search_select.html
58275837
msgid "IMPORT_LIST"
58285838
msgstr "Import list"

locale/fi/LC_MESSAGES/django.po

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -959,13 +959,18 @@ msgstr "Ohita kurssivalikko"
959959
msgid "COURSE"
960960
msgstr "Kurssi"
961961

962+
#: course/templates/course/_course_menu.html
963+
msgid "MINIMISE_SIDEBAR"
964+
msgstr "Pienennä sivupalkki"
965+
962966
#: course/templates/course/_course_menu.html
963967
msgid "CHANGE_LANGUAGE"
964968
msgstr "Vaihda kieli"
965969

966-
#: course/templates/course/_course_menu.html
967-
msgid "MINIMISE_SIDEBAR"
968-
msgstr "Pienennä sivupalkki"
970+
#: course/templates/course/_course_menu.html news/models.py
971+
#: news/templates/news/list.html userprofile/templates/userprofile/profile.html
972+
msgid "LANGUAGE"
973+
msgstr "Kieli"
969974

970975
#: course/templates/course/_course_menu.html
971976
#: course/templates/course/_siblings.html exercise/templates/exercise/toc.html
@@ -1041,6 +1046,7 @@ msgstr "Muokkaa kurssia"
10411046

10421047
#: course/templates/course/_course_menu.html
10431048
#: deviations/templates/deviations/list_dl.html
1049+
#: exercise/templates/exercise/staff/user_results.html
10441050
msgid "DEADLINE_DEVIATIONS"
10451051
msgstr "Määräaikojen poikkeamat"
10461052

@@ -1136,6 +1142,21 @@ msgstr "Palauta yksin"
11361142
msgid "SUBMIT_WITH -- %(collaborators)s"
11371143
msgstr "Palauta ryhmässä: %(collaborators)s "
11381144

1145+
#: course/templates/course/_search_courses_form.html
1146+
msgid "SEARCH_COURSES"
1147+
msgstr "Hae kursseja"
1148+
1149+
#: course/templates/course/_search_courses_form.html
1150+
#, fuzzy
1151+
#| msgid "CLEAR_SELECTION"
1152+
msgid "CLEAR_SEARCH"
1153+
msgstr "Tyhjennä valinta"
1154+
1155+
#: course/templates/course/_search_courses_form.html
1156+
#: templates/ajax_search_select.html
1157+
msgid "SEARCH"
1158+
msgstr "Hae"
1159+
11391160
#: course/templates/course/_siblings.html
11401161
msgid "PAGINATION"
11411162
msgstr "Sivuilla siirtyminen"
@@ -1152,6 +1173,10 @@ msgstr "Aikainen pääsy"
11521173
msgid "COURSE_ARCHIVE"
11531174
msgstr "Kurssiarkisto"
11541175

1176+
#: course/templates/course/archive.html course/templates/course/index.html
1177+
msgid "NO_COURSES_FOUND"
1178+
msgstr "Kursseja ei löytynyt."
1179+
11551180
#: course/templates/course/course.html
11561181
msgid "LEFT_OFF_REMINDER"
11571182
msgstr ""
@@ -1275,10 +1300,6 @@ msgstr "Meneillään olevat kurssit"
12751300
msgid "SEE_ALL_COURSES"
12761301
msgstr "Näytä kaikki kurssit"
12771302

1278-
#: course/templates/course/index.html
1279-
msgid "NO_ACTIVE_COURSES"
1280-
msgstr "Tällä hetkellä ei ole meneillään olevia kursseja."
1281-
12821303
#: course/templates/course/module.html
12831304
#: exercise/templates/exercise/_user_results.html
12841305
#: lti_tool/templates/lti_tool/lti_module.html
@@ -5675,11 +5696,6 @@ msgstr "Lähetä sähköpostia kurssihenkilökunnalle"
56755696
msgid "LABEL_PUBLISH"
56765697
msgstr "julkaise"
56775698

5678-
#: news/models.py news/templates/news/list.html
5679-
#: userprofile/templates/userprofile/profile.html
5680-
msgid "LANGUAGE"
5681-
msgstr "Kieli"
5682-
56835699
#: news/models.py
56845700
msgid "LABEL_PIN"
56855701
msgstr "kiinnitä listan kärkeen"
@@ -5838,10 +5854,6 @@ msgstr ""
58385854
msgid "INTERNAL_SERVER_ERROR_500"
58395855
msgstr "Palvelimen sisäinen virhe"
58405856

5841-
#: templates/ajax_search_select.html
5842-
msgid "SEARCH"
5843-
msgstr "Hae"
5844-
58455857
#: templates/ajax_search_select.html
58465858
msgid "IMPORT_LIST"
58475859
msgstr "Tuo lista"

0 commit comments

Comments
 (0)