[New feature] Comma separated list syntax for HX-Trigger response header (#1479)

* Comma separated list syntax for HX-Trigger response header

* Fix wording
This commit is contained in:
Vincent
2023-07-18 21:10:43 +02:00
committed by GitHub
parent e89c9c6402
commit 91d06309dc
3 changed files with 123 additions and 2 deletions

View File

@@ -1113,7 +1113,10 @@ return (function () {
}
}
} else {
triggerEvent(elt, triggerBody, []);
var eventNames = triggerBody.split(",")
for (var i = 0; i < eventNames.length; i++) {
triggerEvent(elt, eventNames[i].trim(), []);
}
}
}

View File

@@ -168,6 +168,78 @@ describe("Core htmx AJAX headers", function () {
htmx.off('foo', handler);
})
it("should handle simple comma separated list HX-Trigger response header properly", function () {
this.server.respondWith("GET", "/test", [200, {"HX-Trigger": "foo, bar"}, ""]);
var div = make('<div hx-get="/test"></div>');
var invokedEventFoo = false;
var invokedEventBar = false;
div.addEventListener("foo", function (evt) {
invokedEventFoo = true;
});
div.addEventListener("bar", function (evt) {
invokedEventBar = true;
});
div.click();
this.server.respond();
invokedEventFoo.should.equal(true);
invokedEventBar.should.equal(true);
})
it("should handle simple comma separated list without space HX-Trigger response header properly", function () {
this.server.respondWith("GET", "/test", [200, {"HX-Trigger": "foo,bar"}, ""]);
var div = make('<div hx-get="/test"></div>');
var invokedEventFoo = false;
var invokedEventBar = false;
div.addEventListener("foo", function (evt) {
invokedEventFoo = true;
});
div.addEventListener("bar", function (evt) {
invokedEventBar = true;
});
div.click();
this.server.respond();
invokedEventFoo.should.equal(true);
invokedEventBar.should.equal(true);
})
it("should handle dot path in comma separated list HX-Trigger response header properly", function () {
this.server.respondWith("GET", "/test", [200, {"HX-Trigger": "foo.bar,bar.baz"}, ""]);
var div = make('<div hx-get="/test"></div>');
var invokedEventFoo = false;
var invokedEventBar = false;
div.addEventListener("foo.bar", function (evt) {
invokedEventFoo = true;
});
div.addEventListener("bar.baz", function (evt) {
invokedEventBar = true;
});
div.click();
this.server.respond();
invokedEventFoo.should.equal(true);
invokedEventBar.should.equal(true);
})
it("should handle a namespaced comma separated list HX-Trigger response header properly", function () {
this.server.respondWith("GET", "/test", [200, {"HX-Trigger": "namespace:foo,bar"}, ""]);
var div = make('<div hx-get="/test"></div>');
var invokedEventFoo = false;
var invokedEventBar = false;
div.addEventListener("namespace:foo", function (evt) {
invokedEventFoo = true;
});
div.addEventListener("bar", function (evt) {
invokedEventBar = true;
});
div.click();
this.server.respond();
invokedEventFoo.should.equal(true);
invokedEventBar.should.equal(true);
})
it("should handle HX-Retarget", function () {
this.server.respondWith("GET", "/test", [200, {"HX-Retarget": "#d2"}, "Result"]);
@@ -212,6 +284,26 @@ describe("Core htmx AJAX headers", function () {
htmx.off('foo', handler);
})
it("should handle simple comma separated list HX-Trigger-After-Swap response header properly w/ outerHTML swap", function () {
this.server.respondWith("GET", "/test", [200, {"HX-Trigger-After-Swap": "foo, bar"}, ""]);
var div = make('<div hx-swap="outerHTML" hx-get="/test"></div>');
var invokedEventFoo = false;
var invokedEventBar = false;
var handlerFoo = htmx.on('foo', function (evt) {
invokedEventFoo = true;
});
var handlerBar = htmx.on('bar', function (evt) {
invokedEventBar = true;
});
div.click();
this.server.respond();
invokedEventFoo.should.equal(true);
invokedEventBar.should.equal(true);
htmx.off('foo', handlerFoo);
htmx.off('bar', handlerBar);
})
it("should handle simple string HX-Trigger-After-Settle response header properly w/ outerHTML swap", function () {
this.server.respondWith("GET", "/test", [200, {"HX-Trigger-After-Settle": "foo"}, ""]);
@@ -226,6 +318,26 @@ describe("Core htmx AJAX headers", function () {
htmx.off('foo', handler);
})
it("should handle simple comma separated list HX-Trigger-After-Settle response header properly w/ outerHTML swap", function () {
this.server.respondWith("GET", "/test", [200, {"HX-Trigger-After-Settle": "foo, bar"}, ""]);
var div = make('<div hx-swap="outerHTML" hx-get="/test"></div>');
var invokedEventFoo = false;
var invokedEventBar = false;
var handlerFoo = htmx.on('foo', function (evt) {
invokedEventFoo = true;
});
var handlerBar = htmx.on('bar', function (evt) {
invokedEventBar = true;
});
div.click();
this.server.respond();
invokedEventFoo.should.equal(true);
invokedEventBar.should.equal(true);
htmx.off('foo', handlerFoo);
htmx.off('bar', handlerBar);
})
it("should change body content on HX-Location", function () {
this.server.respondWith("GET", "/test", [200, {"HX-Location": '{"path":"/test2", "target":"#testdiv"}'}, ""]);

View File

@@ -60,9 +60,15 @@ document.body.addEventListener("showMessage", function(evt){
Each property of the JSON object on the right hand side will be copied onto the details object for the event.
Finally, if you wish to invoke multiple events, you can simply add additional properties to the top level JSON
### Multiple Triggers
If you wish to invoke multiple events, you can simply add additional properties to the top level JSON
object:
`HX-Trigger: {"event1":"A message", "event2":"Another message"}`
You may also trigger multiple events with no additional details by sending event names separated by commas, like so:
`HX-Trigger: event1, event2`
Using events gives you a lot of flexibility to add functionality to normal htmx responses.