Skip to content

Commit 324bfd6

Browse files
committed
Attach hx-on handlers before processing node
1 parent 9fcb5c5 commit 324bfd6

File tree

3 files changed

+57
-35
lines changed

3 files changed

+57
-35
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
* Using `<button hx-verb="/endpoint" type="reset">` will now reset the associated form (after submitting to `/endpoint`)
66
* Using `<button formmethod="dialog">` will no longer submit its associated form
7+
* Fixed a bug that prevented `hx-on*` from firing when triggered immediately by `load` or `revealed`
78

89
## [2.0.4] - 2024-12-13
910

src/htmx.js

+42-35
Original file line numberDiff line numberDiff line change
@@ -2902,44 +2902,32 @@ var htmx = (function() {
29022902
* @param {Element|HTMLInputElement} elt
29032903
*/
29042904
function initNode(elt) {
2905-
if (closest(elt, htmx.config.disableSelector)) {
2906-
cleanUpElement(elt)
2907-
return
2908-
}
2905+
triggerEvent(elt, 'htmx:beforeProcessNode')
2906+
29092907
const nodeData = getInternalData(elt)
2910-
const attrHash = attributeHash(elt)
2911-
if (nodeData.initHash !== attrHash) {
2912-
// clean up any previously processed info
2913-
deInitNode(elt)
2914-
2915-
nodeData.initHash = attrHash
2916-
2917-
triggerEvent(elt, 'htmx:beforeProcessNode')
2918-
2919-
const triggerSpecs = getTriggerSpecs(elt)
2920-
const hasExplicitHttpAction = processVerbs(elt, nodeData, triggerSpecs)
2921-
2922-
if (!hasExplicitHttpAction) {
2923-
if (getClosestAttributeValue(elt, 'hx-boost') === 'true') {
2924-
boostElement(elt, nodeData, triggerSpecs)
2925-
} else if (hasAttribute(elt, 'hx-trigger')) {
2926-
triggerSpecs.forEach(function(triggerSpec) {
2927-
// For "naked" triggers, don't do anything at all
2928-
addTriggerHandler(elt, triggerSpec, nodeData, function() {
2929-
})
2930-
})
2931-
}
2932-
}
2908+
const triggerSpecs = getTriggerSpecs(elt)
2909+
const hasExplicitHttpAction = processVerbs(elt, nodeData, triggerSpecs)
29332910

2934-
// Handle submit buttons/inputs that have the form attribute set
2935-
// see https://developer.mozilla.org/docs/Web/HTML/Element/button
2936-
if (elt.tagName === 'FORM' || (getRawAttribute(elt, 'type') === 'submit' && hasAttribute(elt, 'form'))) {
2937-
initButtonTracking(elt)
2911+
if (!hasExplicitHttpAction) {
2912+
if (getClosestAttributeValue(elt, 'hx-boost') === 'true') {
2913+
boostElement(elt, nodeData, triggerSpecs)
2914+
} else if (hasAttribute(elt, 'hx-trigger')) {
2915+
triggerSpecs.forEach(function(triggerSpec) {
2916+
// For "naked" triggers, don't do anything at all
2917+
addTriggerHandler(elt, triggerSpec, nodeData, function() {
2918+
})
2919+
})
29382920
}
2921+
}
29392922

2940-
nodeData.firstInitCompleted = true
2941-
triggerEvent(elt, 'htmx:afterProcessNode')
2923+
// Handle submit buttons/inputs that have the form attribute set
2924+
// see https://developer.mozilla.org/docs/Web/HTML/Element/button
2925+
if (elt.tagName === 'FORM' || (getRawAttribute(elt, 'type') === 'submit' && hasAttribute(elt, 'form'))) {
2926+
initButtonTracking(elt)
29422927
}
2928+
2929+
nodeData.firstInitCompleted = true
2930+
triggerEvent(elt, 'htmx:afterProcessNode')
29432931
}
29442932

29452933
/**
@@ -2955,9 +2943,28 @@ var htmx = (function() {
29552943
cleanUpElement(elt)
29562944
return
29572945
}
2958-
initNode(elt)
2959-
forEach(findElementsToProcess(elt), function(child) { initNode(child) })
2946+
2947+
const elementsToInit = []
2948+
2949+
function maybeDeInit(e) {
2950+
if (closest(e, htmx.config.disableSelector)) {
2951+
cleanUpElement(e)
2952+
return
2953+
}
2954+
const nodeData = getInternalData(e)
2955+
const hash = attributeHash(e)
2956+
if (nodeData.initHash !== hash) {
2957+
deInitNode(e)
2958+
nodeData.initHash = hash
2959+
elementsToInit.push(e)
2960+
}
2961+
}
2962+
2963+
maybeDeInit(elt)
2964+
forEach(findElementsToProcess(elt), maybeDeInit)
2965+
29602966
forEach(findHxOnWildcardElements(elt), processHxOnWildcard)
2967+
forEach(elementsToInit, initNode)
29612968
}
29622969

29632970
//= ===================================================================

test/attributes/hx-on-wildcard.js

+14
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ describe('hx-on:* attribute', function() {
133133
delete window.foo
134134
})
135135

136+
it('should fire when triggered by load', function() {
137+
this.server.respondWith('POST', '/test', 'test')
138+
make("<div hx-trigger='load' hx-post='/test' hx-on:htmx:config-request='foo = true'></div>")
139+
window.foo.should.equal(true)
140+
delete window.foo
141+
})
142+
143+
it('should fire when triggered by revealed', function() {
144+
this.server.respondWith('POST', '/test', 'test')
145+
make("<div hx-trigger='revealed' hx-post='/test' hx-on:htmx:config-request='foo = true'></div>")
146+
window.foo.should.equal(true)
147+
delete window.foo
148+
})
149+
136150
it('de-initializes hx-on-* content properly', function() {
137151
window.tempCount = 0
138152
this.server.respondWith('POST', '/test', function(xhr) {

0 commit comments

Comments
 (0)