diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue
index 87d9f429075cad7a46a80dd55a82e3d01ea642c2..c2b765cfdf368764771b6ea7ff71a7bef3e8b5c2 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/Coursebook.vue
@@ -69,7 +69,10 @@
         <DocumentationLoader />
       </template>
     </infinite-scrolling-date-sorted-c-r-u-d-iterator>
-    <absence-creation-dialog :absence-reasons="absenceReasons" />
+    <absence-creation-dialog
+      :absence-reasons="absenceReasons"
+      :affected-query="lastQuery"
+    />
   </div>
 </template>
 
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
index 690b07972cd932a8d5eb0fd91609e0a662d829b0..e62c2ca4a22a314744a72a9feec45e439b9a1379 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
@@ -96,7 +96,10 @@ import permissionsMixin from "aleksis.core/mixins/permissions.js";
 import mutateMixin from "aleksis.core/mixins/mutateMixin.js";
 import { DateTime } from "luxon";
 
-import { createAbsencesForPersons } from "./absenceCreation.graphql";
+import {
+  clearAbsencesForPersons,
+  createAbsencesForPersons,
+} from "./absenceCreation.graphql";
 
 export default {
   name: "AbsenceCreationDialog",
@@ -152,13 +155,17 @@ export default {
     confirm() {
       this.handleLoading(true);
       this.mutate(
-        createAbsencesForPersons,
+        this.absenceReason !== "present"
+          ? createAbsencesForPersons
+          : clearAbsencesForPersons,
         {
           persons: this.persons.map((p) => p.id),
           start: this.$toUTCISO(this.$parseISODate(this.startDate)),
           end: this.$toUTCISO(this.$parseISODate(this.endDate)),
-          comment: this.comment,
-          reason: this.absenceReason,
+          ...(this.absenceReason !== "present" && { comment: this.comment }),
+          ...(this.absenceReason !== "present" && {
+            reason: this.absenceReason,
+          }),
         },
         (storedDocumentations, incomingStatuses) => {
           incomingStatuses.forEach((newStatus) => {
@@ -172,7 +179,7 @@ export default {
               (part) => part.id === newStatus.id,
             );
 
-            participationStatus.absenceReason = newStatus.absenceReason;
+            participationStatus.absenceReason = newStatus?.absenceReason;
             participationStatus.isOptimistic = newStatus.isOptimistic;
           });
 
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue
index 902a33f2582cc30a76d8145e619da432d0092a4c..1d392d83b7cdea91df0f037712a653b89f5f824b 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue
@@ -55,6 +55,7 @@
         <v-text-field
           :label="$t('forms.labels.comment')"
           :value="comment"
+          :disabled="absenceReason == 'present'"
           @input="$emit('comment', $event)"
         />
       </v-row>
@@ -62,6 +63,7 @@
         <div aria-required="true">
           <absence-reason-group-select
             :rules="$rules().required.build()"
+            allow-empty
             :value="absenceReason"
             :custom-absence-reasons="absenceReasons"
             @input="$emit('absence-reason', $event)"
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql
index 5a520453f35062d49edd5eb82aca291384e2f739..f7f6de02e930ee81e2f9bd6c54cbd354e319de3b 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/absenceCreation.graphql
@@ -59,3 +59,23 @@ mutation createAbsencesForPersons(
     }
   }
 }
+
+mutation clearAbsencesForPersons(
+  $persons: [ID]!
+  $start: DateTime!
+  $end: DateTime!
+) {
+  clearAbsencesForPersons(persons: $persons, start: $start, end: $end) {
+    ok
+    items: participationStatuses {
+      id
+      isOptimistic
+      relatedDocumentation {
+        id
+      }
+      absenceReason {
+        id
+      }
+    }
+  }
+}
diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py
index 2dd3deac4fbc03f3e85b4d791170f09eaf5054e3..6e8465376fad8816f65ab28204d60e367a97221b 100644
--- a/aleksis/apps/alsijil/models.py
+++ b/aleksis/apps/alsijil/models.py
@@ -498,6 +498,29 @@ class ParticipationStatus(CalendarEvent):
 
         return participation_statuses
 
+    @classmethod
+    def clear_absence_by_datetimes(
+        cls, person: Person, start: datetime, end: datetime
+    ) -> list["ParticipationStatus"]:
+        participation_statuses = []
+
+        events = cls.get_single_events(
+            start,
+            end,
+            None,
+            {"person": person},
+            with_reference_object=True,
+        )
+
+        for event in events:
+            participation_status = event["REFERENCE_OBJECT"]
+            participation_status.absence_reason = None
+            participation_status.base_absence = None
+            participation_status.save()
+            participation_statuses.append(participation_status)
+
+        return participation_statuses
+
     def fill_from_kolego(self, kolego_absence: KolegoAbsence):
         """Take over data from a Kolego absence."""
         self.base_absence = kolego_absence
diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py
index 284d8da2d3a2570e57ae902b14302048eba7f3b8..f337be4f836c8f73383e952c88f79e229613e02a 100644
--- a/aleksis/apps/alsijil/schema/__init__.py
+++ b/aleksis/apps/alsijil/schema/__init__.py
@@ -24,6 +24,7 @@ from aleksis.core.util.core_helpers import (
 from ..model_extensions import annotate_person_statistics_for_school_term
 from ..models import Documentation, ExtraMark, NewPersonalNote, ParticipationStatus
 from .absences import (
+    AbsencesForPersonsClearMutation,
     AbsencesForPersonsCreateMutation,
 )
 from .documentation import (
@@ -352,6 +353,7 @@ class Mutation(graphene.ObjectType):
     touch_documentation = TouchDocumentationMutation.Field()
     update_participation_statuses = ParticipationStatusBatchPatchMutation.Field()
     create_absences_for_persons = AbsencesForPersonsCreateMutation.Field()
+    clear_absences_for_persons = AbsencesForPersonsClearMutation.Field()
     extend_participation_statuses = ExtendParticipationStatusToAbsenceBatchMutation.Field()
 
     create_extra_marks = ExtraMarkBatchCreateMutation.Field()
diff --git a/aleksis/apps/alsijil/schema/absences.py b/aleksis/apps/alsijil/schema/absences.py
index eea8b075b3e1ba2a0e6011e4b7e33e6df4f09ed4..8a729f0a4ae10624c9522fb27a8a4166af78b40a 100644
--- a/aleksis/apps/alsijil/schema/absences.py
+++ b/aleksis/apps/alsijil/schema/absences.py
@@ -56,3 +56,44 @@ class AbsencesForPersonsCreateMutation(graphene.Mutation):
         return AbsencesForPersonsCreateMutation(
             ok=True, participation_statuses=participation_statuses
         )
+
+
+class AbsencesForPersonsClearMutation(graphene.Mutation):
+    class Arguments:
+        persons = graphene.List(graphene.ID, required=True)
+        start = graphene.DateTime(required=True)
+        end = graphene.DateTime(required=True)
+
+    ok = graphene.Boolean()
+    participation_statuses = graphene.List(ParticipationStatusType)
+
+    @classmethod
+    def mutate(
+        cls,
+        root,
+        info,
+        persons: list[str | int],
+        start: datetime.datetime,
+        end: datetime.datetime,
+    ):
+        participation_statuses = []
+
+        persons = Person.objects.filter(pk__in=persons)
+
+        for person in persons:
+            if not info.context.user.has_perm("alsijil.register_absence_rule", person):
+                raise PermissionDenied()
+
+            participation_statuses += ParticipationStatus.clear_absence_by_datetimes(
+                person=person, start=start, end=end
+            )
+
+            Absence.clear_or_extend_absences_in_timespan(
+                person=person,
+                datetime_start=start,
+                datetime_end=end,
+            )
+
+        return AbsencesForPersonsClearMutation(
+            ok=True, participation_statuses=participation_statuses
+        )