should find properly1ms ‣
var div = make("<div id='d1' class='c1 c2'>")
div.should.equal(htmx.find('#d1'))
div.should.equal(htmx.find('.c1'))
div.should.equal(htmx.find('.c2'))
div.should.equal(htmx.find('.c1.c2'))
should find properly from elt0ms ‣
var div = make("<div><a id='a1'></a><a id='a2'></a></div>")
htmx.find(div, 'a').id.should.equal('a1')
should find all properly0ms ‣
var div = make("<div class='c1 c2 c3'><div class='c1 c2'><div class='c1'>")
htmx.findAll('.c1').length.should.equal(3)
htmx.findAll('.c2').length.should.equal(2)
htmx.findAll('.c3').length.should.equal(1)
should find all properly from elt0ms ‣
var div = make("<div><div class='c1 c2 c3'><div class='c1 c2'><div class='c1'></div>")
htmx.findAll(div, '.c1').length.should.equal(3)
htmx.findAll(div, '.c2').length.should.equal(2)
htmx.findAll(div, '.c3').length.should.equal(1)
should find closest element properly1ms ‣
var div = make("<div><a id='a1'></a><a id='a2'></a></div>")
var a = htmx.find(div, 'a')
htmx.closest(a, 'div').should.equal(div)
should remove element properly1ms ‣
var div = make('<div><a></a></div>')
var a = htmx.find(div, 'a')
htmx.remove(a)
div.innerHTML.should.equal('')
should remove element properly w/ selector1ms ‣
var div = make("<div><a id='a1'></a></div>")
var a = htmx.find(div, 'a')
htmx.remove('#a1')
div.innerHTML.should.equal('')
should add class properly1ms ‣
var div = make('<div></div>')
div.classList.contains('foo').should.equal(false)
htmx.addClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
should add class properly w/ selector0ms ‣
var div = make("<div id='div1'></div>")
div.classList.contains('foo').should.equal(false)
htmx.addClass('#div1', 'foo')
div.classList.contains('foo').should.equal(true)
should add class properly after delay48ms ‣
var div = make('<div></div>')
div.classList.contains('foo').should.equal(false)
htmx.addClass(div, 'foo', 10)
div.classList.contains('foo').should.equal(false)
setTimeout(function() {
div.classList.contains('foo').should.equal(true)
done()
}, 20)
should remove class properly1ms ‣
var div = make('<div></div>')
htmx.addClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
htmx.removeClass(div, 'foo')
div.classList.contains('foo').should.equal(false)
should remove class properly w/ selector3ms ‣
var div = make("<div id='div1'></div>")
htmx.addClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
htmx.removeClass('#div1', 'foo')
div.classList.contains('foo').should.equal(false)
should add class properly after delay20ms ‣
var div = make('<div></div>')
htmx.addClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
htmx.removeClass(div, 'foo', 10)
div.classList.contains('foo').should.equal(true)
setTimeout(function() {
div.classList.contains('foo').should.equal(false)
done()
}, 20)
should toggle class properly1ms ‣
var div = make('<div></div>')
div.classList.contains('foo').should.equal(false)
htmx.toggleClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
htmx.toggleClass(div, 'foo')
div.classList.contains('foo').should.equal(false)
should toggle class properly w/ selector0ms ‣
var div = make("<div id='div1'></div>")
div.classList.contains('foo').should.equal(false)
htmx.toggleClass('#div1', 'foo')
div.classList.contains('foo').should.equal(true)
htmx.toggleClass('#div1', 'foo')
div.classList.contains('foo').should.equal(false)
should take class properly2ms ‣
var div1 = make('<div></div>')
var div2 = make('<div></div>')
var div3 = make('<div></div>')
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass(div1, 'foo')
div1.classList.contains('foo').should.equal(true)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass(div2, 'foo')
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(true)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass(div3, 'foo')
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(true)
should take class properly w/ selector1ms ‣
var div1 = make("<div id='div1'></div>")
var div2 = make("<div id='div2'></div>")
var div3 = make("<div id='div3'></div>")
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass('#div1', 'foo')
div1.classList.contains('foo').should.equal(true)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass('#div2', 'foo')
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(true)
div3.classList.contains('foo').should.equal(false)
htmx.takeClass('#div3', 'foo')
div1.classList.contains('foo').should.equal(false)
div2.classList.contains('foo').should.equal(false)
div3.classList.contains('foo').should.equal(true)
eval can be suppressed1ms ‣
var calledEvent = false
var handler = htmx.on('htmx:evalDisallowedError', function() {
calledEvent = true
})
try {
htmx.config.allowEval = false
should.equal(htmx._('tokenizeString'), undefined)
} finally {
htmx.config.allowEval = true
htmx.off('htmx:evalDisallowedError', handler)
}
calledEvent.should.equal(true)
ajax api works9ms ‣
this.server.respondWith('GET', '/test', 'foo!')
var div = make('<div></div>')
htmx.ajax('GET', '/test', div)
this.server.respond()
div.innerHTML.should.equal('foo!')
ajax api works by ID1ms ‣
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!')
ajax api does not fall back to body when target invalid1ms ‣
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', '#d2')
this.server.respond()
document.body.innerHTML.should.not.equal('foo!')
ajax api fails when target invalid0ms ‣
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', '#d2').then(
(value) => {
},
(reason) => {
done()
}
)
this.server.respond()
div.innerHTML.should.equal('')
ajax api fails when target invalid even if source set1ms ‣
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', {
source: div,
target: '#d2'
}).then(
(value) => {
},
(reason) => {
done()
}
)
this.server.respond()
div.innerHTML.should.equal('')
ajax api fails when source invalid and no target set1ms ‣
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', {
source: '#d2'
}).then(
(value) => {
},
(reason) => {
done()
}
)
this.server.respond()
div.innerHTML.should.equal('')
ajax api falls back to targeting source if target not set2ms ‣
this.server.respondWith('GET', '/test', 'foo!')
var div = make("<div id='d1'></div>")
htmx.ajax('GET', '/test', {
source: div
})
this.server.respond()
div.innerHTML.should.equal('foo!')
ajax api works with swapSpec2ms ‣
this.server.respondWith('GET', '/test', "<p class='test'>foo!</p>")
var div = make("<div><div id='target'></div></div>")
htmx.ajax('GET', '/test', { target: '#target', swap: 'outerHTML' })
this.server.respond()
div.innerHTML.should.equal('<p class="test">foo!</p>')
ajax api works with select2ms ‣
this.server.respondWith('GET', '/test', "<div id='d1'>foo</div><div id='d2'>bar</div>")
var div = make("<div id='target'></div>")
htmx.ajax('GET', '/test', { target: '#target', select: '#d2' })
this.server.respond()
div.innerHTML.should.equal('<div id="d2">bar</div>')
ajax api works with Hx-Select overrides select1ms ‣
this.server.respondWith('GET', '/test', [200, { 'HX-Reselect': '#d2' }, "<div id='d1'>foo</div><div id='d2'>bar</div>"])
var div = make("<div id='target'></div>")
htmx.ajax('GET', '/test', { target: '#target', select: '#d1' })
this.server.respond()
div.innerHTML.should.equal('<div id="d2">bar</div>')
ajax returns a promise2ms ‣
if (typeof Promise !== 'undefined') {
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()
})
} else {
done()
}
ajax api can pass parameters2ms ‣
this.server.respondWith('POST', '/test', function(xhr) {
var params = getParameters(xhr)
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make("<div id='d1'></div>")
htmx.ajax('POST', '/test', { target: '#d1', values: { i1: 'test' } })
this.server.respond()
div.innerHTML.should.equal('Clicked!')
ajax api Content-Type header is application/x-www-form-urlencoded1ms ‣
this.server.respondWith('POST', '/test', function(xhr) {
var params = getParameters(xhr)
xhr.requestHeaders['Content-Type'].should.equal('application/x-www-form-urlencoded;charset=utf-8')
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make("<div id='d1'></div>")
htmx.ajax('POST', '/test', { target: '#d1', values: { i1: 'test' } })
this.server.respond()
div.innerHTML.should.equal('Clicked!')
ajax api Content-Type header override to application/json1ms ‣
this.server.respondWith('POST', '/test', function(xhr) {
var params = getParameters(xhr)
xhr.requestHeaders['Content-Type'].should.equal('application/json;charset=utf-8')
params.i1.should.equal('test')
xhr.respond(200, {}, 'Clicked!')
})
var div = make("<div id='d1'></div>")
htmx.ajax('POST', '/test', {
target: '#d1',
swap: 'innerHTML',
headers: {
'Content-Type': 'application/json'
},
values: { i1: 'test' }
})
this.server.respond()
div.innerHTML.should.equal('Clicked!')
can re-init with new attributes4ms ‣
this.server.respondWith('PATCH', '/test', 'patch')
this.server.respondWith('DELETE', '/test', 'delete')
var div = make('<div hx-patch="/test">click me</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('patch')
div.removeAttribute('hx-patch')
div.setAttribute('hx-delete', '/test')
htmx.process(div)
div.click()
this.server.respond()
div.innerHTML.should.equal('delete')
does not trigger load on re-init of an existing element3ms ‣
this.server.respondWith('GET', '/test', 'test')
var div = make('<div hx-get="/test" hx-trigger="load" hx-swap="beforeend"></div>')
this.server.respond()
div.innerHTML.should.equal('test')
div.setAttribute('hx-swap', 'afterbegin')
htmx.process(div)
this.server.respond()
div.innerHTML.should.equal('test')
onLoad is called... onLoad2ms ‣
this.server.respondWith('GET', '/test', "<div id='d1' hx-get='/test'></div>")
var helper = htmx.onLoad(function(elt) {
elt.setAttribute('foo', 'bar')
})
try {
var div = make("<div id='d1' hx-get='/test' hx-swap='outerHTML'></div>")
div.click()
this.server.respond()
byId('d1').getAttribute('foo').should.equal('bar')
htmx.off('htmx:load', helper)
} catch (error) {
htmx.off('htmx:load', helper)
throw error
}
triggers properly1ms ‣
var div = make('<div/>')
var myEventCalled = false
var detailStr = ''
htmx.on('myEvent', function(evt) {
myEventCalled = true
detailStr = evt.detail.str
})
htmx.trigger(div, 'myEvent', { str: 'foo' })
myEventCalled.should.equal(true)
detailStr.should.equal('foo')
triggers properly w/ selector1ms ‣
var div = make("<div id='div1'/>")
var myEventCalled = false
var detailStr = ''
htmx.on('myEvent', function(evt) {
myEventCalled = true
detailStr = evt.detail.str
})
htmx.trigger('#div1', 'myEvent', { str: 'foo' })
myEventCalled.should.equal(true)
detailStr.should.equal('foo')
triggers with no details properly1ms ‣
var div = make('<div/>')
var myEventCalled = false
htmx.on('myEvent', function(evt) {
myEventCalled = true
})
htmx.trigger(div, 'myEvent')
myEventCalled.should.equal(true)
swaps content properly (basic)1ms ‣
var output = make('<output id="output"/>')
htmx.swap('#output', '<div>Swapped!</div>', { swapStyle: 'innerHTML' })
output.innerHTML.should.be.equal('<div>Swapped!</div>')
swaps content properly (with select)1ms ‣
var output = make('<output id="output"/>')
htmx.swap('#output', '<div><p id="select-me">Swapped!</p></div>', { swapStyle: 'innerHTML' }, { select: '#select-me' })
output.innerHTML.should.be.equal('<p id="select-me">Swapped!</p>')
swaps content properly (with oob)1ms ‣
var output = make('<output id="output"/>')
var oobDiv = make('<div id="oob"/>')
htmx.swap('#output', '<div id="oob" hx-swap-oob="innerHTML">OOB Swapped!</div><div>Swapped!</div>', { swapStyle: 'innerHTML' })
output.innerHTML.should.be.equal('<div>Swapped!</div>')
oobDiv.innerHTML.should.be.equal('OOB Swapped!')
swaps content properly (with select oob)1ms ‣
var output = make('<output id="output"/>')
var oobDiv = make('<div id="oob"/>')
htmx.swap('#output', '<div id="oob">OOB Swapped!</div><div>Swapped!</div>', { swapStyle: 'innerHTML' }, { selectOOB: '#oob:innerHTML' })
output.innerHTML.should.be.equal('<div>Swapped!</div>')
oobDiv.innerHTML.should.be.equal('OOB Swapped!')
swap delete works when parent is removed1ms ‣
this.server.respondWith('DELETE', '/test', 'delete')
var parent = make('<div><div id="d1" hx-swap="delete" hx-delete="/test">click me</div></div>')
var div = htmx.find(parent, '#d1')
div.click()
div.remove()
parent.remove()
this.server.respond()
parent.children.length.should.equal(0)
swap outerHTML works when parent is removed1ms ‣
this.server.respondWith('GET', '/test', 'delete')
var parent = make('<div><div id="d1" hx-swap="outerHTML" hx-get="/test">click me</div></div>')
var div = htmx.find(parent, '#d1')
div.click()
div.remove()
parent.remove()
this.server.respond()
parent.children.length.should.equal(0)