Skip to content

Commit 246a733

Browse files
authored
phx-trigger-action: check for cloned tree (#3601)
Fixes #3591.
1 parent 3d2d3dd commit 246a733

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

assets/js/phoenix_live_view/dom.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ let DOM = {
467467
isTextualInput(el){ return FOCUSABLE_INPUTS.indexOf(el.type) >= 0 },
468468

469469
isNowTriggerFormExternal(el, phxTriggerExternal){
470-
return el.getAttribute && el.getAttribute(phxTriggerExternal) !== null
470+
return el.getAttribute && el.getAttribute(phxTriggerExternal) !== null && document.body.contains(el)
471471
},
472472

473473
cleanChildNodes(container, phxUpdate){

assets/js/phoenix_live_view/dom_patch.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export default class DOMPatch {
3030
let focused = liveSocket.getActiveElement()
3131
let {selectionStart, selectionEnd} = focused && DOM.hasSelectionRange(focused) ? focused : {}
3232
let phxUpdate = liveSocket.binding(PHX_UPDATE)
33+
let externalFormTriggered = null
3334

3435
morphdom(container, clonedTree, {
3536
childrenOnly: false,
@@ -42,9 +43,19 @@ export default class DOMPatch {
4243
DOM.mergeFocusedInput(fromEl, toEl)
4344
return false
4445
}
46+
if(DOM.isNowTriggerFormExternal(toEl, liveSocket.binding(PHX_TRIGGER_ACTION))){
47+
externalFormTriggered = toEl
48+
}
4549
}
4650
})
4751

52+
if(externalFormTriggered){
53+
liveSocket.unload()
54+
// use prototype's submit in case there's a form control with name or id of "submit"
55+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit
56+
Object.getPrototypeOf(externalFormTriggered).submit.call(externalFormTriggered)
57+
}
58+
4859
liveSocket.silenceEvents(() => DOM.restoreFocus(focused, selectionStart, selectionEnd))
4960
}
5061

@@ -228,7 +239,7 @@ export default class DOMPatch {
228239
return false
229240
}
230241
if(fromEl.type === "number" && (fromEl.validity && fromEl.validity.badInput)){ return false }
231-
// If the element has PHX_REF_SRC, it is loading or locked and awaiting an ack.
242+
// If the element has PHX_REF_SRC, it is loading or locked and awaiting an ack.
232243
// If it's locked, we clone the fromEl tree and instruct morphdom to use
233244
// the cloned tree as the source of the morph for this branch from here on out.
234245
// We keep a reference to the cloned tree in the element's private data, and

assets/test/dom_test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,15 @@ describe("DOM", () => {
181181
test("isNowTriggerFormExternal", () => {
182182
let form
183183
form = tag("form", {"phx-trigger-external": ""}, "")
184+
document.body.appendChild(form)
184185
expect(DOM.isNowTriggerFormExternal(form, "phx-trigger-external")).toBe(true)
185186

186187
form = tag("form", {}, "")
188+
document.body.appendChild(form)
189+
expect(DOM.isNowTriggerFormExternal(form, "phx-trigger-external")).toBe(false)
190+
191+
// not in the DOM -> false
192+
form = tag("form", {"phx-trigger-external": ""}, "")
187193
expect(DOM.isNowTriggerFormExternal(form, "phx-trigger-external")).toBe(false)
188194
})
189195

0 commit comments

Comments
 (0)