diff --git a/src/pat/modal/modal.js b/src/pat/modal/modal.js
index fc82bb17e..821f58e5e 100644
--- a/src/pat/modal/modal.js
+++ b/src/pat/modal/modal.js
@@ -67,7 +67,7 @@ export default Base.extend({
         inject.init(this.$el, opts);
     },
 
-    _init_div1() {
+    async _init_div1() {
         const $header = $("<div class='header' />");
         if (this.options.closing.indexOf("close-button") !== -1) {
             $(
@@ -101,13 +101,20 @@ export default Base.extend({
         if (document.activeElement) {
             document.activeElement.focus();
         }
-        this._init_handlers();
+
         this.resize();
         this.setPosition();
+
         $("body").addClass("modal-active");
         this.el.dispatchEvent(
             new Event("pat-modal-ready", { bubbles: true, cancelable: true })
         );
+
+        // Wait a bit to let any pattern initializations settle before initializing handlers.
+        await utils.timeout(2);
+        this._init_handlers();
+        const modal_observer = new MutationObserver(this._init_handlers.bind(this));
+        modal_observer.observe(this.el, { childList: true, subtree: true });
     },
 
     _init_handlers() {
@@ -225,9 +232,10 @@ export default Base.extend({
         $("body").removeClass("modal-panel");
     },
 
-    destroy_inject() {
-        const form = this.el.querySelector("form.pat-inject");
-        if (form) {
+    destroy_inject(e) {
+        const button = e.target;
+        const form = button.form;
+        if (form && form.classList.contains("pat-inject")) {
             // if the modal contains a for mwith pat-inject, wait for injection
             // to be finished and then destroy the modal.
             const destroy_handler = () => {
@@ -241,8 +249,7 @@ export default Base.extend({
                 destroy_handler.bind(this)
             );
         } else {
-            // if working without injection, destroy after waiting a tick to let
-            // eventually registered on-submit handlers kick in first.
+            // if working without form injection, just destroy.
             this.destroy();
         }
     },
diff --git a/src/pat/modal/modal.test.js b/src/pat/modal/modal.test.js
index 481032975..ab8bf5ac4 100644
--- a/src/pat/modal/modal.test.js
+++ b/src/pat/modal/modal.test.js
@@ -196,6 +196,7 @@ describe("pat-modal", function () {
             `;
             registry.scan(document.body);
             await utils.timeout(1); // wait a tick for async to settle.
+            await utils.timeout(2); // wait a tick for async to settle.
 
             document.querySelector("button.close-panel[type=submit]").click();
             await utils.timeout(1); // wait a tick for pat-inject to settle.
@@ -206,6 +207,65 @@ describe("pat-modal", function () {
             expect(document.querySelector("#target2").textContent).toBe("there");
         });
 
+        it("Submit form, do injection and close overlay with multiple forms.", async function () {
+            await import("../inject/inject");
+            const registry = (await import("../../core/registry")).default;
+
+            jest.spyOn($, "ajax").mockImplementation(() => deferred);
+            answer(
+                `<html><body><div id="source">hello.</div><div id="source2">there</div></body></html>`
+            );
+
+            document.body.innerHTML = `
+              <div class="pat-modal">
+                <form
+                    class="form1 pat-inject"
+                    action="test.html"
+                    data-pat-inject="source: #source; target: #target">
+                  <button type="submit" class="close-panel">submit</button>
+                </form>
+                <form
+                    class="form2 pat-inject"
+                    action="test.html"
+                    data-pat-inject="source: #source; target: #target">
+                  <button type="submit" class="close-panel">submit</button>
+                </form>
+              </div>
+              <div id="target">
+              </div>
+            `;
+            registry.scan(document.body);
+            await utils.timeout(1); // wait a tick for async to settle.
+            await utils.timeout(2); // wait a tick for async to settle.
+
+            document.querySelector(".form2 button.close-panel[type=submit]").click();
+            await utils.timeout(1); // wait a tick for pat-inject to settle.
+            await utils.timeout(1); // wait a tick for pat-modal destroy to settle.
+
+            expect(document.querySelector(".pat-modal")).toBe(null);
+            expect(document.querySelector("#target").textContent).toBe("hello.");
+        });
+
+        it("Initialize modal also when modal contents change.", async function () {
+            document.body.innerHTML = `
+              <div class="pat-modal">
+              </div>
+            `;
+            const instance = new pattern(document.querySelector(".pat-modal"));
+            const spy_init_handlers = jest.spyOn(instance, "_init_handlers");
+            expect(spy_init_handlers).toHaveBeenCalledTimes(0);
+
+            // first call is invoked after some ticks to allow any other
+            // patterns to modify the dom before the handlers are initialized.
+            await utils.timeout(2); // wait for init to happen.
+            expect(spy_init_handlers).toHaveBeenCalledTimes(1);
+
+            // Provoke a DOM subtree change and the MutationObserver to kick in
+            document.querySelector(".pat-modal").innerHTML = "<div/>";
+            await utils.timeout(1); // wait a tick for async to settle.
+            expect(spy_init_handlers).toHaveBeenCalledTimes(2);
+        });
+
         it("Ensure destroy callback isn't called multiple times.", async function () {
             document.body.innerHTML = `
               <div id="pat-modal" class="pat-modal">
@@ -215,12 +275,13 @@ describe("pat-modal", function () {
 
             const instance = new pattern(document.querySelector(".pat-modal"));
             await utils.timeout(1); // wait a tick for async to settle.
+            await utils.timeout(2); // wait a tick for async to settle.
 
             const spy_destroy = jest.spyOn(instance, "destroy");
 
             // ``destroy`` was already initialized with instantiating the pattern above.
             // Call init again for new instantiation.
-            instance.init($(".pat-modal"));
+            await instance.init($(".pat-modal"));
 
             document.querySelector("#close-modal").click();
             await utils.timeout(1); // wait a tick for pat-modal destroy to settle.
@@ -247,13 +308,14 @@ describe("pat-modal", function () {
             pattern_inject.init($(".pat-inject"));
             const instance = new pattern(document.querySelector(".pat-modal"));
             await utils.timeout(1); // wait a tick for async to settle.
+            await utils.timeout(2); // wait a tick for async to settle.
 
             const spy_destroy = jest.spyOn(instance, "destroy");
             const spy_destroy_inject = jest.spyOn(instance, "destroy_inject");
 
             // ``destroy`` was already initialized with instantiating the pattern above.
             // Call init again for new instantiation.
-            instance.init($(".pat-modal"));
+            await instance.init($(".pat-modal"));
 
             document.querySelector("#close-modal").click();
             await utils.timeout(1); // wait a tick for pat-inject to settle.
@@ -266,6 +328,7 @@ describe("pat-modal", function () {
             pattern_inject.init($(".pat-inject"));
             new pattern(document.querySelector(".pat-modal"));
             await utils.timeout(1); // wait a tick for async to settle.
+            await utils.timeout(2); // wait a tick for async to settle.
             document.querySelector("#close-modal").click();
             await utils.timeout(1); // wait a tick for pat-inject to settle.
             // Previous mocks still active.