Version: 2.0.4
htmx._('makeFragment')('<html></html>').children.length.should.equal(0)
htmx._('makeFragment')('<html><body></body></html>').children.length.should.equal(0)
// NB - the tag name should be the *parent* element hosting the HTML since we use the fragment children
// for the swap
htmx._('makeFragment')('<td></td>').firstElementChild.tagName.should.equal('TD')
htmx._('makeFragment')('<thead></thead>').firstElementChild.tagName.should.equal('THEAD')
htmx._('makeFragment')('<col></col>').firstElementChild.tagName.should.equal('COL')
htmx._('makeFragment')('<tr></tr>').firstElementChild.tagName.should.equal('TR')
htmx._('makeFragment')('<html></html>').children.length.should.equal(0)
htmx._('makeFragment')('<html><body></body></html>').children.length.should.equal(0)
var fragment = htmx._('makeFragment')('<td></td>')
fragment.firstElementChild.tagName.should.equal('TD')
fragment = htmx._('makeFragment')('<thead></thead>')
fragment.firstElementChild.tagName.should.equal('THEAD')
fragment = htmx._('makeFragment')('<col></col>')
fragment.firstElementChild.tagName.should.equal('COL')
fragment = htmx._('makeFragment')('<tr></tr>')
fragment.firstElementChild.tagName.should.equal('TR')
htmx.config.useTemplateFragments = true
try {
var fragment = htmx._('makeFragment')('<td></td><div></div>')
fragment.children[0].tagName.should.equal('TD')
fragment.children[1].tagName.should.equal('DIV')
} finally {
htmx.config.useTemplateFragments = false
}
var xhr = new XMLHttpRequest()
xhr.open('GET', '/dummy')
htmx._('safelySetHeaderValue')(xhr, 'Example', 'привет')
// unfortunately I can't test the value :/
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
chai.expect(htmx.parseInterval('1ms')).to.be.equal(1)
chai.expect(htmx.parseInterval('300ms')).to.be.equal(300)
chai.expect(htmx.parseInterval('1s')).to.be.equal(1000)
chai.expect(htmx.parseInterval('1.5s')).to.be.equal(1500)
chai.expect(htmx.parseInterval('2s')).to.be.equal(2000)
chai.expect(htmx.parseInterval('0ms')).to.be.equal(0)
chai.expect(htmx.parseInterval('0s')).to.be.equal(0)
chai.expect(htmx.parseInterval('0m')).to.be.equal(0)
chai.expect(htmx.parseInterval('0')).to.be.equal(0)
chai.expect(htmx.parseInterval('5')).to.be.equal(5)
chai.expect(htmx.parseInterval(null)).to.be.undefined
chai.expect(htmx.parseInterval('')).to.be.undefined
chai.expect(htmx.parseInterval('undefined')).to.be.undefined
chai.expect(htmx.parseInterval('true')).to.be.undefined
chai.expect(htmx.parseInterval('false')).to.be.undefined
chai.expect(htmx._('tokenizeString')('a,')).to.be.deep.equal(['a', ','])
chai.expect(htmx._('tokenizeString')('aa,')).to.be.deep.equal(['aa', ','])
chai.expect(htmx._('tokenizeString')('aa,aa')).to.be.deep.equal(['aa', ',', 'aa'])
chai.expect(htmx._('tokenizeString')('aa.aa')).to.be.deep.equal(['aa', '.', 'aa'])
var anchorThatShouldCancel = make("<a href='/foo'></a>")
htmx._('shouldCancel')({ type: 'click' }, anchorThatShouldCancel).should.equal(true)
anchorThatShouldCancel = make("<a href='#'></a>")
htmx._('shouldCancel')({ type: 'click' }, anchorThatShouldCancel).should.equal(true)
var anchorThatShouldNotCancel = make("<a href='#foo'></a>")
htmx._('shouldCancel')({ type: 'click' }, anchorThatShouldNotCancel).should.equal(false)
var form = make('<form></form>')
htmx._('shouldCancel')({ type: 'submit' }, form).should.equal(true)
form = make("<form><input id='i1' type='submit'></form>")
var input = byId('i1')
htmx._('shouldCancel')({ type: 'click' }, input).should.equal(true)
form = make("<form><button id='b1' type='submit'></form>")
var button = byId('b1')
htmx._('shouldCancel')({ type: 'click' }, button).should.equal(true)
form = make("<form id='f1'></form><input id='i1' form='f1' type='submit'><button id='b1' form='f1' type='submit'>")
input = byId('i1')
button = byId('b1')
htmx._('shouldCancel')({ type: 'click' }, input).should.equal(true)
htmx._('shouldCancel')({ type: 'click' }, button).should.equal(true)
make("<div foo='1'><div foo='2'><div foo='unset' id='d1'></div></div></div>")
var div = byId('d1')
should.equal(undefined, htmx._('getClosestAttributeValue')(div, 'foo'))
make("<div foo='1'><div foo='unset'><div id='d1'></div></div></div>")
var div = byId('d1')
should.equal(undefined, htmx._('getClosestAttributeValue')(div, 'foo'))
make("<div foo='unset'><div foo='2'><div id='d1'></div></div></div>")
var div = byId('d1')
should.equal('2', htmx._('getClosestAttributeValue')(div, 'foo'))
var form = make("<form enctype='multipart/form-data'></form>")
var value = htmx._('encodeParamsForBody')(null, form, {});
(value instanceof FormData).should.equal(true)
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'))
var div = make("<div><a id='a1'></a><a id='a2'></a></div>")
htmx.find(div, 'a').id.should.equal('a1')
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)
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)
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)
var div = make('<div><a></a></div>')
var a = htmx.find(div, 'a')
htmx.remove(a)
div.innerHTML.should.equal('')
var div = make("<div><a id='a1'></a></div>")
var a = htmx.find(div, 'a')
htmx.remove('#a1')
div.innerHTML.should.equal('')
var div = make('<div></div>')
div.classList.contains('foo').should.equal(false)
htmx.addClass(div, 'foo')
div.classList.contains('foo').should.equal(true)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
this.server.respondWith('GET', '/test', 'foo!')
var div = make('<div></div>')
htmx.ajax('GET', '/test', div)
this.server.respond()
div.innerHTML.should.equal('foo!')
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!')
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!')
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('')
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('')
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('')
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!')
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>')
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>')
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>')
// in IE we do not return a promise
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()
}
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!')
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!')
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!')
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')
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')
// also tests on/off
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) {
// Clean up the event if the test fails, then throw it again
htmx.off('htmx:load', helper)
throw error
}
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')
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')
var div = make('<div/>')
var myEventCalled = false
htmx.on('myEvent', function(evt) {
myEventCalled = true
})
htmx.trigger(div, 'myEvent')
myEventCalled.should.equal(true)
var output = make('<output id="output"/>')
htmx.swap('#output', '<div>Swapped!</div>', { swapStyle: 'innerHTML' })
output.innerHTML.should.be.equal('<div>Swapped!</div>')
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>')
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!')
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!')
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)
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)
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', '<a hx-get="/test2">Click Me</a>')
this.server.respondWith('GET', '/test2', 'Clicked!')
var div = make('<div hx-get="/test"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<a hx-get="/test2">Click Me</a>')
var a = div.querySelector('a')
a.click()
this.server.respond()
a.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', '<a id="a1" hx-get="/test2">Click Me</a>')
this.server.respondWith('GET', '/test2', 'Clicked!')
var div = make('<div id="d1" hx-get="/test" hx-swap="outerHTML"></div>')
div.click()
should.equal(byId('d1'), div)
this.server.respond()
should.equal(byId('d1'), null)
byId('a1').click()
this.server.respond()
byId('a1').innerHTML.should.equal('Clicked!')
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>')
})
this.server.respondWith('GET', '/test2', '*')
var div = make('<div hx-get="/test" hx-swap="beforebegin">*</div>')
var parent = div.parentElement
div.click()
this.server.respond()
div.innerText.should.equal('*')
removeWhiteSpace(parent.innerText).should.equal('1*')
byId('a1').click()
this.server.respond()
removeWhiteSpace(parent.innerText).should.equal('**')
div.click()
this.server.respond()
div.innerText.should.equal('*')
removeWhiteSpace(parent.innerText).should.equal('*2*')
byId('a2').click()
this.server.respond()
removeWhiteSpace(parent.innerText).should.equal('***')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="afterbegin">*</div>')
div.click()
this.server.respond()
div.innerText.should.equal('1*')
div.click()
this.server.respond()
div.innerText.should.equal('21*')
div.click()
this.server.respond()
div.innerText.should.equal('321*')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="afterbegin"></div>')
div.click()
this.server.respond()
div.innerText.should.equal('1')
div.click()
this.server.respond()
div.innerText.should.equal('21')
div.click()
this.server.respond()
div.innerText.should.equal('321')
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>')
})
this.server.respondWith('GET', '/test2', '*')
var div = make('<div hx-get="/test" hx-swap="afterend">*</div>')
var parent = div.parentElement
div.click()
this.server.respond()
div.innerText.should.equal('*')
removeWhiteSpace(parent.innerText).should.equal('*1')
byId('a1').click()
this.server.respond()
removeWhiteSpace(parent.innerText).should.equal('**')
div.click()
this.server.respond()
div.innerText.should.equal('*')
removeWhiteSpace(parent.innerText).should.equal('*2*')
byId('a2').click()
this.server.respond()
removeWhiteSpace(parent.innerText).should.equal('***')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="beforeend">*</div>')
div.click()
this.server.respond()
div.innerText.should.equal('*1')
div.click()
this.server.respond()
div.innerText.should.equal('*12')
div.click()
this.server.respond()
div.innerText.should.equal('*123')
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('<div hx-get="/test" hx-swap="beforeend"></div>')
div.click()
this.server.respond()
div.innerText.should.equal('1')
div.click()
this.server.respond()
div.innerText.should.equal('12')
div.click()
this.server.respond()
div.innerText.should.equal('123')
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('<button hx-get="/test" hx-target="#s1">Click Me!</button>')
var target = make('<span id="s1">Initial</span>')
btn.click()
target.innerHTML.should.equal('Initial')
this.server.respond()
target.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', [204, {}, 'No Content!'])
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
btn.innerHTML.should.equal('Click Me!')
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
this.server.respondWith('GET', '/test-1', [200, {}, 'Content for Tab 1'])
this.server.respondWith('GET', '/test-2', [200, {}, 'Content for Tab 2'])
var target = make('<div id="target"></div>')
var btn1 = make('<button hx-get="/test-1" hx-target="#target">Tab 1</button>')
var btn2 = make('<button hx-get="/test-2" hx-target="#target">Tab 2</button>')
btn1.click()
target.innerHTML.should.equal('')
this.server.respond()
target.innerHTML.should.equal('Content for Tab 1')
btn2.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 2')
this.server.respondWith('GET', '/test-1', [304, {}, 'Content for Tab 1'])
this.server.respondWith('GET', '/test-2', [304, {}, 'Content for Tab 2'])
btn1.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 1')
btn2.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 2')
this.server.respondWith('GET', '/test', 'Clicked!')
var form = make('<form hx-get="/test" hx-trigger="click">Click Me!</form>')
form.click()
form.innerHTML.should.equal('Click Me!')
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', 'Loaded!')
var div = make('<div hx-get="/test" hx-trigger="load">Load Me!</div>')
div.innerHTML.should.equal('Load Me!')
this.server.respond()
div.innerHTML.should.equal('Loaded!')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'done')
xhr.overriddenMimeType.should.equal('text/html')
done()
})
var div = make('<div hx-get="/test">Click Me!</div>')
div.click()
this.server.respond()
var i = 1
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'click ' + i)
i++
})
var div = make('<div hx-get="/test"></div>')
div.click()
div.click()
this.server.respond()
div.innerHTML.should.equal('click 1')
this.server.respond()
div.innerHTML.should.equal('click 2')
var i = 1
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'click ' + i)
i++
})
var div = make('<div hx-get="/test"></div>')
div.click()
div.click()
div.click()
this.server.respondAll()
div.innerHTML.should.equal('click 2')
var i = 1
this.server.respondWith('GET', '/test', "<div id='d1'>foo</div><div id='d2'>bar</div>")
var div = make('<div hx-get="/test" hx-select="#d1"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<div id="d1">foo</div>')
this.server.respondWith('GET', '/test', "<html><body><div id='d1'>foo</div><div id='d2'>bar</div></body></html>")
var div = make('<div hx-get="/test" hx-select="#d1"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<div id="d1">foo</div>')
this.server.respondWith('GET', '/test', "<div hx-get='/test'><div width='bar' id='d1'></div></div>")
var div = make("<div hx-get='/test' hx-swap='outerHTML settle:10ms'><div id='d1'></div></div>")
div.click()
this.server.respond()
should.equal(byId('d1').getAttribute('width'), null)
setTimeout(function() {
should.equal(byId('d1').getAttribute('width'), 'bar')
done()
}, 20)
this.server.respondWith('GET', '/test', "<div hx-get='/test'><div width='bar' id=\"d1'\"></div></div>")
var div = make("<div hx-get='/test' hx-swap='outerHTML settle:10ms'><div id=\"d1'\"></div></div>")
div.click()
this.server.respond()
should.equal(byId("d1'").getAttribute('width'), null)
setTimeout(function() {
should.equal(byId("d1'").getAttribute('width'), 'bar')
done()
}, 20)
this.server.respondWith('GET', '/test', "<div hx-get='/test'><div width='bar' id='d1\"'></div></div>")
var div = make("<div hx-get='/test' hx-swap='outerHTML settle:10ms'><div id='d1\"'></div></div>")
div.click()
this.server.respond()
should.equal(byId('d1"').getAttribute('width'), null)
setTimeout(function() {
should.equal(byId('d1"').getAttribute('width'), 'bar')
done()
}, 20)
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<select id="multiSelect" name="multiSelect" multiple="multiple">' +
'<option id="m1" value="m1">m1</option>' +
'<option id="m2" value="m2">m2</option>' +
'<option id="m3" value="m3">m3</option>' +
'<option id="m4" value="m4">m4</option>' +
'</select>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<select name="multiSelect" id="id_question_list" multiple="" tabindex="-1" aria-hidden="true">' +
'<option id="m1" value="m1">m1</option>' +
'<option id="m2" value="m2">m2</option>' +
'<option id="m3" value="m3">m3</option>' +
'<option id="m4" value="m4">m4</option>' +
'</select>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<select id="multiSelect" name="multiSelect" multiple="multiple">' +
'<option id="m1" value="m1">m1</option>' +
'<option id="m2" value="m2">m2</option>' +
'<option id="m3" value="m3">m3</option>' +
'<option id="m4" value="m4">m4</option>' +
'</select>' +
'<select id="multiSelect" name="multiSelect" multiple="multiple">' +
'<option id="m5" value="m5">m1</option>' +
'<option id="m6" value="m6">m2</option>' +
'<option id="m7" value="m7">m3</option>' +
'<option id="m8" value="m8">m4</option>' +
'</select>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
byId('m7').selected = true
byId('m8').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3', 'm7', 'm8'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<input id="multiEmail" name="multiEmail" multiple>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: '' })
byId('multiEmail').value = 'foo@example.com'
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: 'foo@example.com' })
byId('multiEmail').value = 'foo@example.com,bar@example.com'
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: 'foo@example.com,bar@example.com' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<input id="cb1" name="c1" value="cb1" type="checkbox">' +
'<input id="cb2" name="c1" value="cb2" type="checkbox">' +
'<input id="cb3" name="c1" value="cb3" type="checkbox">' +
'<input id="cb4" name="c2" value="cb4" type="checkbox">' +
'<input id="cb5" name="c2" value="cb5" type="checkbox">' +
'<input id="cb6" name="c3" value="cb6" type="checkbox">' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('cb1').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: 'cb1' })
byId('cb1').checked = true
byId('cb2').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: 'cb4' })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
byId('cb5').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: ['cb4', 'cb5'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
byId('cb5').checked = true
byId('cb6').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: ['cb4', 'cb5'], c3: 'cb6' })
byId('cb1').checked = true
byId('cb2').checked = false
byId('cb3').checked = true
byId('cb4').checked = false
byId('cb5').checked = true
byId('cb6').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb3'], c2: 'cb5', c3: 'cb6' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('<form hx-post="/test" hx-trigger="click">' +
'<div role="radiogroup">' +
'<input id="rb1" name="r1" value="rb1" type="radio">' +
'<input id="rb2" name="r1" value="rb2" type="radio">' +
'<input id="rb3" name="r1" value="rb3" type="radio">' +
'<input id="rb4" name="r2" value="rb4" type="radio">' +
'<input id="rb5" name="r2" value="rb5" type="radio">' +
'<input id="rb6" name="r3" value="rb6" type="radio">' +
'</div>' +
'</form>')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('rb1').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ r1: 'rb1' })
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()
this.server.respond()
byId('d1').click()
this.server.respond()
byId('d1').innerHTML.should.equal('clicked')
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<div></div><script type='text/javascript'>callGlobal()</script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<script type='text/javascript'>callGlobal()</script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
try {
window.foo = {}
this.server.respondWith('GET', '/test', "<script type='text/javascript'>foo.bar = function() { return 42 }</script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
foo.bar().should.equal(42)
} finally {
delete window.foo
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<div><script type='text/javascript'>callGlobal()</script></div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<script type='text/javascript'>callGlobal()</script><div></div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', '<div><script>callGlobal()</script></div>')
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "<div><script type='text/samplescript'>callGlobal()</script></div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
globalWasCalled.should.equal(false)
} finally {
delete window.callGlobal
}
window.callGlobal = function() {
console.log('Here...')
window.tempVal = byId('d1').innerText
}
try {
this.server.respondWith('GET', '/test', "<div><script>callGlobal()</script><div id='d1'>After settle...</div> </div>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
window.tempVal.should.equal('After settle...')
} finally {
delete window.callGlobal
delete window.tempVal
}
var path = null
var div = make("<div hx-get=''/>")
htmx.on(div, 'htmx:configRequest', function(evt) {
path = evt.detail.path
return false
})
div.click()
this.server.respond()
path.should.not.be.null
var path = null
var div = make('<div hx-get/>')
htmx.on(div, 'htmx:configRequest', function(evt) {
path = evt.detail.path
return false
})
div.click()
this.server.respond()
path.should.not.be.null
this.server.respondWith('GET', '/test', "<input id='i1' value='bar'/>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='outerHTML settle:50' hx-trigger='click'/>")
input.click()
this.server.respond()
input = byId('i1')
input.value.should.equal('bar')
this.server.respondWith('GET', '/test', "<input id='i2' value='bar' autofocus/>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='afterend' hx-trigger='click'/>")
input.focus()
input.click()
document.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
document.activeElement.should.equal(input2)
this.server.respondWith('GET', '/test', "<div><input id='i2' value='bar' autofocus/></div>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='afterend' hx-trigger='click'/>")
input.focus()
input.click()
document.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
document.activeElement.should.equal(input2)
this.server.respondWith('GET', '/test', "<div><input id='i2' value='bar' autofocus='true'/></div>")
var input = make("<input id='i1' hx-get='/test' value='foo' hx-swap='afterend' hx-trigger='click'/>")
input.focus()
input.click()
document.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
document.activeElement.should.equal(input2)
this.server.respondWith('POST', '/test', function(xhr) {
should.equal(xhr.requestHeaders['Content-Type'], undefined)
if (xhr.requestBody.get) { // IE 11 does not support
xhr.requestBody.get('i1').should.equal('foo')
}
xhr.respond(200, {}, 'body: ' + xhr.requestBody)
})
var form = make("<form hx-post='/test' hx-encoding='multipart/form-data' hx-trigger='click'>" +
"<input name='i1' id='i1' value='foo'/>" +
'</form>')
form.focus()
form.click()
this.server.respond()
var count = 0
this.server.respondWith('GET', '/test', function(xhr) {
count++
xhr.respond(200, {}, '')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
htmx.remove(btn)
btn.click()
this.server.respond()
count.should.equal(0)
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "<title class=''>htmx rocks!</title>Clicked!")
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal('htmx rocks!')
var originalTitle = window.document.title
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "<svg class=''><title>" + originalTitle + 'UPDATE' + '</title></svg>Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal(originalTitle)
var originalTitle = window.document.title
var newTitle = originalTitle + '!!!'
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "<title class=''>" + newTitle + "</title><svg class=''><title>foo</title></svg>Clicked!<title class=''>x</title>")
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal(newTitle)
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, '<title></> htmx rocks!</title>Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal('</> htmx rocks!')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Click Me!')
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
htmx.off('htmx:beforeSwap', handler)
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
event.detail.target = byId('d1')
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
var div = make('<div id="d1"></div>')
btn.click()
this.server.respond()
div.innerText.should.equal('Clicked!')
htmx.off('htmx:beforeSwap', handler)
var errors = 0
var handler = htmx.on('htmx:responseError', function() {
errors++
})
this.server.respondWith('GET', '/test1', function(xhr) {
xhr.respond(204, {}, 'Clicked!')
})
this.server.respondWith('GET', '/test2', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn1 = make('<button hx-get="/test1">Click Me!</button>')
var btn2 = make('<button hx-get="/test2">Click Me!</button>')
btn1.click()
btn2.click()
this.server.respond()
this.server.respond()
errors.should.equal(1)
htmx.off('htmx:responseError', handler)
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
event.detail.serverResponse = event.detail.serverResponse + '!!'
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!!!')
htmx.off('htmx:beforeSwap', handler)
try {
this.server.respondWith('GET', '/test', "<script id='setGlobalScript' src='setGlobal.js'></script>")
var div = make("<div hx-get='/test'></div>")
div.click()
this.server.respond()
byId('setGlobalScript').addEventListener('load', function() {
window.globalWasCalled.should.equal(true)
delete window.globalWasCalled
done()
})
} finally {
delete window.globalWasCalled
}
this.server.respondWith('GET', '/test', '<with:colon id="foobar">Foobar</with:colon>')
var btn = make('<button hx-get="/test">Give me colons!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('<with:colon id="foobar">Foobar</with:colon>')
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<button id="submit" type="submit" name="b1" value="buttonValue">button</button>' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input id="submit" type="submit" name="b1" value="buttonValue">' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form>' +
'<input type="text" name="t1" value="textValue">' +
'<button id="submit" type="submit" name="b1" value="buttonValue" hx-post="/test">button</button>' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form>' +
'<input type="text" name="t1" value="textValue">' +
'<input id="submit" type="submit" name="b1" value="buttonValue" hx-post="/test">' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'</form>' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'</form>' +
'<input id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="hidden" name="action" value="A">' +
'<button id="btnA" type="submit">A</button>' +
'<button id="btnB" type="submit" name="action" value="B">B</button>' +
'<button id="btnC" type="submit" name="action" value="C">C</button>' +
'</form>')
byId('btnA').click()
this.server.respond()
values.should.deep.equal({ action: 'A' })
byId('btnB').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'B'] })
byId('btnC').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'C'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form hx-post="/test">' +
'<input type="hidden" name="action" value="A">' +
'<input id="btnA" type="submit">A</input>' +
'<input id="btnB" type="submit" name="action" value="B">B</input>' +
'<input id="btnC" type="submit" name="action" value="C">C</input>' +
'</form>')
byId('btnA').click()
this.server.respond()
values.should.deep.equal({ action: 'A' })
byId('btnB').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'B'] })
byId('btnC').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'C'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<form hx-post="/test2">' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<form hx-post="/test2">' +
'<input id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">' +
'</form>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'] })
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('<form id="externalForm" hx-post="/test">' +
' <input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<input type="text" name="t1" value="textValue" form="externalForm">' +
'<select name="s1" form="externalForm">' +
' <option value="someValue"></option>' +
' <option value="selectValue" selected></option>' +
'</select>' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'], s1: 'selectValue' })
var values
this.server.respondWith('POST', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(200, {}, '')
})
make('<dialog><form hx-post="/test"><button id="submit" formmethod="dialog" name="foo" value="bar">submit</button></form></dialog>')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ foo: 'bar' })
var responded = false
this.server.respondWith('GET', '/test', function(xhr) {
responded = true
xhr.respond(200, {}, '')
})
make('<dialog><form hx-get="/test"><button id="submit" formmethod="dialog">submit</button></form></dialog>')
byId('submit').click()
this.server.respond()
responded.should.equal(true)
const template = '<form ' +
'id="hello" ' +
'hx-target="#hello" ' +
'hx-select="#hello" ' +
'hx-swap="outerHTML" ' +
'hx-post="/test">\n' +
'<input id="input" type="text" name="name" />\n' +
'<button name="value" type="submit">Submit</button>\n' +
'</form>\n' +
'<button id="outside" name="outside" form="hello" type="submit">Outside</button>'
var values
this.server.respondWith('/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(200, {}, template)
})
make(template)
const button = byId('outside')
button.focus()
button.click()
this.server.respond()
values.should.deep.equal({ name: '', outside: '' })
button.focus()
button.click()
this.server.respond()
values.should.deep.equal({ name: '', outside: '' })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 200 // 200 should cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('200')
responseCode = 204 // 204 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
responseCode = 300 // 300 should cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('300')
responseCode = 400 // 400 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
responseCode = 500 // 500 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
var originalResponseHandling = htmx.config.responseHandling
try {
htmx.config.responseHandling = [{ code: '...', swap: true }]
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 200 // 200 should cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('200')
responseCode = 203 // 203 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('203')
responseCode = 300 // 300 should cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('300')
responseCode = 400 // 400 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('400')
responseCode = 500 // 500 should not cause a swap by default
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('500')
} finally {
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: true, target: '#a-div' })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 444
var div = make('<div id="a-div">Another Div</div>')
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
div.innerHTML.should.equal('444')
} finally {
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: true, target: '#a-div', swapOverride: 'outerHTML' })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 444
var div = make('<div><div id="a-div">Another Div</div></div>')
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
div.innerHTML.should.equal('444')
} finally {
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: true, select: '.foo' })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, "<div><a class='foo'>" + responseCode + '</a></div>')
})
responseCode = 444
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('<a class="foo">444</a>')
} finally {
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
var originalTitle = document.title
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: true, ignoreTitle: true })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '<title>Should Not Be Set</title>' + responseCode)
})
responseCode = 444
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('444')
document.title.should.equal(originalTitle)
} finally {
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
var errorDetected = false
var handler = htmx.on('htmx:responseError', function() {
errorDetected = true
})
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: true, error: false })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 444
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('444')
errorDetected.should.equal(false)
} finally {
htmx.off('htmx:responseError', handler)
htmx.config.responseHandling = originalResponseHandling
}
var originalResponseHandling = htmx.config.responseHandling
var myEventWasTriggered = false
var handler = htmx.on('myEvent', function() {
myEventWasTriggered = true
})
try {
htmx.config.responseHandling = originalResponseHandling.slice()
htmx.config.responseHandling.unshift({ code: '444', swap: false, error: false, event: 'myEvent' })
var responseCode = null
this.server.respondWith('GET', '/test', function(xhr, id) {
xhr.respond(responseCode, { 'Content-Type': 'text/html' }, '' + responseCode)
})
responseCode = 444
var btn = make('<button hx-get="/test">Click Me!</button>')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
myEventWasTriggered.should.equal(true)
} finally {
htmx.off('htmx:responseError', handler)
htmx.config.responseHandling = originalResponseHandling
}
this.server.respondWith('POST', '/test', 'post')
var div = make('<div hx-post="/test">click me</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('post')
this.server.respondWith('PUT', '/test', 'put')
var div = make('<div hx-put="/test">click me</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('put')
this.server.respondWith('PATCH', '/test', 'patch')
var div = make('<div hx-patch="/test">click me</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('patch')
this.server.respondWith('DELETE', '/test', 'delete')
var div = make('<div hx-delete="/test">click me</div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('delete')
var input = make('<input name="foo" value="bar"/>')
var vals = htmx._('getInputValues')(input).values
vals.foo.should.equal('bar')
var input = make('<input name="foo" value="bar"/>')
var vals = htmx._('getInputValues')(input, 'get').values
vals.foo.should.equal('bar')
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/></form>')
var input = byId('i1')
var vals = htmx._('getInputValues')(input).values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/></form>')
var input = byId('i1')
var vals = htmx._('getInputValues')(input, 'get').values
vals.foo.should.equal('bar')
should.equal(vals.do, undefined)
var form = make('<form><div id="d1"/><input id="i2" name="do" value="rey"/></form>')
var div = byId('d1')
var vals = htmx._('getInputValues')(div, 'post').values
vals.do.should.equal('rey')
var form = make('<form><div id="d1"/><input id="i2" name="do" value="rey"/></form>')
var div = byId('d1')
var vals = htmx._('getInputValues')(div, 'get').values
should.equal(vals.do, undefined)
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/></form>')
var vals = htmx._('getInputValues')(form, 'get').values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/></form>')
var vals = htmx._('getInputValues')(form, 'post').values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input id="i2" name="do" value="rey"/></form>')
var vals = htmx._('getInputValues')(form).values
vals.foo.should.equal('bar')
vals.do.should.deep.equal(['rey', 'rey'])
var form = make('<form><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey1"/><input id="i3" name="do" value="rey2"/></form>')
var vals = htmx._('getInputValues')(byId('i3')).values
vals.foo.should.equal('bar')
vals.do.should.deep.equal(['rey1', 'rey2'])
var form = make('<form><input id="i1" name="do" value=""/><input id="i2" name="do" value="rey"/><input id="i3" name="do" value=""/></form>')
var vals = htmx._('getInputValues')(byId('i3')).values
vals.do.should.deep.equal(['', 'rey', ''])
var form = make('<form id="f1"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input id="i2" name="do" value="rey"/></form>')
var div = make('<div hx-include="#f1"></div>')
var vals = htmx._('getInputValues')(div).values
vals.foo.should.equal('bar')
vals.do.should.deep.equal(['rey', 'rey'])
var form = make('<form id="f1"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input id="i2" name="do" value="rey"/></form>')
var div = make('<div hx-include="#i1"></div>')
var vals = htmx._('getInputValues')(div).values
vals.foo.should.equal('bar')
should.equal(vals.do, undefined)
var form = make('<form id="f1"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input id="i2" name="do" value="rey"/></form>')
var div = make('<div hx-include="#i1, #i2"></div>')
var vals = htmx._('getInputValues')(div).values
vals.foo.should.equal('bar')
vals.do.should.deep.equal(['rey', 'rey'])
var form = make('<form id="f1"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input id="i2" name="do" value="rey"/></form>')
var div = make('<div hx-include="#i1, #i2, #f1"></div>')
var vals = htmx._('getInputValues')(div).values
vals.foo.should.equal('bar')
vals.do.should.deep.equal(['rey', 'rey'])
htmx._('urlEncode')({}).should.equal('')
htmx._('urlEncode')({ foo: 'bar' }).should.equal('foo=bar')
htmx._('urlEncode')({ foo: 'bar', do: 'rey' }).should.equal('foo=bar&do=rey')
htmx._('urlEncode')({ foo: 'bar', do: ['rey', 'blah'] }).should.equal('foo=bar&do=rey&do=blah')
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><button id="b1" name="btn" value="bar"></button></form>')
var input = byId('i1')
var button = byId('b1')
// Listen for focusin on form as it'll bubble up from the button, and htmx binds on the form itself
form.addEventListener('focusin', function() {
var vals = htmx._('getInputValues')(form).values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
vals.btn.should.equal('bar')
done()
}, { once: true })
button.focus()
// Headless / Hardly-throttled CPU might result in 'focusin' not being fired, double it just in case
htmx.trigger(button, 'focusin')
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input type="submit" id="s1" name="s1" value="bar"/></form>')
var input = byId('i1')
var button = byId('s1')
// Listen for focusin on form as it'll bubble up from the button, and htmx binds on the form itself
form.addEventListener('focusin', function() {
var vals = htmx._('getInputValues')(form).values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
vals.s1.should.equal('bar')
done()
}, { once: true })
button.focus()
// Headless / Hardly-throttled CPU might result in 'focusin' not being fired, double it just in case
htmx.trigger(button, 'focusin')
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input type="submit" id="s1" name="s1" value="bar"/></form>')
var input = byId('i1')
var button = byId('s1')
button.focus()
input.focus()
var vals = htmx._('getInputValues')(form).values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
should.equal(vals.s1, undefined)
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input type="submit" id="s1" name="s1" value="bar"/></form>')
var anchor = make('<button id="a1"></button>')
var button = byId('s1')
button.focus()
anchor.focus()
var vals = htmx._('getInputValues')(form).values
vals.foo.should.equal('bar')
vals.do.should.equal('rey')
should.equal(vals.s1, undefined)
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><button type="submit" id="btn1" name="do" value="rey"><div id="div1"><span id="span1"></span></div></button></form>')
var nestedElt = byId('span1')
nestedElt.click()
var vals = htmx._('getInputValues')(form).values
vals.do.should.equal('rey')
this.server.respondWith('GET', '/test?i1=value', function(xhr) {
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-get="/test"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestBody.should.equal('i1=value')
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-get="/test"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
try {
htmx.config.methodsThatUseUrlParams = []
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
} finally {
htmx.config.methodsThatUseUrlParams = ['get']
}
this.server.respondWith('DELETE', '/test', function(xhr) {
xhr.requestBody.should.equal('i1=value')
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-delete="/test"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('DELETE', '/test?i1=value', function(xhr) {
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-trigger="click" hx-delete="/test"><input name="i1" value="value"/><button id="b1">Click Me!</button></form>')
try {
htmx.config.methodsThatUseUrlParams.push('delete')
form.click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
} finally {
htmx.config.methodsThatUseUrlParams = ['get']
}
var input = make('<form><input name="foo" value="bar"/><fieldset disabled><input name="do" value="rey"/></fieldset></form>')
var vals = htmx._('getInputValues')(input, 'get').values
vals.foo.should.equal('bar')
should.equal(vals.do, undefined)
// See https://web.dev/articles/more-capable-form-controls
class TestElement extends HTMLElement {
static formAssociated = true
constructor() {
super()
this._form = null
}
formAssociatedCallback(form) {
if (this._form) {
this._form.removeEventListener('formdata', this.handleFormData)
}
this._form = form
this._form.addEventListener('formdata', this.handleFormData)
}
handleFormData({
formData
}) {
formData.append('foo', 'bar')
}
}
customElements.define('test-element', TestElement)
var form = make('<form hx-post="/test"><test-element></test-element></form>')
var vals = htmx._('getInputValues')(form, 'get').values
vals.foo.should.equal('bar')
var form = make('<form hx-post="/test"><input name="foo" value="bar"/></form>')
var vals = htmx._('getInputValues')(form, 'get').values
function updateToNull() { vals.foo = null }
updateToNull.should.not.throw()
vals.foo.should.equal('null')
var form = make('<input name="foo" value="bar"/>')
var vals = htmx._('getInputValues')(form, 'get').values
function makeSearchParams() { return new URLSearchParams(vals).toString() }
makeSearchParams.should.not.throw()
makeSearchParams().should.equal('foo=bar')
this.server.respondWith('GET', '/test?foo=bar&bar=foo&foo=bar&foo2=bar2', function(xhr) {
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-get="/test">' +
'<input name="foo" value="bar">' +
'<input name="bar" value="foo">' +
'<input name="foo" value="bar">' +
'<input name="foo2" value="bar2">' +
'<button id="b1">Click Me!</button>' +
'</form>')
byId('b1').click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/test', function(xhr) {
xhr.requestBody.should.equal('foo=bar&bar=foo&foo=bar&foo2=bar2')
xhr.respond(200, {}, 'Clicked!')
})
var form = make('<form hx-post="/test">' +
'<input name="foo" value="bar">' +
'<input name="bar" value="foo">' +
'<input name="foo" value="bar">' +
'<input name="foo2" value="bar2">' +
'<button id="b1">Click Me!</button>' +
'</form>')
byId('b1').click()
this.server.respond()
form.innerHTML.should.equal('Clicked!')
this.server.respondWith('POST', '/test', function(xhr) {
should.equal(xhr.requestHeaders['Content-Type'], undefined)
const file = xhr.requestBody.get('file')
file.should.instanceOf(File)
file.name.should.equal('test.txt')
xhr.respond(200, {}, 'OK')
})
const form = make('<form hx-post="/test" hx-target="#result" hx-encoding="multipart/form-data">' +
'<input type="file" name="file">' +
'<button type="submit"></button>' +
'</form>')
const input = form.querySelector('input')
const file = new File(['Test'], 'test.txt', { type: 'text/plain' })
const dataTransfer = new DataTransfer()
dataTransfer.items.add(file)
input.files = dataTransfer.files
const result = make('<div id="result"></div>')
form.querySelector('button').click()
this.server.respond()
result.innerHTML.should.equal('OK')
this.server.respondWith('POST', '/test', function(xhr) {
should.equal(xhr.requestHeaders['Content-Type'], undefined)
const file = xhr.requestBody.get('file')
file.should.instanceOf(File)
file.name.should.equal('test.txt')
xhr.respond(200, {}, 'OK')
})
const div = make('<div hx-encoding="multipart/form-data"></div>')
htmx.ajax('POST', '/test', {
source: div,
values: {
file: new File(['Test'], 'test.txt', { type: 'text/plain' })
}
})
this.server.respond()
div.innerHTML.should.equal('OK')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-Request'].should.be.equal('true')
xhr.respond(200, {}, '')
})
var div = make('<div hx-get="/test"></div>')
div.click()
this.server.respond()
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-Trigger'].should.equal('d1')
xhr.respond(200, {}, '')
})
var div = make('<div id="d1" hx-get="/test"></div>')
div.click()
this.server.respond()
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-Trigger-Name'].should.equal('n1')
xhr.respond(200, {}, '')
})
var div = make('<button name="n1" hx-get="/test"></button>')
div.click()
this.server.respond()
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-Target'].should.equal('d1')
xhr.respond(200, {}, '')
})
var div = make('<div hx-target="#d1" hx-get="/test"></div><div id="d1" ></div>')
div.click()
this.server.respond()
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'foo' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'foo.bar' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo.bar', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'hx-trigger': 'foo' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'namespace:foo' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('namespace:foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': '{"foo":null}' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo', function(evt) {
invokedEvent = true
should.equal(null, evt.detail.value)
evt.detail.elt.should.equal(div)
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': '{"foo":[1, 2, 3]}' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo', function(evt) {
invokedEvent = true
evt.detail.elt.should.equal(div)
evt.detail.value.should.deep.equal([1, 2, 3])
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': '{"foo":{"a":1, "b":2}}' }, ''])
var div = make('<div hx-get="/test"></div>')
var invokedEvent = false
div.addEventListener('foo', function(evt) {
invokedEvent = true
evt.detail.elt.should.equal(div)
evt.detail.a.should.equal(1)
evt.detail.b.should.equal(2)
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': '{"foo":{"target":"#testdiv"}}' }, ''])
var div = make('<div hx-get="/test"></div>')
var testdiv = make('<div id="testdiv"></div>')
var invokedEvent = false
testdiv.addEventListener('foo', function(evt) {
invokedEvent = true
evt.detail.elt.should.equal(testdiv)
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': '{not: valid}' }, ''])
var div = make('<div hx-get="/test"></div>')
div.click()
this.server.respond()
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger': 'foo' }, ''])
var div = make('<div hx-swap="outerHTML" hx-get="/test"></div>')
var invokedEvent = false
var handler = htmx.on('foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
htmx.off('foo', handler)
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)
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)
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)
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)
this.server.respondWith('GET', '/test', [200, { 'HX-Retarget': '#d2' }, 'Result'])
var div1 = make('<div id="d1" hx-get="/test"></div>')
var div2 = make('<div id="d2"></div>')
div1.click()
this.server.respond()
div1.innerHTML.should.equal('')
div2.innerHTML.should.equal('Result')
this.server.respondWith('GET', '/test', [200, { 'HX-Reswap': 'innerHTML' }, 'Result'])
var div1 = make('<div id="d1" hx-get="/test" hx-swap="outerHTML"></div>')
div1.click()
this.server.respond()
div1.innerHTML.should.equal('Result')
this.server.respondWith('GET', '/test', [200, { 'HX-Reselect': '#d2' }, "<div id='d1'>foo</div><div id='d2'>bar</div>"])
var div = make('<div hx-get="/test" hx-select="#d1"></div>')
div.click()
this.server.respond()
div.innerHTML.should.equal('<div id="d2">bar</div>')
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger-After-Swap': 'foo' }, ''])
var div = make('<div hx-swap="outerHTML" hx-get="/test"></div>')
var invokedEvent = false
var handler = htmx.on('foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
htmx.off('foo', handler)
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)
this.server.respondWith('GET', '/test', [200, { 'HX-Trigger-After-Settle': 'foo' }, ''])
var div = make('<div hx-swap="outerHTML" hx-get="/test"></div>')
var invokedEvent = false
var handler = htmx.on('foo', function(evt) {
invokedEvent = true
})
div.click()
this.server.respond()
invokedEvent.should.equal(true)
htmx.off('foo', handler)
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)
this.server.respondWith('GET', '/test', [200, { 'HX-Location': '{"path":"/test2", "target":"#testdiv"}' }, ''])
this.server.respondWith('GET', '/test2', [200, {}, '<div>Yay! Welcome</div>'])
var div = make('<div id="testdiv" hx-trigger="click" hx-get="/test"></div>')
div.click()
this.server.respond()
this.server.respond()
div.innerHTML.should.equal('<div>Yay! Welcome</div>')
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-Request'].should.be.equal('true')
xhr.respond(200, {}, '')
})
htmx._('loadHistoryFromServer')('/test')
this.server.respond()
this.server.respondWith('GET', '/test', function(xhr) {
xhr.requestHeaders['HX-History-Restore-Request'].should.be.equal('true')
xhr.respond(200, {}, '')
})
htmx._('loadHistoryFromServer')('/test')
this.server.respond()
this.server.respondWith('GET', '/test', function(xhr) {
chai.assert(typeof xhr.requestHeaders['HX-Current-URL'] !== 'undefined', 'HX-Current-URL should not be undefined')
xhr.respond(200, {}, '')
})
htmx._('loadHistoryFromServer')('/test')
this.server.respond()
var btn = make('<svg onclick="document.getElementById(\'contents\').classList.toggle(\'show\')" class="hamburger" viewBox="0 0 100 80" width="25" height="25" style="margin-bottom:-5px">\n' +
'<rect width="100" height="20" style="fill:rgb(52, 101, 164)" rx="10"></rect>\n' +
'<rect y="30" width="100" height="20" style="fill:rgb(52, 101, 164)" rx="10"></rect>\n' +
'<rect y="60" width="100" height="20" style="fill:rgb(52, 101, 164)" rx="10"></rect>\n' +
'</svg>')
this.server.respondWith('GET', '/index2a.php',
"<div id='message' hx-swap-oob='true'>I came from message oob swap I should be second</div>" +
"<div id='message2' hx-swap-oob='true'>I came from a message2 oob swap I should be third but I am in the wrong spot</div>" +
"I'm page2 content (non-swap) I should be first")
var h1 = make('' +
"<div id='page2' ></div>" +
"<div id='message'></div>" +
"<div id='message2'></div>" +
"<h1 hx-get='/index2a.php' hx-target='#page2' hx-trigger='click'>Kutty CLICK ME</h1>")
h1.click()
this.server.respond()
htmx.find('#page2').innerHTML.should.equal("I'm page2 content (non-swap) I should be first")
htmx.find('#message').innerHTML.should.equal('I came from message oob swap I should be second')
htmx.find('#message2').innerHTML.should.equal('I came from a message2 oob swap I should be third but I am in the wrong spot')
this.server.respondWith('POST', '/htmx.php', function(xhr) {
xhr.respond(200, {}, xhr.requestBody)
})
var form = make('<form hx-trigger="click" hx-post="/htmx.php">\n' +
'<input type="text" name="variable" value="">\n' +
'<button type="submit">Submit</button>\n' +
'</form>')
form.click()
this.server.respond()
form.innerHTML.should.equal('variable=')
this.server.respondWith('GET', '/test', 'Foo<form><input name="id"/></form>')
var div = make('<div hx-get="/test">Get It</div>')
div.click()
this.server.respond()
div.innerText.should.contain('Foo')
this.server.respondWith('GET', '/test', "Foo\n<div id=''></div>")
var div = make('<div hx-get="/test">Get It</div>')
div.click()
this.server.respond()
div.innerText.should.contain('Foo')
this.server.respondWith('GET', '/test', "Foo <div id='ViewModel.Test'></div>")
var div = make('<div hx-get="/test">Get It</div>')
div.click()
this.server.respond()
div.innerText.should.contain('Foo')
this.server.respondWith('GET', '/test', "<div id='d1' @foo='bar'>Foo</div>")
var div = make('<div hx-get="/test">Get It</div>')
div.click()
this.server.respond()
byId('d1').getAttribute('@foo').should.equal('bar')
this.server.respondWith('GET', '/test', "<div id='d1' @foo='bar'>Foo</div>")
var div = make('<div hx-get="/test"><div id="d1">Foo</div></div>')
div.click()
this.server.respond()
byId('d1').getAttribute('@foo').should.equal('bar')
this.server.respondWith('GET', '/test', "<div id='d1'>Replaced</div>")
var input = make('<input hx-trigger="click" hx-get="/test" id="i1" hx-swap="outerHTML">')
input.focus()
input.click()
this.server.respond()
byId('d1').innerText.should.equal('Replaced')
this.server.respondWith('POST', '/test', 'Submitted')
var defaultPrevented = false
htmx.on('click', function(evt) {
defaultPrevented = evt.defaultPrevented
})
var form = make('<form hx-post="/test" hx-trigger="click[false]"></form>')
form.click()
this.server.respond()
defaultPrevented.should.equal(true)
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')
this.server.respondWith('POST', '/test', 'posted')
var form = make('<div id="d1"></div><form _="on htmx:afterRequest reset() me" hx-post="/test" hx-target="#d1">' +
' <input type="text" name="input" id="i1"/>' +
' <input type="submit" id="s1"/>' +
'</form>')
htmx.trigger(form, 'htmx:load') // have to manually trigger the load event for non-AJAX dynamic content
var div1 = byId('d1')
var input = byId('i1')
input.value = 'foo'
var submit = byId('s1')
input.value.should.equal('foo')
submit.click()
this.server.respond()
div1.innerHTML.should.equal('posted')
input.value.should.equal('') // form should be reset
this.server.respondWith('GET', '/test', 'triggered')
make('<div>' +
' <div id="d1"></div>' +
' <img src="img/bars.svg" usemap="#workmap" width="400" height="379">' +
'' +
' <map name="workmap">' +
' <area shape="rect" coords="34,44,270,350" alt="Computer" hx-get="/test" hx-target="#d1">' +
' </map>' +
'</div>')
var div1 = byId('d1')
var area = document.getElementsByTagName('area')[0]
area.click()
this.server.respond()
div1.innerHTML.should.equal('triggered')
this.server.respondWith('GET', '/test', "Foo<span id='example'>Bar</span>")
make('<form hx-select="#example">\n' +
' <button id="b1" hx-select="unset" hx-get="/test">Initial</button>\n' +
'</form>')
var btn = byId('b1')
btn.click()
this.server.respond()
btn.innerText.should.equal('FooBar')
const template = '<form id="formtest"> \n' +
'<input hx-get="/test" hx-target="#formtest" hx-trigger="click" type="text" id="id_email" value="test@test.com" />\n' +
'</form>'
const response = '<form id="formtest">\n' +
'<input hx-get="/test" hx-target="#formtest" hx-trigger="click" type="email" id="id_email" value="supertest@test.com" />\n' +
'</form>'
this.server.respondWith('GET', '/test', response)
make(template)
var input = byId('id_email')
// HTMX only attempts to restore the selection on inputs that have a current selection and are active.
// additionally we can't set the selection on email inputs (that's the whole bug) so start as a text input where you can set selection
// and replace with an email
input.focus()
input.selectionStart = 3
input.selectionEnd = 3
input.click()
this.server.respond()
var input = byId('id_email')
input.value.should.equal('supertest@test.com')