support css class based indicators

This commit is contained in:
carson 2020-04-28 20:02:11 -07:00
parent d0d344588d
commit 2adff95fdd
5 changed files with 91 additions and 20 deletions

View File

@ -182,6 +182,26 @@ var HTMx = HTMx || (function () {
}
}
function addRequestIndicatorClasses(elt) {
mutateRequestIndicatorClasses(elt, "add");
}
function removeRequestIndicatorClasses(elt) {
mutateRequestIndicatorClasses(elt, "remove");
}
function mutateRequestIndicatorClasses(elt, action) {
var indicator = getClosestAttributeValue(elt, 'hx-indicator');
if (indicator) {
var indicators = document.querySelectorAll(indicator);
} else {
indicators = [elt];
}
for (var i = 0; i < indicators.length; i++) {
indicators[i].classList[action].call(indicators[i].classList, "hx-show-indicator");
}
}
// core ajax request
function issueAjaxRequest(elt, url) {
var target = getTarget(elt);
@ -222,11 +242,14 @@ var HTMx = HTMx || (function () {
// TODO error handling
elt.innerHTML = "ERROR";
}
removeRequestIndicatorClasses(elt);
};
xhr.onerror = function () {
removeIndicatorClasses(elt);
// TODO error handling
// There was a connection error of some sort
};
addRequestIndicatorClasses(elt);
xhr.send();
}

View File

@ -22,13 +22,13 @@ describe("HTMx History Tests", function() {
var div = make('<div hx-push-url="true" hx-get="/test">first</div>');
div.click();
this.server.respond();
getWorkArea().innerHTML.should.equal("<div hx-push-url=\"true\" hx-get=\"/test\">second</div>")
getWorkArea().textContent.should.equal("second")
history.back();
setTimeout(function(){
getWorkArea().innerHTML.should.be.equal("<div hx-push-url=\"true\" hx-get=\"/test\">first</div>");
getWorkArea().textContent.should.equal("first");
done();
}, 20);
})
});
it("should handle two forward clicks then back twice", function (done) {
var i = 0;
@ -37,22 +37,22 @@ describe("HTMx History Tests", function() {
xhr.respond(200, {}, "" + i);
});
getWorkArea().innerHTML.should.be.equal("");
var div = make('<div hx-push-url="true" hx-get="/test">0</div>');
getWorkArea().innerHTML.should.equal("");
var div = make('<div hx-push-url="true" hx-get="/test" class="">0</div>');
div.click();
this.server.respond();
getWorkArea().innerHTML.should.be.equal("<div hx-push-url=\"true\" hx-get=\"/test\">1</div>")
getWorkArea().textContent.should.equal("1")
div.click();
this.server.respond();
getWorkArea().innerHTML.should.be.equal("<div hx-push-url=\"true\" hx-get=\"/test\">2</div>")
getWorkArea().textContent.should.equal("2")
history.back();
setTimeout(function(){
getWorkArea().innerHTML.should.be.equal("<div hx-push-url=\"true\" hx-get=\"/test\">1</div>");
getWorkArea().textContent.should.equal("1");
history.back();
setTimeout(function(){
getWorkArea().innerHTML.should.be.equal("<div hx-push-url=\"true\" hx-get=\"/test\">0</div>");
getWorkArea().textContent.should.equal("0");
done();
}, 20);
}, 20);
@ -61,20 +61,20 @@ describe("HTMx History Tests", function() {
it("should handle a back, forward, back button click", function (done) {
this.server.respondWith("GET", "/test", "second");
getWorkArea().innerHTML.should.be.equal("");
var div = make('<div hx-push-url="true" hx-get="/test">first</div>');
getWorkArea().innerHTML.should.equal("");
var div = make('<div hx-push-url="true" hx-get="/test" class="">first</div>');
div.click();
this.server.respond();
getWorkArea().innerHTML.should.be.equal("<div hx-push-url=\"true\" hx-get=\"/test\">second</div>")
getWorkArea().textContent.should.equal("second")
history.back();
setTimeout(function(){
getWorkArea().innerHTML.should.be.equal("<div hx-push-url=\"true\" hx-get=\"/test\">first</div>");
getWorkArea().textContent.should.equal("first");
history.forward();
setTimeout(function() {
getWorkArea().innerHTML.should.be.equal("<div hx-push-url=\"true\" hx-get=\"/test\">second</div>");
getWorkArea().textContent.should.equal("second");
history.back();
setTimeout(function() {
getWorkArea().innerHTML.should.be.equal("<div hx-push-url=\"true\" hx-get=\"/test\">first</div>");
getWorkArea().textContent.should.equal("first");
done();
}, 20);
}, 20);

View File

@ -21,6 +21,7 @@
<script src="ajax.js"></script>
<script src="headers.js"></script>
<script src="classes.js"></script>
<script src="indicators.js"></script>
<script src="history.js"></script>
<script class="mocha-exec">

36
test/indicators.js Normal file
View File

@ -0,0 +1,36 @@
describe("HTMx Indicator Tests", function(){
beforeEach(function() {
this.server = sinon.fakeServer.create();
clearWorkArea();
});
afterEach(function() {
this.server.restore();
clearWorkArea();
});
it('Indicator classes are properly put on element with no explicit indicator', function()
{
this.server.respondWith("GET", "/test", "Clicked!");
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click();
btn.classList.contains("hx-show-indicator").should.equal(true);
this.server.respond();
btn.classList.contains("hx-show-indicator").should.equal(false);
});
it('Indicator classes are properly put on element with explicit indicator', function()
{
this.server.respondWith("GET", "/test", "Clicked!");
var btn = make('<button hx-get="/test" hx-indicator="#a1, #a2">Click Me!</button>')
var a1 = make('<a id="a1"></a>')
var a2 = make('<a id="a2"></a>')
btn.click();
btn.classList.contains("hx-show-indicator").should.equal(false);
a1.classList.contains("hx-show-indicator").should.equal(true);
a2.classList.contains("hx-show-indicator").should.equal(true);
this.server.respond();
btn.classList.contains("hx-show-indicator").should.equal(false);
a1.classList.contains("hx-show-indicator").should.equal(false);
a2.classList.contains("hx-show-indicator").should.equal(false);
});
})

View File

@ -4,6 +4,18 @@
<title>Scratch File</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
<style>
.indicator {
opacity: 0;
transition: all 200ms ease-in;
}
.hx-show-indicator .indicator {
opacity: 100%;
}
body {
background-color: #6272a4;
}
</style>
</head>
<body>
<script src="../node_modules/sinon/pkg/sinon.js"></script>
@ -11,16 +23,15 @@
<script>
var server = sinon.fakeServer.create();
server.autoRespond = true;
server.respondWith("GET", "/test", "<li>FOO</li>");
</script>
<em>Work Area</em>
<button onclick="server.respond()">Server Respond</button><em>Work Area</em>
<hr/>
<div id="work-area" class="hx-history-element">
<ul hx-get="/test" hx-swap="append" hx-trigger="every 1s">
</ul>
<button hx-indicator="#work-area" hx-get="/test">Click Me</button>
<img src="spinning-circles.svg" class="indicator">
</div>
</body>
</html>