diff --git a/resources/assets/javascripts/lib/dialog.js b/resources/assets/javascripts/lib/dialog.js
index dff05b9b9a1b28448d5ee7972414bed59dbd3df6..048714ff218292ec62afe956e2a864e316890677 100644
--- a/resources/assets/javascripts/lib/dialog.js
+++ b/resources/assets/javascripts/lib/dialog.js
@@ -21,31 +21,40 @@ var dialog_margin = 0;
 
 /**
  * Extract buttons from given element.
+ *
+ * @param {Element} element
+ * @param {function|null} callback
  */
-function extractButtons(element) {
-    var buttons = {};
+function extractButtons(element, callback = null) {
+    const buttons = [];
     $('[data-dialog-button]', element)
         .hide()
         .find('a,button')
         .addBack()
         .filter('a,button')
         .each(function() {
-            var label = $(this).text();
-            var cancel = $(this).is('.cancel');
-            var index = cancel ? 'cancel' : label;
-            var classes = $(this).attr('class') || '';
-            var name = $(this).attr('name') || '';
-            var disabled = $(this).is(':disabled');
+            const id = $(this).uniqueId().attr('id');
+            const label = $(this).text();
+            const cancel = $(this).is('.cancel');
+            const index = cancel ? 'cancel' : label;
+            let classes = $(this).attr('class') || '';
+            const name = $(this).attr('name') || '';
+            const disabled = $(this).is(':disabled');
 
             classes = classes.replace(/\bbutton\b/, '').trim();
 
-            buttons[index] = {
+            buttons.push({
+                id: id,
                 text: label,
                 class: classes,
                 name: name,
                 disabled: disabled,
                 click: () => this.click()
-            };
+            });
+
+            if (callback !== null) {
+                callback(this, index);
+            }
         });
 
     return buttons;
@@ -403,13 +412,6 @@ Dialog.show = function(content, options = {}) {
             $('head').append(scripts);
 
             $(options.origin || document).trigger('dialog-open', { dialog: this, options: options });
-
-            // Transfer defined classes from options to actual displayed buttons
-            // This should work natively, but it kinda does not
-            Object.keys(dialog_options.buttons).forEach(function(label, index) {
-                var classes = dialog_options.buttons[label]['class'];
-                $(buttons.get(index)).addClass(classes);
-            });
         },
         close: function(event) {
             $(options.origin || document).trigger('dialog-close', { dialog: this, options: options });
@@ -425,17 +427,41 @@ Dialog.show = function(content, options = {}) {
         options.buttons === undefined
         || (options.buttons && !$.isPlainObject(options.buttons))
     ) {
-        dialog_options.buttons = extractButtons.call(this, instance.element);
+        // Create observer to detect changes on disabled attribute
+        const observer = new MutationObserver((mutations) => {
+            mutations.forEach(mutation => {
+                const id = mutation.target.id;
+                const buttonIndex = dialog_options.buttons.findIndex(button => button.id === id);
+
+                if (mutation.attributeName === 'disabled') {
+                    dialog_options.buttons[buttonIndex].disabled = mutation.target.disabled;
+                } else if (mutation.attributeName === 'class') {
+                    const classes = mutation.target.classList.toString();
+                    dialog_options.buttons[buttonIndex].class = classes.replace(/\bbutton\b/, '');
+                }
+
+                instance.element.dialog('option', 'buttons', dialog_options.buttons);
+            });
+        });
+
+        dialog_options.buttons = extractButtons(instance.element, (button) => {
+            observer.observe(button, {
+                attributes: true,
+                attributeFilter: ['class', 'disabled'],
+            });
+        });
+
         // Create 'close' button
-        if (dialog_options.buttons.cancel === undefined) {
-            dialog_options.buttons.cancel = {
+        const cancelButton = dialog_options.buttons.find(button => button.class.split(' ').includes('cancel'));
+        if (!cancelButton) {
+            dialog_options.buttons.push({
                 text: $gettext('Schließen'),
-                'class': 'cancel'
-            };
+                class: 'cancel',
+                click: () => Dialog.close(options),
+            });
+        } else {
+            cancelButton.click = () => Dialog.close(options);
         }
-        dialog_options.buttons.cancel.click = function() {
-            Dialog.close(options);
-        };
     }
 
     // Create/update dialog