support next and previous (taken from hyperscript) in target expressions

fixes https://github.com/bigskysoftware/htmx/issues/814
This commit is contained in:
Carson Gross 2022-05-13 08:14:38 -06:00
parent b735c291df
commit 8290da624b
2 changed files with 64 additions and 1 deletions

View File

@ -523,6 +523,10 @@ return (function () {
return [closest(elt, selector.substr(8))];
} else if (selector.indexOf("find ") === 0) {
return [find(elt, selector.substr(5))];
} else if (selector.indexOf("next ") === 0) {
return [scanForwardQuery(elt, selector.substr(5))];
} else if (selector.indexOf("previous ") === 0) {
return [scanBackwardsQuery(elt, selector.substr(9))];
} else if (selector === 'document') {
return [document];
} else if (selector === 'window') {
@ -532,6 +536,26 @@ return (function () {
}
}
var scanForwardQuery = function(start, match) {
var results = getDocument().querySelectorAll(match);
for (var i = 0; i < results.length; i++) {
var elt = results[i];
if (elt.compareDocumentPosition(start) === Node.DOCUMENT_POSITION_PRECEDING) {
return elt;
}
}
}
var scanBackwardsQuery = function(start, match) {
var results = getDocument().querySelectorAll(match);
for (var i = results.length - 1; i >= 0; i--) {
var elt = results[i];
if (elt.compareDocumentPosition(start) === Node.DOCUMENT_POSITION_FOLLOWING) {
return elt;
}
}
}
function querySelectorExt(eltOrSelector, selector) {
if (selector) {
return querySelectorAllExt(eltOrSelector, selector)[0];
@ -1111,7 +1135,7 @@ return (function () {
} else if (token === "from" && tokens[0] === ":") {
tokens.shift();
var from_arg = consumeUntil(tokens, WHITESPACE_OR_COMMA);
if (from_arg === "closest" || from_arg === "find") {
if (from_arg === "closest" || from_arg === "find" || from_arg === "next" || from_arg === "previous") {
tokens.shift();
from_arg +=
" " +

View File

@ -91,5 +91,44 @@ describe("hx-target attribute", function(){
div1.innerHTML.should.equal("Clicked!");
});
it('targets a `next` element properly', function()
{
this.server.respondWith("GET", "/test", "Clicked!");
make('<div>' +
' <div id="d3"></div>' +
' <button id="b1" hx-target="next div" hx-get="/test">Click Me!</button>' +
' <div id="d1"></div>' +
' <div id="d2"></div>' +
'</div>')
var btn = byId("b1")
var div1 = byId("d1")
var div2 = byId("d2")
var div3 = byId("d3")
btn.click();
this.server.respond();
div1.innerHTML.should.equal("Clicked!");
div2.innerHTML.should.equal("");
div3.innerHTML.should.equal("");
});
it('targets a `previous` element properly', function()
{
this.server.respondWith("GET", "/test", "Clicked!");
make('<div>' +
' <div id="d3"></div>' +
' <button id="b1" hx-target="previous div" hx-get="/test">Click Me!</button>' +
' <div id="d1"></div>' +
' <div id="d2"></div>' +
'</div>')
var btn = byId("b1")
var div1 = byId("d1")
var div2 = byId("d2")
var div3 = byId("d3")
btn.click();
this.server.respond();
div1.innerHTML.should.equal("");
div2.innerHTML.should.equal("");
div3.innerHTML.should.equal("Clicked!");
});
})