diff --git a/aleksis/apps/alsijil/static/js/vue/components/alsijil/PersonalNotes.js b/aleksis/apps/alsijil/static/js/vue/components/alsijil/PersonalNotes.js
index 37ddb5887413ac6bdf71e24ea43bd7d79815dee2..5ace2f9e72bd15d32ac7643190eaeae16a80fc72 100644
--- a/aleksis/apps/alsijil/static/js/vue/components/alsijil/PersonalNotes.js
+++ b/aleksis/apps/alsijil/static/js/vue/components/alsijil/PersonalNotes.js
@@ -27,6 +27,55 @@ export default {
                 return {};
             }
             return this.personalNotes.filter(item => item.student.id === studentID)[0] || {};
+        },
+        savePersonalNote() {
+            if (this.editedPersonID === ID_NO_PERSON) {
+                return
+            }
+
+            // Loop through all personal notes and update the ones that match the editedPersonID
+            this.personalNotes.forEach(item => {
+                if (item.student.id === this.editedPersonID) {
+                    item.tardiness = this.editedTardiness;
+                    item.absent = this.editedAbsent;
+                    item.excused = this.editedExcused;
+                    item.excuse_type = this.editedExcuseType;
+                    item.extra_marks = this.editedExtraMarks;
+                }
+            });
+        },
+        cancelDialog() {
+            this.dialog = false;
+            this.editedPersonID = ID_NO_PERSON;
+        },
+        saveDialog() {
+            this.savePersonalNote();
+            this.dialog = false;
+            this.editedPersonID = ID_NO_PERSON;
+        },
+        personalNoteString(personalNote) {
+            let personalNoteString = "";
+            if (personalNote.tardiness > 0) {
+                personalNoteString += personalNote.tardiness + " min. ";
+            }
+            if (personalNote.absent) {
+                personalNoteString += "abwesend ";
+            }
+            if (personalNote.excused) {
+                personalNoteString += "entschuldigt ";
+            }
+            if (personalNote.excuse_type) {
+                personalNoteString += personalNote.excuse_type.name;
+            }
+            if (personalNote.extra_marks.length > 0) {
+                personalNoteString += " (";
+                personalNote.extra_marks.forEach(item => {
+                    personalNoteString += item.name + ", ";
+                });
+                personalNoteString = personalNoteString.substring(0, personalNoteString.length - 2);
+                personalNoteString += ")";
+            }
+            return personalNoteString;
         }
     },
     props: ["personalNotes", "groups", "excuseTypes", "extraMarks"],
@@ -93,12 +142,52 @@ export default {
         </v-card-title>
         <v-card-text>
           <v-container>
-<!--            FIXME: Sync values with data-->
-            <v-select item-text="full_name" item-value="id" :items="persons"
-            v-model="editedPersonID" @input="updatePersonalNote"></v-select>
-            <v-text-field label="Tardiness" suffix="min" type="number" min="0" v-model="editedTardiness"></v-text-field>
-            <v-checkbox label="Absent" v-model="personalNoteByStudentID(editedPersonID).absent"></v-checkbox>
-            <v-checkbox label="Excused" v-model="editedExcused"></v-checkbox>
+            <v-select
+              item-text="full_name"
+              item-value="id"
+              :items="persons"
+              label="Student"
+              v-model="editedPersonID"
+              @input="updatePersonalNote"
+            ></v-select>
+            <v-text-field
+              label="Tardiness"
+              suffix="min" type="number"
+              min="0"
+              :disabled="editedPersonID === ID_NO_PERSON"
+              v-model="editedTardiness"
+            ></v-text-field>
+            <v-checkbox
+              label="Absent"
+              v-model="editedAbsent"
+              :disabled="editedPersonID === ID_NO_PERSON"
+              @change="editedExcused = false; editedExcuseType = null"
+            ></v-checkbox>
+            <v-checkbox
+              label="Excused"
+              v-model="editedExcused"
+              :disabled="editedPersonID === ID_NO_PERSON || !editedAbsent"
+              @change="editedExcuseType = null"
+            ></v-checkbox>
+            <v-select
+              label="Excuse Type"
+              v-model="editedExcuseType"
+              :items="excuseTypes"
+              item-text="name"
+              item-value="short_name"
+              :disabled="editedPersonID === ID_NO_PERSON || !editedAbsent || !editedExcused"
+            ></v-select>
+            <!-- FIXME: get extra mark itself as value -->
+            <v-select
+              label="Extra Marks"
+              v-model="editedExtraMarks"
+              :items="extraMarks"
+              item-text="name"
+              item-value="valueOf"
+              :disabled="editedPersonID === ID_NO_PERSON"
+              multiple
+              chips
+            ></v-select>
           </v-container>
 <!--          <small>*indicates required field</small>-->
         </v-card-text>
@@ -112,9 +201,9 @@ export default {
             Cancel
           </v-btn>
           <v-btn
-            color="blue darken-1"
-            text
-            @click="dialog = false"
+            color="success"
+            @click="saveDialog"
+            :disabled="editedPersonID === ID_NO_PERSON"
           >
             Save
           </v-btn>