diff --git a/biscuit/apps/chronos/forms.py b/biscuit/apps/chronos/forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..a242f060ae59e8b28bf0e064dc071f2a56f27fbc
--- /dev/null
+++ b/biscuit/apps/chronos/forms.py
@@ -0,0 +1,19 @@
+from django import forms
+from django.db.models import Count
+from django.utils.translation import ugettext_lazy as _
+
+from biscuit.core.models import Person, Group
+
+from .models import Room
+
+
+class SelectForm(forms.Form):
+    group = forms.ModelChoiceField(
+        queryset=Group.objects.annotate(lessons_count=Count('lessons')).filter(lessons_count__gt=0),
+        label=_('Group'), required=False)
+    teacher = forms.ModelChoiceField(
+        queryset=Person.objects.annotate(lessons_count=Count('lessons')).filter(lessons_count__gt=0),
+        label=_('Teacher'), required=False)
+    room = forms.ModelChoiceField(
+        queryset=Room.objects.annotate(lessons_count=Count('lesson_periods')).filter(lessons_count__gt=0),
+        label=_('Room'), required=False)
diff --git a/biscuit/apps/chronos/locale/de_DE/LC_MESSAGES/django.po b/biscuit/apps/chronos/locale/de_DE/LC_MESSAGES/django.po
index e42cc09b5300778ff15cd1f4c11eab73bde1cb81..3f3ecfcc53100bc1c7f672ae8a701bbf2d760126 100644
--- a/biscuit/apps/chronos/locale/de_DE/LC_MESSAGES/django.po
+++ b/biscuit/apps/chronos/locale/de_DE/LC_MESSAGES/django.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-18 21:36+0200\n"
-"PO-Revision-Date: 2019-08-17 13:37+0200\n"
+"POT-Creation-Date: 2019-08-24 13:55+0200\n"
+"PO-Revision-Date: 2019-08-24 13:55+0200\n"
 "Last-Translator: Tom Teichler <tom.teichler@teckids.org>\n"
 "Language-Team: \n"
 "Language: de_DE\n"
@@ -21,6 +21,18 @@ msgstr ""
 msgid "BiscuIT - Chronos (Timetables)"
 msgstr "BiscuIT - Chronos (Stundenpläne)"
 
+#: forms.py:13
+msgid "Group"
+msgstr "Gruppe"
+
+#: forms.py:16
+msgid "Teacher"
+msgstr "Lehrer"
+
+#: forms.py:19
+msgid "Room"
+msgstr "Raum"
+
 #: menus.py:6
 msgid "Timetables"
 msgstr "Stundenpläne"
@@ -29,97 +41,86 @@ msgstr "Stundenpläne"
 msgid "Timetable"
 msgstr "Stundenplan"
 
-#: models.py:8
+#: models.py:15
 msgid "Sunday"
 msgstr "Sonntag"
 
-#: models.py:9
+#: models.py:16
 msgid "Monday"
 msgstr "Montag"
 
-#: models.py:10
+#: models.py:17
 msgid "Tuesday"
 msgstr "Dienstag"
 
-#: models.py:11
+#: models.py:18
 msgid "Wednesday"
 msgstr "Mittwoch"
 
-#: models.py:12
+#: models.py:19
 msgid "Thursday"
 msgstr "Donnerstag"
 
-#: models.py:13
+#: models.py:20
 msgid "Friday"
 msgstr "Freitag"
 
-#: models.py:14
+#: models.py:21
 msgid "Saturday"
 msgstr "Samstag"
 
-#: models.py:18
+#: models.py:25
 msgid "Week day"
 msgstr "Wochentag"
 
-#: models.py:20
+#: models.py:27
 msgid "Number of period"
 msgstr "Nummer der Stunde"
 
-#: models.py:22
+#: models.py:29
 msgid "Time the period starts"
 msgstr "Anfangszeit der Stunde"
 
-#: models.py:23
+#: models.py:30
 msgid "Time the period ends"
 msgstr "Endzeit der Stunde"
 
-#: models.py:42
+#: models.py:49
 msgid "Abbreviation of subject in timetable"
 msgstr "Kürzel des Faches im Stundenplan"
 
-#: models.py:44
+#: models.py:51
 msgid "Long name of subject"
 msgstr "Name des Faches"
 
-#: models.py:46
+#: models.py:53
 msgid "Foreground colour in timetable"
 msgstr "Vordergrundfarbe im Stundenplan"
 
-#: models.py:48
+#: models.py:55
 msgid "Background colour in timetable"
 msgstr "Hintergrundfarbe im Stundenplan"
 
-#: models.py:57
+#: models.py:64
 msgid "Short name, e.g. room number"
 msgstr "Kurzer Name, z.B. Raumnummer"
 
-#: models.py:58
+#: models.py:65
 msgid "Long name"
 msgstr "Langer Name"
 
-#: models.py:73
+#: models.py:81
 msgid "Effective start date of lesson"
 msgstr "Effektives Startdatum des Unterrichts"
 
-#: models.py:75
+#: models.py:83
 msgid "Effective end date of lesson"
 msgstr "Effektives Enddatum des Unterrichts"
 
-#: templates/chronos/tt_week.html:24
+#: models.py:86
+msgid "Week"
+msgstr "Kalenderwoche"
+
+#: templates/chronos/tt_week.html:28
 msgid "Times"
 msgstr "Zeiten"
-
-#: views.py:24
-#, python-format
-msgid "Group: %s"
-msgstr "Gruppen: %s"
-
-#: views.py:29
-#, python-format
-msgid "Teacher: %s"
-msgstr "Lehrer: %s"
-
-#: views.py:34
-#, python-format
-msgid "Room: %s"
-msgstr "Raum: %s"
diff --git a/biscuit/apps/chronos/menus.py b/biscuit/apps/chronos/menus.py
index 2d81f31e4ab8531d607fe60c5bf3201fe9ce61cc..4ac8cff53502f8a79cf776065846e3c76ef3904c 100644
--- a/biscuit/apps/chronos/menus.py
+++ b/biscuit/apps/chronos/menus.py
@@ -6,11 +6,12 @@ MENUS = {
             'name': _('Timetables'),
             'url': '#',
             'root': True,
+            'validators': ['menu_generator.validators.is_authenticated'],
             'submenu': [
                 {
                     'name': _('Timetable'),
                     'url': 'timetable',
-                    'validators': ['menu_generator.validators.is_authenticated', 'menu_generator.validators.is_superuser']
+                    'validators': ['menu_generator.validators.is_authenticated']
                 }
             ]
         }
diff --git a/biscuit/apps/chronos/models.py b/biscuit/apps/chronos/models.py
index 9e116b0ed80f163ebc920e3613ca65307586a555..6da90f9f9d9787c1ae0707f11a06398ff2a2a83c 100644
--- a/biscuit/apps/chronos/models.py
+++ b/biscuit/apps/chronos/models.py
@@ -1,5 +1,5 @@
 from datetime import datetime
-from typing import List, Tuple, Optional
+from typing import Dict, Optional, List, Tuple
 
 from django.core import validators
 from django.db import models
@@ -29,7 +29,7 @@ class TimePeriod(models.Model):
     time_start = models.TimeField(verbose_name=_('Time the period starts'))
     time_end = models.TimeField(verbose_name=_('Time the period ends'))
 
-    def __str__(self): str:
+    def __str__(self) -> str:
         return '%s, %d. period (%s - %s)' % (self.weekday, self.period, self.time_start, self.time_end)
 
     @classmethod
@@ -82,12 +82,26 @@ class Lesson(models.Model):
     date_end = models.DateField(verbose_name=_(
         'Effective end date of lesson'), null=True)
 
+class LessonSubstitution(models.Model):
+    week = models.IntegerField(verbose_name=_('Week'),
+                               default=current_week)
+
+    lesson_period = models.ForeignKey(
+        'LessonPeriod', models.CASCADE, 'substitutions')
+
+    subject = models.ForeignKey(
+        'Subject', on_delete=models.CASCADE,
+        related_name='lesson_substitutions', null=True)
+    teachers = models.ManyToManyField('core.Person',
+                                      related_name='lesson_substitutions')
+    room = models.ForeignKey('Room', models.CASCADE, null=True)
+
 
 class LessonPeriod(models.Model):
     lesson = models.ForeignKey('Lesson', models.CASCADE, related_name='lesson_periods')
     period = models.ForeignKey('TimePeriod', models.CASCADE, related_name='lesson_periods')
 
-    room = models.ForeignKey('Room', models.CASCADE, null=True)
+    room = models.ForeignKey('Room', models.CASCADE, null=True, related_name='lesson_periods')
 
     def get_substitution(self, week: Optional[int] = None) -> LessonSubstitution:
         wanted_week = week or current_week()
@@ -113,18 +127,3 @@ class LessonPeriod(models.Model):
 
     def get_groups(self) -> models.query.QuerySet:
         return self.lesson.groups
-
-
-class LessonSubstitution(models.Model):
-    week = models.IntegerField(verbose_name=_('Kalenderwoche'),
-                               default=current_week)
-
-    lesson_period = models.ForeignKey(
-        'LessonPeriod', models.CASCADE, 'substitutions')
-
-    subject = models.ForeignKey(
-        'Subject', on_delete=models.CASCADE,
-        related_name='lesson_substitutions', null=True)
-    teachers = models.ManyToManyField('core.Person',
-                                      related_name='lesson_substitutions')
-    room = models.ForeignKey('Room', models.CASCADE, null=True)
diff --git a/biscuit/apps/chronos/static/css/chronos/timetable.css b/biscuit/apps/chronos/static/css/chronos/timetable.css
index 6b692ce69e65188b09442c7b11160ecbd93eb088..6d7a5af706b33e4bc81958ada4acd360f759a43c 100644
--- a/biscuit/apps/chronos/static/css/chronos/timetable.css
+++ b/biscuit/apps/chronos/static/css/chronos/timetable.css
@@ -1,3 +1,8 @@
 .chronos-lesson {
     height: 6em;
 }
+
+ul#timetable_select_form li {
+    dispaly: inline;
+
+}
\ No newline at end of file
diff --git a/biscuit/apps/chronos/templates/chronos/tt_week.html b/biscuit/apps/chronos/templates/chronos/tt_week.html
index 7293aa68541b51d414f45df68ae51d15dc86e750..d590d6fed85156901b966027ef771cbe21357f14 100644
--- a/biscuit/apps/chronos/templates/chronos/tt_week.html
+++ b/biscuit/apps/chronos/templates/chronos/tt_week.html
@@ -10,9 +10,13 @@
 {% block page_title %}Timetable{% endblock %}
 
 {% block content %}
- <p>
-  {{ filter_descs }}
- </p>
+ <form method="get">
+  {% csrf_token %}
+  <ul id="timetable_select_form">
+   {{ select_form.as_ul }}
+  </ul>
+  <input type="submit" value="Select" /> 
+ </form>
 
  <div class="row">
   <div class="col-sm px-0">
diff --git a/biscuit/apps/chronos/templatetags/__init__.py b/biscuit/apps/chronos/templatetags/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/biscuit/apps/chronos/templatetags/week_helpers.py b/biscuit/apps/chronos/templatetags/week_helpers.py
new file mode 100644
index 0000000000000000000000000000000000000000..a30af503f4df8a7e56e7970f2b0e3605357e5ef8
--- /dev/null
+++ b/biscuit/apps/chronos/templatetags/week_helpers.py
@@ -0,0 +1,18 @@
+from datetime import date
+
+from django import template
+
+from ..util import week_days
+
+
+register = template.Library()
+
+
+@register.filter
+def week_start(week: int) -> date:
+    return week_days(week)[0]
+
+
+@register.filter
+def week_end(week: int) -> date:
+    return week_days(week)[-1]
diff --git a/biscuit/apps/chronos/util.py b/biscuit/apps/chronos/util.py
index 4fdff2de99f33da620743bfb7153908844209453..d315859e8eb0af9835142d3f272e9c9913f1c055 100644
--- a/biscuit/apps/chronos/util.py
+++ b/biscuit/apps/chronos/util.py
@@ -1,18 +1,30 @@
-from datetime import datetime
-from typing import Optional
+from datetime import date, datetime, timedelta
+from typing import Optional, Sequence
 
+from django.apps import apps
 from django.db import models
 
-from .models import LessonPeriod
-
 
 def current_week() -> int:
     return int(datetime.now().strftime('%V'))
 
 
+def week_days(week: Optional[int]) -> Sequence[date]:
+    # FIXME Make this aware of the school term concept
+    # cf. BiscuIT-ng#40
+
+    year = date.today().year
+    wanted_week = week or current_week()
+
+    first_day = datetime.strptime('%d-%d-1' % (year, wanted_week), '%Y-%W-%w')
+
+    return [(first_day + timedelta(days=offset)).date() for offset in range(0, 7)]
+
+
 def current_lesson_periods(when: Optional[datetime] = None) -> models.query.QuerySet:
     now = when or datetime.now()
 
+    LessonPeriod = apps.get_model('chronos.LessonPeriod')
     return LessonPeriod.objects.filter(lesson__date_start__lte=now.date(),
                                        lesson__date_end__gte=now.date(),
                                        period__weekday=now.isoweekday(),
diff --git a/biscuit/apps/chronos/views.py b/biscuit/apps/chronos/views.py
index 9659dd63b078cb689e6e253a11217bcf06fcf96d..babc471ebb49163e82e496aeaaf967da4201356e 100644
--- a/biscuit/apps/chronos/views.py
+++ b/biscuit/apps/chronos/views.py
@@ -1,6 +1,7 @@
 from collections import OrderedDict
 
 from django.contrib.auth.decorators import login_required
+from django.db.models import Max, Min
 from django.http import HttpRequest, HttpResponse
 from django.shortcuts import redirect, render
 from django.urls import reverse
@@ -9,6 +10,7 @@ from django.utils.translation import ugettext as _
 from biscuit.core.decorators import admin_required
 from biscuit.core.models import Group, Person
 
+from .forms import SelectForm
 from .models import LessonPeriod, TimePeriod, Room
 from .util import current_week
 
@@ -19,51 +21,47 @@ def timetable(request: HttpRequest) -> HttpResponse:
     context = {}
 
     lesson_periods = LessonPeriod.objects.all()
-    filter_descs = []
 
-    if 'group' in request.GET:
-        lesson_periods = lesson_periods.filter(
-            lesson__groups__pk=int(request.GET['group']))
-        filter_descs.append(_('Group: %s') % Group.objects.get(
-            pk=int(request.GET['group'])))
-    elif 'teacher' in request.GET:
-        lesson_periods = lesson_periods.filter(
-            lesson__teachers__pk=int(request.GET['teacher']))
-        filter_descs.append(_('Teacher: %s') % Person.objects.get(
-            pk=int(request.GET['teacher'])))
-    elif 'room' in request.GET:
-        lesson_periods = lesson_periods.filter(
-            room__pk=int(request.GET['room']))
-        filter_descs.append(_('Room: %s') % Room.objects.get(
-            pk=int(request.GET['room'])))
+    if request.GET.get('group', None) or request.GET.get('teacher', None) or request.GET.get('room', None):
+        # Incrementally filter lesson periods by GET parameters
+        if 'group' in request.GET and request.GET['group']:
+            lesson_periods = lesson_periods.filter(
+                lesson__groups__pk=int(request.GET['group']))
+        if 'teacher' in request.GET and request.GET['teacher']:
+            lesson_periods = lesson_periods.filter(
+                lesson__teachers__pk=int(request.GET['teacher']))
+        if 'room' in request.GET and request.GET['room']:
+            lesson_periods = lesson_periods.filter(
+                room__pk=int(request.GET['room']))
     else:
+        # Redirect to a selected view if no filter provided
         if request.user.person:
             if request.user.person.primary_group:
                 return redirect(reverse('timetable') + '?group=%d' % request.user.person.primary_group.pk)
             elif lesson_periods.filter(lesson__teachers=request.user.person).exists():
                 return redirect(reverse('timetable') + '?teacher=%d' % request.user.person.pk)
 
+    # Regroup lesson periods per weekday
     per_day = {}
-    period_min, period_max = None, None
     for lesson_period in lesson_periods:
         per_day.setdefault(lesson_period.period.weekday,
                            {})[lesson_period.period.period] = lesson_period
 
-        # Expand min and max lesson to later fill in empty lessons
-        if period_min is None or period_min > lesson_period.period.period:
-            period_min = lesson_period.period.period
-        if period_max is None or period_max < lesson_period.period.period:
-            period_max = lesson_period.period.period
+    # Determine overall first and last day and period
+    min_max = TimePeriod.objects.aggregate(
+        Min('period'), Max('period'),
+        Min('weekday'), Max('weekday'))
 
     # Fill in empty lessons
-    for weekday_num in range(min(per_day.keys() or [0]),
-                             max(per_day.keys() or [6]) + 1):
+    for weekday_num in range(min_max.get('weekday__min', 0),
+                             min_max.get('weekday__max', 6) + 1):
         # Fill in empty weekdays
         if weekday_num not in per_day.keys():
             per_day[weekday_num] = {}
 
         # Fill in empty lessons on this workday
-        for period_num in range(period_min, period_max + 1):
+        for period_num in range(min_max.get('period__min', 1),
+                                min_max.get('period__max', 7) + 1):
             if period_num not in per_day[weekday_num].keys():
                 per_day[weekday_num][period_num] = None
 
@@ -71,10 +69,13 @@ def timetable(request: HttpRequest) -> HttpResponse:
         per_day[weekday_num] = OrderedDict(
             sorted(per_day[weekday_num].items()))
 
+    # Add a form to filter the view
+    select_form = SelectForm(request.GET or None)
+
     context['lesson_periods'] = OrderedDict(sorted(per_day.items()))
-    context['filter_descs'] = ', '.join(filter_descs)
     context['periods'] = TimePeriod.get_times_dict()
     context['weekdays'] = dict(TimePeriod.WEEKDAY_CHOICES)
     context['current_week'] = current_week()
+    context['select_form'] = select_form
 
     return render(request, 'chronos/tt_week.html', context)