diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
index d1b848c4f8faff1cd7ebef43304dd2496aeaa4de..88672264aea7a128930d4b912e55b5aab2dd0a11 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationDialog.vue
@@ -31,6 +31,7 @@
       :end-date="endDate"
       :comment="comment"
       :absence-reason="absenceReason"
+      @valid="formValid = $event"
       @persons="persons = $event"
       @start-date="startDate = $event"
       @end-date="endDate = $event"
@@ -56,6 +57,7 @@
         i18n-key="actions.continue"
         @click="form = false"
         :loading="loading"
+        :disabled="!formValid"
       />
       <save-button
         v-else
@@ -92,6 +94,7 @@ export default {
     return {
       popup: false,
       form: true,
+      formValid: false,
       persons: [],
       startDate: "",
       endDate: "",
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue
index 23c6db202bf87a5731b4f7809f5d94e58802343c..f8b20a0baac0a004f01228b52f9a401cd551e4d1 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/AbsenceCreationForm.vue
@@ -1,56 +1,70 @@
 <template>
-  <v-container>
-    <v-row>
-      <v-autocomplete
-        :label="$t('forms.labels.persons')"
-        :items="allPersons"
-        item-text="fullName"
-        return-object
-        multiple
-        :value="persons"
-        @input="$emit('persons', $event)"
-      />
-    </v-row>
-    <v-row>
-      <v-col
-        cols="12"
-        :sm="6"
-        class="pl-0"
-        >
-        <date-field
-          :label="$t('forms.labels.start')"
-          :max="endDate"
-          :value="startDate"
-          @input="$emit('start-date', $event)"
+  <v-form @input="$emit('valid', $event)">
+    <v-container>
+      <v-row>
+        <div aria-required="true" class="full-width">
+          <v-autocomplete
+            :label="$t('forms.labels.persons')"
+            :items="allPersons"
+            item-text="fullName"
+            return-object
+            multiple
+            :rules="rules"
+            :value="persons"
+            @input="$emit('persons', $event)"
           />
-      </v-col>
-      <v-col
-        cols="12"
-        :sm="6"
-        class="pr-0"
-        >
-        <date-field
-          :label="$t('forms.labels.end')"
-          :min="startDate"
-          :value="endDate"
-          @input="$emit('end-date', $event)"
+        </div>
+      </v-row>
+      <v-row>
+        <v-col
+          cols="12"
+          :sm="6"
+          class="pl-0"
+          >
+          <div aria-required="true">
+            <date-field
+              :label="$t('forms.labels.start')"
+              :max="endDate"
+              :rules="rules"
+              :value="startDate"
+              @input="$emit('start-date', $event)"
+            />
+          </div>
+        </v-col>
+        <v-col
+          cols="12"
+          :sm="6"
+          class="pr-0"
+          >
+          <div aria-required="true">
+            <date-field
+              :label="$t('forms.labels.end')"
+              :min="startDate"
+              :rules="rules"
+              :value="endDate"
+              @input="$emit('end-date', $event)"
+            />
+          </div>
+        </v-col>
+      </v-row>
+      <v-row>
+        <v-text-field
+          :label="$t('forms.labels.comment')"
+          :value="comment"
+          @input="$emit('comment', $event)"
+        />
+      </v-row>
+      <v-row>
+        <div aria-required="true">
+          <absence-reason-group-select
+            :rules="rules"
+            :value="absenceReason"
+            @input="$emit('absence-reason', $event)"
           />
-      </v-col>
-    </v-row>
-    <v-row>
-      <v-text-field
-        :label="$t('forms.labels.comment')"
-        :value="comment"
-        @input="$emit('comment', $event)"
-      />
-    </v-row>
-    <v-row>
-      <absence-reason-group-select
-        :value="absenceReason"
-        @input="$emit('absence-reason', $event)"
-      />
-    </v-row>
-  </v-container>
+        </div>
+      </v-row>
+    </v-container>
+  </v-form>
 </template>
 
 <script>
@@ -64,7 +78,7 @@ export default {
     AbsenceReasonGroupSelect,
     DateField,
   },
-  emits: ["persons", "start-date", "end-date", "comment", "absence-reason"],
+  emits: ["valid", "persons", "start-date", "end-date", "comment", "absence-reason"],
   apollo: {
     // TODO: Query currently returns all persons. But should return
     // only persons the current user can create ParticipationStati and
@@ -93,5 +107,12 @@ export default {
       required: true,
     },
   },
+  data() {
+    return {
+      rules: [
+          (value) => value.length > 0,
+      ],
+    };
+  },
 };
 </script>