From bdcb040a2f6c8bcf2fa6580c9dd7772b743d442a Mon Sep 17 00:00:00 2001 From: Eric Kwoka <43540491+ekwoka@users.noreply.github.com> Date: Wed, 1 Nov 2023 02:32:58 +0400 Subject: [PATCH] Fix stale form references (#1820) * :bug: ensures form reference is accurate * :white_check_mark: Adds test * :bug: Fixes null checks * Revert www updates This reverts commit d2d14056e2635688fdcb0e6abe572034f77c0bef. * Revert www updates This reverts commit 3de585e02997a7877f47ef84f6c2f1a5fcc91ac3. * :recycle: Refactors code * :white_check_mark: Passes tests --- src/htmx.js | 47 +++++++++++++++++++++++++++-------------------- test/core/ajax.js | 27 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/htmx.js b/src/htmx.js index d8c1fa82..562db6c5 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -1912,32 +1912,39 @@ return (function () { } } - function initButtonTracking(elt) { - // Handle submit buttons/inputs that have the form attribute set - // see https://developer.mozilla.org/docs/Web/HTML/Element/button - var form = resolveTarget("#" + getRawAttribute(elt, "form")) || closest(elt, "form") - if (!form) { - return + // Handle submit buttons/inputs that have the form attribute set + // see https://developer.mozilla.org/docs/Web/HTML/Element/button + function maybeSetLastButtonClicked(evt) { + var elt = closest(evt.target, "button, input[type='submit']"); + var internalData = getRelatedFormData(evt) + if (internalData) { + internalData.lastButtonClicked = elt; } - - var maybeSetLastButtonClicked = function (evt) { - var elt = closest(evt.target, "button, input[type='submit']"); - if (elt !== null) { - var internalData = getInternalData(form); - internalData.lastButtonClicked = elt; - } - }; - + }; + function maybeUnsetLastButtonClicked(evt){ + var internalData = getRelatedFormData(evt) + if (internalData) { + internalData.lastButtonClicked = null; + } + } + function getRelatedFormData(evt) { + var elt = closest(evt.target, "button, input[type='submit']"); + if (!elt) { + return; + } + var form = resolveTarget('#' + getRawAttribute(elt, 'form')) || closest(elt, 'form'); + if (!form) { + return; + } + return getInternalData(form); + } + function initButtonTracking(elt) { // need to handle both click and focus in: // focusin - in case someone tabs in to a button and hits the space bar // click - on OSX buttons do not focus on click see https://bugs.webkit.org/show_bug.cgi?id=13724 - elt.addEventListener('click', maybeSetLastButtonClicked) elt.addEventListener('focusin', maybeSetLastButtonClicked) - elt.addEventListener('focusout', function(evt){ - var internalData = getInternalData(form); - internalData.lastButtonClicked = null; - }) + elt.addEventListener('focusout', maybeUnsetLastButtonClicked) } function countCurlies(line) { diff --git a/test/core/ajax.js b/test/core/ajax.js index 0ca9e075..7d18be73 100644 --- a/test/core/ajax.js +++ b/test/core/ajax.js @@ -1284,5 +1284,32 @@ describe("Core htmx AJAX Tests", function(){ byId("submit").click(); this.server.respond(); responded.should.equal(true); + it("can associate submit buttons from outside a form with the current version of the form after swap", function(){ + const template = '
\n' + + ''; + + var values + this.server.respondWith("/test", function (xhr) { + values = getParameters(xhr); + xhr.respond(200, {}, template); + }); + make(template); + const button = byId("outside"); + button.focus(); + button.click(); + this.server.respond(); + values.should.deep.equal({name: "", outside: ""}); + button.focus(); + button.click(); + this.server.respond(); + values.should.deep.equal({name: "", outside: ""}); }) })