Skip to content

Commit 8e489ef

Browse files
fix click events on elements wrapped by link don't cancel link navigation (#3357)
fix click events on elements wrapped by link doesn't cancel link navigation
1 parent 726292a commit 8e489ef

3 files changed

Lines changed: 50 additions & 1 deletion

File tree

src/htmx.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2435,7 +2435,9 @@ var htmx = (function() {
24352435
if (elt.form && elt.type === 'submit') {
24362436
return true
24372437
}
2438-
if (elt instanceof HTMLAnchorElement && elt.href &&
2438+
elt = elt.closest('a')
2439+
// @ts-ignore check for a link wrapping the event elt or if elt is a link. elt will be link so href check is fine
2440+
if (elt && elt.href &&
24392441
(elt.getAttribute('href') === '#' || elt.getAttribute('href').indexOf('#') !== 0)) {
24402442
return true
24412443
}

test/core/internals.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ describe('Core htmx internals Tests', function() {
107107
htmx._('shouldCancel')({ type: 'submit', target: anchorThatShouldNotCancel }, form).should.equal(false)
108108
htmx._('shouldCancel')({ type: 'click', target: divThatShouldNotCancel }, form).should.equal(false)
109109

110+
// check elements inside links getting click events should cancel parent links
111+
var anchorWithButton = make("<a href='/foo'><button></button></a>")
112+
htmx._('shouldCancel')({ type: 'click', target: anchorWithButton.firstChild }, anchorWithButton).should.equal(true)
113+
htmx._('shouldCancel')({ type: 'click', target: anchorWithButton.firstChild }, anchorWithButton.firstChild).should.equal(true)
114+
110115
form = make('<form id="f1">' +
111116
'<input id="insideInput" type="submit">' +
112117
'<button id="insideFormBtn"></button>' +

test/core/regressions.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,4 +291,46 @@ describe('Core htmx Regression Tests', function() {
291291

292292
byId('datefield').click()
293293
})
294+
295+
it('a button clicked inside an htmx enabled link will prevent the link from navigating on click', function(done) {
296+
var defaultPrevented = 'unset'
297+
var link = make('<a href="/foo" hx-get="/foo"><button>test</button></a>')
298+
var button = link.firstChild
299+
300+
htmx.on(link, 'click', function(evt) {
301+
// we need to wait so the state of the evt is finalized
302+
setTimeout(() => {
303+
defaultPrevented = evt.defaultPrevented
304+
try {
305+
defaultPrevented.should.equal(true)
306+
done()
307+
} catch (err) {
308+
done(err)
309+
}
310+
}, 0)
311+
})
312+
313+
button.click()
314+
})
315+
316+
it('a htmx enabled button clicked inside a link will prevent the link from navigating on click', function(done) {
317+
var defaultPrevented = 'unset'
318+
var link = make('<a href="/foo"><button hx-get="/foo">test</button></a>')
319+
var button = link.firstChild
320+
321+
htmx.on(link, 'click', function(evt) {
322+
// we need to wait so the state of the evt is finalized
323+
setTimeout(() => {
324+
defaultPrevented = evt.defaultPrevented
325+
try {
326+
defaultPrevented.should.equal(true)
327+
done()
328+
} catch (err) {
329+
done(err)
330+
}
331+
}, 0)
332+
})
333+
334+
button.click()
335+
})
294336
})

0 commit comments

Comments
 (0)