mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-10-02 07:21:05 +00:00
Merge branch 'dev' of https://github.com/bigskysoftware/htmx
This commit is contained in:
commit
8d655da761
@ -5,7 +5,7 @@
|
||||
"AJAX",
|
||||
"HTML"
|
||||
],
|
||||
"version": "1.2.1",
|
||||
"version": "1.3.0",
|
||||
"homepage": "https://htmx.org/",
|
||||
"bugs": {
|
||||
"url": "https://github.com/bigskysoftware/htmx/issues"
|
||||
|
59
src/htmx.js
59
src/htmx.js
@ -847,12 +847,17 @@ return (function () {
|
||||
triggerSpec.changed = true;
|
||||
} else if (token === "once") {
|
||||
triggerSpec.once = true;
|
||||
} else if (token === "consume") {
|
||||
triggerSpec.consume = true;
|
||||
} else if (token === "delay" && tokens[0] === ":") {
|
||||
tokens.shift();
|
||||
triggerSpec.delay = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA));
|
||||
} else if (token === "from" && tokens[0] === ":") {
|
||||
tokens.shift();
|
||||
triggerSpec.from = consumeUntil(tokens, WHITESPACE_OR_COMMA);
|
||||
} else if (token === "target" && tokens[0] === ":") {
|
||||
tokens.shift();
|
||||
triggerSpec.target = consumeUntil(tokens, WHITESPACE_OR_COMMA);
|
||||
} else if (token === "throttle" && tokens[0] === ":") {
|
||||
tokens.shift();
|
||||
triggerSpec.throttle = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA));
|
||||
@ -962,9 +967,20 @@ return (function () {
|
||||
return;
|
||||
}
|
||||
var eventData = getInternalData(evt);
|
||||
if (eventData.handledFor == null) {
|
||||
eventData.handledFor = [];
|
||||
}
|
||||
var elementData = getInternalData(elt);
|
||||
if (!eventData.handled) {
|
||||
eventData.handled = true;
|
||||
if (eventData.handledFor.indexOf(elt) < 0) {
|
||||
eventData.handledFor.push(elt);
|
||||
if (triggerSpec.consume) {
|
||||
evt.stopPropagation();
|
||||
}
|
||||
if (triggerSpec.target && evt.target) {
|
||||
if (!evt.target.matches(triggerSpec.target)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (triggerSpec.once) {
|
||||
if (elementData.triggeredOnce) {
|
||||
return;
|
||||
@ -1174,6 +1190,7 @@ return (function () {
|
||||
var settleInfo = makeSettleInfo(elt);
|
||||
|
||||
selectAndSwap(swapSpec.swapStyle, elt, target, response, settleInfo)
|
||||
settleImmediately(settleInfo.tasks)
|
||||
triggerEvent(elt, "htmx:sseMessage", event)
|
||||
};
|
||||
|
||||
@ -1427,7 +1444,7 @@ return (function () {
|
||||
while(historyCache.length > 0){
|
||||
try {
|
||||
localStorage.setItem("htmx-history-cache", JSON.stringify(historyCache));
|
||||
return;
|
||||
break;
|
||||
} catch (e) {
|
||||
triggerErrorEvent(getDocument().body, "htmx:historyCacheError", {cause:e, cache: historyCache})
|
||||
historyCache.shift(); // shrink the cache and retry
|
||||
@ -1923,16 +1940,22 @@ return (function () {
|
||||
function ajaxHelper(verb, path, context) {
|
||||
if (context) {
|
||||
if (context instanceof Element || isType(context, 'String')) {
|
||||
issueAjaxRequest(verb, path, null, null, null, resolveTarget(context));
|
||||
return issueAjaxRequest(verb, path, null, null, null, resolveTarget(context));
|
||||
} else {
|
||||
issueAjaxRequest(verb, path, resolveTarget(context.source), context.event, context.handler, resolveTarget(context.target));
|
||||
return issueAjaxRequest(verb, path, resolveTarget(context.source), context.event, context.handler, resolveTarget(context.target));
|
||||
}
|
||||
} else {
|
||||
issueAjaxRequest(verb, path);
|
||||
return issueAjaxRequest(verb, path);
|
||||
}
|
||||
}
|
||||
|
||||
function issueAjaxRequest(verb, path, elt, event, responseHandler, targetOverride) {
|
||||
var resolve = null;
|
||||
var reject = null;
|
||||
var promise = new Promise(function (_resolve, _reject) {
|
||||
resolve = _resolve;
|
||||
reject = _reject;
|
||||
});
|
||||
if(elt == null) {
|
||||
elt = getDocument().body;
|
||||
}
|
||||
@ -1970,12 +1993,18 @@ return (function () {
|
||||
// prompt returns null if cancelled and empty string if accepted with no entry
|
||||
if (promptResponse === null ||
|
||||
!triggerEvent(elt, 'htmx:prompt', {prompt: promptResponse, target:target}))
|
||||
return endRequestLock();
|
||||
resolve();
|
||||
endRequestLock();
|
||||
return promise;
|
||||
}
|
||||
|
||||
var confirmQuestion = getClosestAttributeValue(elt, "hx-confirm");
|
||||
if (confirmQuestion) {
|
||||
if(!confirm(confirmQuestion)) return endRequestLock();
|
||||
if(!confirm(confirmQuestion)) {
|
||||
resolve();
|
||||
endRequestLock()
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
@ -2018,7 +2047,9 @@ return (function () {
|
||||
|
||||
if(errors && errors.length > 0){
|
||||
triggerEvent(elt, 'htmx:validation:halted', requestConfig)
|
||||
return endRequestLock();
|
||||
resolve();
|
||||
endRequestLock();
|
||||
return promise;
|
||||
}
|
||||
|
||||
var splitPath = path.split("#");
|
||||
@ -2071,6 +2102,7 @@ return (function () {
|
||||
}
|
||||
triggerEvent(finalElt, 'htmx:afterRequest', responseInfo);
|
||||
triggerEvent(finalElt, 'htmx:afterOnLoad', responseInfo);
|
||||
resolve();
|
||||
endRequestLock();
|
||||
}
|
||||
}
|
||||
@ -2082,6 +2114,7 @@ return (function () {
|
||||
}
|
||||
triggerErrorEvent(finalElt, 'htmx:afterRequest', responseInfo);
|
||||
triggerErrorEvent(finalElt, 'htmx:sendError', responseInfo);
|
||||
reject();
|
||||
endRequestLock();
|
||||
}
|
||||
xhr.onabort = function() {
|
||||
@ -2092,9 +2125,14 @@ return (function () {
|
||||
}
|
||||
triggerErrorEvent(finalElt, 'htmx:afterRequest', responseInfo);
|
||||
triggerErrorEvent(finalElt, 'htmx:sendAbort', responseInfo);
|
||||
reject();
|
||||
endRequestLock();
|
||||
}
|
||||
if(!triggerEvent(elt, 'htmx:beforeRequest', responseInfo)) return endRequestLock();
|
||||
if(!triggerEvent(elt, 'htmx:beforeRequest', responseInfo)){
|
||||
resolve();
|
||||
endRequestLock()
|
||||
return promise
|
||||
}
|
||||
var indicators = addRequestIndicatorClasses(elt);
|
||||
|
||||
forEach(['loadstart', 'loadend', 'progress', 'abort'], function(eventName) {
|
||||
@ -2109,6 +2147,7 @@ return (function () {
|
||||
});
|
||||
});
|
||||
xhr.send(verb === 'get' ? null : encodeParamsForBody(xhr, elt, filteredParameters));
|
||||
return promise;
|
||||
}
|
||||
|
||||
function handleAjaxResponse(elt, responseInfo) {
|
||||
|
@ -73,26 +73,22 @@ describe("hx-swap attribute", function(){
|
||||
var i = 0;
|
||||
this.server.respondWith("GET", "/test", function(xhr){
|
||||
i++;
|
||||
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>');
|
||||
xhr.respond(200, {}, "" + i);
|
||||
});
|
||||
this.server.respondWith("GET", "/test2", "*");
|
||||
|
||||
var div = make('<div hx-get="/test" hx-swap="afterbegin">*</div>')
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("1*");
|
||||
|
||||
byId("a1").click();
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("**");
|
||||
div.innerText.should.equal("21*");
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("2**");
|
||||
|
||||
byId("a2").click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("***");
|
||||
div.innerText.should.equal("321*");
|
||||
});
|
||||
|
||||
it('swap afterbegin properly with no initial content', function()
|
||||
@ -100,26 +96,22 @@ describe("hx-swap attribute", function(){
|
||||
var i = 0;
|
||||
this.server.respondWith("GET", "/test", function(xhr){
|
||||
i++;
|
||||
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>');
|
||||
xhr.respond(200, {}, "" + i);
|
||||
});
|
||||
this.server.respondWith("GET", "/test2", "*");
|
||||
|
||||
var div = make('<div hx-get="/test" hx-swap="afterbegin"></div>')
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("1");
|
||||
|
||||
byId("a1").click();
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("*");
|
||||
div.innerText.should.equal("21");
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("2*");
|
||||
|
||||
byId("a2").click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("**");
|
||||
div.innerText.should.equal("321");
|
||||
});
|
||||
|
||||
it('swap afterend properly', function()
|
||||
@ -152,58 +144,50 @@ describe("hx-swap attribute", function(){
|
||||
removeWhiteSpace(parent.innerText).should.equal("***");
|
||||
});
|
||||
|
||||
it('swap beforeend properly', function()
|
||||
it('handles beforeend properly', function()
|
||||
{
|
||||
var i = 0;
|
||||
this.server.respondWith("GET", "/test", function(xhr){
|
||||
i++;
|
||||
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>');
|
||||
xhr.respond(200, {}, "" + i);
|
||||
});
|
||||
this.server.respondWith("GET", "/test2", "*");
|
||||
|
||||
var div = make('<div hx-get="/test" hx-swap="beforeend">*</div>')
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("*1");
|
||||
|
||||
byId("a1").click();
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("**");
|
||||
div.innerText.should.equal("*12");
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("**2");
|
||||
|
||||
byId("a2").click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("***");
|
||||
div.innerText.should.equal("*123");
|
||||
});
|
||||
|
||||
it('swap beforeend properly with no initial content', function()
|
||||
it('handles beforeend properly with no initial content', function()
|
||||
{
|
||||
var i = 0;
|
||||
this.server.respondWith("GET", "/test", function(xhr){
|
||||
i++;
|
||||
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>');
|
||||
xhr.respond(200, {}, "" + i);
|
||||
});
|
||||
this.server.respondWith("GET", "/test2", "*");
|
||||
|
||||
var div = make('<div hx-get="/test" hx-swap="beforeend"></div>')
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("1");
|
||||
|
||||
byId("a1").click();
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("*");
|
||||
div.innerText.should.equal("12");
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("*2");
|
||||
|
||||
byId("a2").click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("**");
|
||||
div.innerText.should.equal("123");
|
||||
});
|
||||
|
||||
it('properly parses various swap specifications', function(){
|
||||
|
@ -385,15 +385,18 @@ describe("hx-trigger attribute", function(){
|
||||
this.server.respond();
|
||||
requests.should.equal(1);
|
||||
|
||||
requests.should.equal(1);
|
||||
|
||||
div1.click();
|
||||
this.server.respond();
|
||||
div1.innerHTML.should.equal("Clicked");
|
||||
|
||||
requests.should.equal(2);
|
||||
|
||||
document.body.click();
|
||||
this.server.respond();
|
||||
|
||||
// event listener should have been removed when this element was removed
|
||||
requests.should.equal(1);
|
||||
requests.should.equal(2);
|
||||
});
|
||||
|
||||
it('multiple triggers with from clauses mixed in work', function()
|
||||
@ -414,4 +417,57 @@ describe("hx-trigger attribute", function(){
|
||||
div1.innerHTML.should.equal("Requests: 2");
|
||||
});
|
||||
|
||||
it('event listeners can filter on target', function()
|
||||
{
|
||||
var requests = 0;
|
||||
this.server.respondWith("GET", "/test", function (xhr) {
|
||||
requests++;
|
||||
xhr.respond(200, {}, "Requests: " + requests);
|
||||
});
|
||||
|
||||
var div1 = make('<div>' +
|
||||
'<div id="d1" hx-trigger="click from:body target:#d3" hx-get="/test">Requests: 0</div>' +
|
||||
'<div id="d2"></div>' +
|
||||
'<div id="d3"></div>' +
|
||||
'</div>');
|
||||
var div1 = byId("d1");
|
||||
var div2 = byId("d2");
|
||||
var div3 = byId("d3");
|
||||
|
||||
div1.innerHTML.should.equal("Requests: 0");
|
||||
document.body.click();
|
||||
this.server.respond();
|
||||
requests.should.equal(0);
|
||||
|
||||
div1.click();
|
||||
this.server.respond();
|
||||
requests.should.equal(0);
|
||||
|
||||
div2.click();
|
||||
this.server.respond();
|
||||
requests.should.equal(0);
|
||||
|
||||
div3.click();
|
||||
this.server.respond();
|
||||
requests.should.equal(1);
|
||||
|
||||
});
|
||||
|
||||
it('consume prevents event propogation', function()
|
||||
{
|
||||
this.server.respondWith("GET", "/foo", "foo");
|
||||
this.server.respondWith("GET", "/bar", "bar");
|
||||
var div = make("<div hx-trigger='click' hx-get='/foo'>" +
|
||||
" <div id='d1' hx-trigger='click consume' hx-get='/bar'></div>" +
|
||||
"</div>");
|
||||
|
||||
byId("d1").click();
|
||||
this.server.respond();
|
||||
|
||||
// should not have been replaced by click
|
||||
byId("d1").parentElement.should.equal(div);
|
||||
byId("d1").innerText.should.equal("bar");
|
||||
});
|
||||
|
||||
|
||||
})
|
||||
|
@ -84,26 +84,22 @@ describe("Core htmx AJAX Tests", function(){
|
||||
var i = 0;
|
||||
this.server.respondWith("GET", "/test", function(xhr){
|
||||
i++;
|
||||
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>');
|
||||
xhr.respond(200, {}, "" + i);
|
||||
});
|
||||
this.server.respondWith("GET", "/test2", "*");
|
||||
|
||||
var div = make('<div hx-get="/test" hx-swap="afterbegin">*</div>')
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("1*");
|
||||
|
||||
byId("a1").click();
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("**");
|
||||
div.innerText.should.equal("21*");
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("2**");
|
||||
|
||||
byId("a2").click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("***");
|
||||
div.innerText.should.equal("321*");
|
||||
});
|
||||
|
||||
it('handles afterbegin properly with no initial content', function()
|
||||
@ -111,26 +107,22 @@ describe("Core htmx AJAX Tests", function(){
|
||||
var i = 0;
|
||||
this.server.respondWith("GET", "/test", function(xhr){
|
||||
i++;
|
||||
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>');
|
||||
xhr.respond(200, {}, "" + i);
|
||||
});
|
||||
this.server.respondWith("GET", "/test2", "*");
|
||||
|
||||
var div = make('<div hx-get="/test" hx-swap="afterbegin"></div>')
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("1");
|
||||
|
||||
byId("a1").click();
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("*");
|
||||
div.innerText.should.equal("21");
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("2*");
|
||||
|
||||
byId("a2").click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("**");
|
||||
div.innerText.should.equal("321");
|
||||
});
|
||||
|
||||
it('handles afterend properly', function()
|
||||
@ -168,26 +160,22 @@ describe("Core htmx AJAX Tests", function(){
|
||||
var i = 0;
|
||||
this.server.respondWith("GET", "/test", function(xhr){
|
||||
i++;
|
||||
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>');
|
||||
xhr.respond(200, {}, "" + i);
|
||||
});
|
||||
this.server.respondWith("GET", "/test2", "*");
|
||||
|
||||
var div = make('<div hx-get="/test" hx-swap="beforeend">*</div>')
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("*1");
|
||||
|
||||
byId("a1").click();
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("**");
|
||||
div.innerText.should.equal("*12");
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("**2");
|
||||
|
||||
byId("a2").click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("***");
|
||||
div.innerText.should.equal("*123");
|
||||
});
|
||||
|
||||
it('handles beforeend properly with no initial content', function()
|
||||
@ -195,26 +183,22 @@ describe("Core htmx AJAX Tests", function(){
|
||||
var i = 0;
|
||||
this.server.respondWith("GET", "/test", function(xhr){
|
||||
i++;
|
||||
xhr.respond(200, {}, '<a id="a' + i + '" hx-get="/test2" hx-swap="innerHTML">' + i + '</a>');
|
||||
xhr.respond(200, {}, "" + i);
|
||||
});
|
||||
this.server.respondWith("GET", "/test2", "*");
|
||||
|
||||
var div = make('<div hx-get="/test" hx-swap="beforeend"></div>')
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("1");
|
||||
|
||||
byId("a1").click();
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("*");
|
||||
div.innerText.should.equal("12");
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("*2");
|
||||
|
||||
byId("a2").click();
|
||||
this.server.respond();
|
||||
div.innerText.should.equal("**");
|
||||
div.innerText.should.equal("123");
|
||||
});
|
||||
|
||||
it('handles hx-target properly', function()
|
||||
@ -551,7 +535,7 @@ describe("Core htmx AJAX Tests", function(){
|
||||
|
||||
it('text nodes dont screw up settling via variable capture', function()
|
||||
{
|
||||
this.server.respondWith("GET", "/test", "<div id='d1' hx-get='/test2'></div>fooo");
|
||||
this.server.respondWith("GET", "/test", "<div id='d1' hx-trigger='click consume' hx-get='/test2'></div>fooo");
|
||||
this.server.respondWith("GET", "/test2", "clicked");
|
||||
var div = make("<div hx-get='/test'/>");
|
||||
div.click();
|
||||
@ -561,7 +545,6 @@ describe("Core htmx AJAX Tests", function(){
|
||||
byId("d1").innerHTML.should.equal("clicked");
|
||||
});
|
||||
|
||||
|
||||
it('script nodes evaluate', function()
|
||||
{
|
||||
var globalWasCalled = false;
|
||||
|
@ -261,5 +261,36 @@ describe("Core htmx API test", function(){
|
||||
calledEvent.should.equal(true);
|
||||
});
|
||||
|
||||
it('ajax api works', function()
|
||||
{
|
||||
this.server.respondWith("GET", "/test", "foo!");
|
||||
var div = make("<div></div>");
|
||||
htmx.ajax("GET", "/test", div)
|
||||
this.server.respond();
|
||||
div.innerHTML.should.equal("foo!");
|
||||
});
|
||||
|
||||
it('ajax api works by ID', function()
|
||||
{
|
||||
this.server.respondWith("GET", "/test", "foo!");
|
||||
var div = make("<div id='d1'></div>");
|
||||
htmx.ajax("GET", "/test", "#d1")
|
||||
this.server.respond();
|
||||
div.innerHTML.should.equal("foo!");
|
||||
});
|
||||
|
||||
it('ajax returns a promise', function(done)
|
||||
{
|
||||
this.server.respondWith("GET", "/test", "foo!");
|
||||
var div = make("<div id='d1'></div>");
|
||||
var promise = htmx.ajax("GET", "/test", "#d1");
|
||||
this.server.respond();
|
||||
div.innerHTML.should.equal("foo!");
|
||||
promise.then(function(){
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
@ -41,4 +41,24 @@ describe("Core htmx internals Tests", function() {
|
||||
chai.expect(htmx._("tokenizeString")("aa.aa")).to.be.deep.equal(['aa', '.', 'aa']);
|
||||
})
|
||||
|
||||
it("tags respond correctly to shouldCancel", function() {
|
||||
var anchorThatShouldCancel = make("<a href='/foo'></a>");
|
||||
htmx._("shouldCancel")(anchorThatShouldCancel).should.equal(true);
|
||||
|
||||
var anchorThatShouldNotCancel = make("<a href='#'></a>");
|
||||
htmx._("shouldCancel")(anchorThatShouldNotCancel).should.equal(false);
|
||||
|
||||
var form = make("<form></form>");
|
||||
htmx._("shouldCancel")(form).should.equal(true);
|
||||
|
||||
var form = make("<form><input id='i1' type='submit'></form>");
|
||||
var input = byId("i1");
|
||||
htmx._("shouldCancel")(input).should.equal(true);
|
||||
|
||||
var form = make("<form><button id='b1' type='submit'></form>");
|
||||
var button = byId("b1");
|
||||
htmx._("shouldCancel")(button).should.equal(true);
|
||||
|
||||
})
|
||||
|
||||
});
|
@ -110,4 +110,21 @@ describe("Core htmx Regression Tests", function(){
|
||||
defaultPrevented.should.equal(true);
|
||||
})
|
||||
|
||||
it('two elements can listen for the same event on another element', function() {
|
||||
this.server.respondWith("GET", "/test", "triggered");
|
||||
|
||||
make('<div id="d1" hx-trigger="click from:body" hx-get="/test"></div>' +
|
||||
' <div id="d2" hx-trigger="click from:body" hx-get="/test"></div>');
|
||||
|
||||
|
||||
var div1 = byId("d1");
|
||||
var div2 = byId("d2");
|
||||
|
||||
document.body.click();
|
||||
this.server.respond();
|
||||
|
||||
div2.innerHTML.should.equal("triggered");
|
||||
div1.innerHTML.should.equal("triggered");
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -58,6 +58,9 @@ is seen again it will reset the delay.
|
||||
* `throttle:<timing declaration>` - a throttle will occur before an event triggers a request. If the event
|
||||
is seen again before the delay completes it is ignored, the element will trigger at the end of the delay.
|
||||
* `from:<CSS selector>` - allows the event that triggers a request to come from another element in the document (e.g. listening to a key event on the body, to support hot keys)
|
||||
* `target:<CSS selector>` - allows you to filter via a CSS selector on the target of the event. This can be useful when you want to listen for
|
||||
triggers from elements that might not be in the DOM at the point of initialization, by listening on the body, but with a target filter for a
|
||||
child
|
||||
|
||||
Here is an example of a search box that searches on `keyup`, but only if the search value has changed
|
||||
and the user hasn't typed anything new for 1 second:
|
||||
|
Loading…
x
Reference in New Issue
Block a user