-
Notifications
You must be signed in to change notification settings - Fork 0
/
htmx-mini.js
93 lines (76 loc) · 2.88 KB
/
htmx-mini.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
let elementMap = {};
let requestType = ['get', 'post', 'put', 'delete', 'patch'];
let swapMode = ['innerHTML', 'outerHTML', 'beforebegin', 'afterbegin', 'beforeend', 'afterend', 'delete', 'none'];
function handler(event) {
event.preventDefault();
const el = elementMap[event.target];
let xhr = new XMLHttpRequest();
xhr.open(el.type, el.url, true);
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
if (el.swap == 'none') { return; }
let response = xhr.responseText;
let target = el.target ? document.querySelector(el.target) : event.target;
let adjacent = (el.swap != 'innerHTML' && el.swap != 'outerHTML');
if (el.swap == 'delete') {
target.parentNode.removeChild(target);
return;
}
if (adjacent) {
target.insertAdjacentHTML(el.swap, response);
} else {
target[el.swap] = response;
}
}
}
let data = {};
if (event.currentTarget.tagName.toLowerCase() === 'form') {
data = new FormData(event.currentTarget);
}
xhr.send(data);
}
document.addEventListener('DOMContentLoaded', () => {
let elements = document.querySelectorAll('[data-hxm-req]');
for (let i = 0; i < elements.length; i++) {
let element = elements[i];
let type = element.getAttribute('data-hxm-req');
if (!requestType.includes(type.toLowerCase())) {
throw new Error(`Invalid request type: ${type}. It has to be one of ${requestType.join(', ')}`);
}
let url = element.getAttribute('data-hxm-url');
let trigger = element.getAttribute('data-hxm-trigger');
let target = element.getAttribute('data-hxm-target');
let swap = element.getAttribute('data-hxm-swap');
if (!url) {
url = window.location.href;
}
if (!trigger) {
switch (element.tagName.toLowerCase()) {
case 'input':
case 'textarea':
case 'select':
trigger = 'change';
break;
case 'form':
trigger = 'submit';
break;
default:
trigger = 'click';
}
}
if (!swap) {
swap = 'innerHTML';
}
if (!swapMode.includes(swap)) {
throw new Error(`Invalid swap mode: ${swap}. It has to be one of ${swapMode.join(', ')}`);
}
elementMap[element] = { url, type, target, swap };
let triggers = trigger.split(",");
for (let j = 0; j < triggers.length; j++) {
element.addEventListener(triggers[j].trim(), handler);
if (triggers[j].trim() == 'load') {
element.dispatchEvent(new Event('load'));
}
}
}
});