diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
index dbb504c393b0dc03f43b647ca305f614fd7df1da..d203ad680dcae02fda4fc736e2099845c8f5ce3b 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
@@ -1,5 +1,5 @@
 <template>
-  <mobile-fullscreen-dialog v-model="popup" persistent>
+  <mobile-fullscreen-dialog v-model="popup" persistent :close-button="false">
     <template #activator="activator">
       <fab-button
         color="secondary"
@@ -167,7 +167,7 @@ export default {
     },
     handleSave() {
       this.cancel();
-      this.$toastSuccess("alsijil.coursebook.absences.success");
+      this.$toastSuccess(this.$t("alsijil.coursebook.absences.success"));
     },
   },
 };
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue
index 02dda22073e775b30324db22ea358ff7e9924ba4..aa9176a8bbf4e3bb61c6641580e1eb5c5b96f980 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/ManageStudentsDialog.vue
@@ -2,7 +2,7 @@
 import AbsenceReasonButtons from "aleksis.apps.kolego/components/AbsenceReasonButtons.vue";
 import AbsenceReasonChip from "aleksis.apps.kolego/components/AbsenceReasonChip.vue";
 import AbsenceReasonGroupSelect from "aleksis.apps.kolego/components/AbsenceReasonGroupSelect.vue";
-import CancelButton from "aleksis.core/components/generic/buttons/CancelButton.vue";
+import DialogCloseButton from "aleksis.core/components/generic/buttons/DialogCloseButton.vue";
 import MobileFullscreenDialog from "aleksis.core/components/generic/dialogs/MobileFullscreenDialog.vue";
 import updateParticipationMixin from "./updateParticipationMixin.js";
 import deepSearchMixin from "aleksis.core/mixins/deepSearchMixin.js";
@@ -23,11 +23,11 @@ export default {
     AbsenceReasonGroupSelect,
     AbsenceReasonButtons,
     PersonalNotes,
-    CancelButton,
     LessonInformation,
     MobileFullscreenDialog,
     SlideIterator,
     TardinessField,
+    DialogCloseButton,
   },
   mixins: [updateParticipationMixin, deepSearchMixin],
   data() {
@@ -77,13 +77,17 @@ export default {
     v-bind="$attrs"
     v-on="$listeners"
     v-model="dialog"
+    :close-button="false"
   >
     <template #activator="activator">
       <slot name="activator" v-bind="activator" />
     </template>
 
     <template #title>
-      <lesson-information v-bind="documentationPartProps" :compact="false" />
+      <div class="d-flex full-width">
+        <lesson-information v-bind="documentationPartProps" :compact="false" />
+        <dialog-close-button @click="dialog = false" class="ml-4" />
+      </div>
       <v-scroll-x-transition leave-absolute>
         <v-text-field
           v-show="!isExpanded"
@@ -100,15 +104,6 @@ export default {
           class="pt-4 full-width"
         />
       </v-scroll-x-transition>
-      <v-scroll-x-transition>
-        <div v-show="selected.length > 0" class="full-width mt-4">
-          <absence-reason-buttons
-            allow-empty
-            empty-value="present"
-            @input="handleMultipleAction"
-          />
-        </div>
-      </v-scroll-x-transition>
     </template>
     <template #content>
       <slide-iterator
@@ -212,11 +207,15 @@ export default {
     </template>
 
     <template #actions>
-      <cancel-button
-        @click="dialog = false"
-        i18n-key="actions.close"
-        v-show="$vuetify.breakpoint.mobile"
-      />
+      <v-scroll-y-reverse-transition>
+        <div v-show="selected.length > 0" class="full-width">
+          <absence-reason-buttons
+            allow-empty
+            empty-value="present"
+            @input="handleMultipleAction"
+          />
+        </div>
+      </v-scroll-y-reverse-transition>
     </template>
   </mobile-fullscreen-dialog>
 </template>
diff --git a/aleksis/apps/alsijil/preferences.py b/aleksis/apps/alsijil/preferences.py
index b00d9277e507e284130340b84cbbca8c07597d1f..c47546e235ce26da6fef88fee0a2e0324d9df75f 100644
--- a/aleksis/apps/alsijil/preferences.py
+++ b/aleksis/apps/alsijil/preferences.py
@@ -2,8 +2,14 @@ from django.core.exceptions import ValidationError
 from django.utils.translation import gettext_lazy as _
 
 from dynamic_preferences.preferences import Section
-from dynamic_preferences.types import BooleanPreference, ChoicePreference, IntegerPreference
-
+from dynamic_preferences.types import (
+    BooleanPreference,
+    ChoicePreference,
+    IntegerPreference,
+    ModelMultipleChoicePreference,
+)
+
+from aleksis.core.models import GroupType
 from aleksis.core.registries import person_preferences_registry, site_preferences_registry
 
 alsijil = Section("alsijil", verbose_name=_("Class register"))
@@ -181,3 +187,19 @@ class AllowEditFutureDocumentations(ChoicePreference):
         ),
     )
     verbose_name = _("Set time range for which documentations may be edited")
+
+
+@site_preferences_registry.register
+class GroupTypesRegisterAbsence(ModelMultipleChoicePreference):
+    section = alsijil
+    name = "group_types_register_absence"
+    required = False
+    default = []
+    model = GroupType
+    verbose_name = _(
+        "User is allowed to register absences for members "
+        "of groups the user is an owner of with these group types"
+    )
+    help_text = _(
+        "If you leave it empty, all member of groups the user is an owner of will be shown."
+    )
diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py
index c1ffafbe856ffa64c91a17e3eaf062942debbe40..8b8e15e7b0250c76651144190ea4153b4e5717df 100644
--- a/aleksis/apps/alsijil/rules.py
+++ b/aleksis/apps/alsijil/rules.py
@@ -14,6 +14,8 @@ from .util.predicates import (
     can_edit_documentation,
     can_edit_participation_status,
     can_edit_personal_note,
+    can_register_absence_for_at_least_one_group,
+    can_register_absence_for_person,
     can_view_any_documentation,
     can_view_documentation,
     can_view_participation_status,
@@ -171,12 +173,12 @@ add_perm("alsijil.view_week_personalnote_rule", view_week_personal_notes_predica
 
 # Register absence
 view_register_absence_predicate = has_person & (
-    is_person_group_owner | has_global_perm("alsijil.register_absence")
+    can_register_absence_for_at_least_one_group | has_global_perm("alsijil.register_absence")
 )
 add_perm("alsijil.view_register_absence_rule", view_register_absence_predicate)
 
 register_absence_predicate = has_person & (
-    is_group_owner
+    can_register_absence_for_person
     | has_global_perm("alsijil.register_absence")
     | has_object_perm("core.register_absence_person")
     | has_person_group_object_perm("core.register_absence_group")
diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py
index 35c0201f92bcf66b46f8e25583ea36522c7775af..49bfbe7abb2b04515c30ccd931c4d9d847578caf 100644
--- a/aleksis/apps/alsijil/schema/__init__.py
+++ b/aleksis/apps/alsijil/schema/__init__.py
@@ -12,7 +12,7 @@ from aleksis.core.models import Group, Person
 from aleksis.core.schema.base import FilterOrderList
 from aleksis.core.schema.group import GroupType
 from aleksis.core.schema.person import PersonType
-from aleksis.core.util.core_helpers import has_person
+from aleksis.core.util.core_helpers import get_site_preferences, has_person
 
 from ..models import Documentation
 from .absences import (
@@ -177,7 +177,15 @@ class Query(graphene.ObjectType):
     @staticmethod
     def resolve_absence_creation_persons(root, info, **kwargs):
         if not info.context.user.has_perm("alsijil.register_absence"):
-            return Person.objects.filter(member_of__owners=info.context.user.person)
+            group_types = get_site_preferences()["alsijil__group_types_register_absence"]
+            if group_types:
+                return Person.objects.filter(
+                    member_of__in=Group.objects.filter(
+                        owners=info.context.user.person, group_type__in=group_types
+                    )
+                )
+            else:
+                return Person.objects.filter(member_of__owners=info.context.user.person)
         return Person.objects.all()
 
     @staticmethod
diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py
index e1d8f8a02760b846d35672ffddeeb73d161ece72..5966a7459bc8a32f7e7468f20de2e7da0044441e 100644
--- a/aleksis/apps/alsijil/util/predicates.py
+++ b/aleksis/apps/alsijil/util/predicates.py
@@ -103,6 +103,26 @@ def is_person_group_owner(user: User, obj) -> bool:
     return Group.objects.filter(owners=user.person).exists()
 
 
+@predicate
+def can_register_absence_for_at_least_one_group(user: User, obj) -> bool:
+    """Predicate for registering absence for at least one group."""
+    group_types = get_site_preferences()["alsijil__group_types_register_absence"]
+    qs = Group.objects.filter(owners=user.person)
+    if not group_types:
+        return qs.exists()
+    return qs.filter(group_type__in=group_types).exists()
+
+
+@predicate
+def can_register_absence_for_person(user: User, obj: Person) -> bool:
+    """Predicate for registering absence for person."""
+    group_types = get_site_preferences()["alsijil__group_types_register_absence"]
+    qs = obj.member_of.filter(owners=user.person)
+    if not group_types:
+        return qs.exists()
+    return qs.filter(group_type__in=group_types).exists()
+
+
 def use_prefetched(obj, attr):
     prefetched_attr = f"{attr}_prefetched"
     if hasattr(obj, prefetched_attr):