Newer
Older
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
(function() {
var table = document.querySelector('[data-js="multi-datetime"]');
var lang = document.documentElement.lang;
var dateFormatter = new Intl.DateTimeFormat(lang, {
year: 'numeric',
month: 'numeric',
day: 'numeric',
weekday: 'short',
});
var timeFormatter = new Intl.DateTimeFormat(lang, {
hour: '2-digit',
minute: '2-digit',
});
var formatDate = function(s) {
return dateFormatter.format(new Date(s));
};
var formatTime = function(s) {
return timeFormatter.format(new Date('1970-01-01 ' + s));
};
var getElementIndex = function(el) {
var i = 0;
while (el.previousElementSibling) {
i += 1;
el = el.previousElementSibling;
}
return i;
};
var createCell = function(date, time) {
var td = document.createElement('td');
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.name = 'timeslots';
checkbox.value = date + ' ' + time;
checkbox.checked = true;
td.append(checkbox);
return td;
};
var createDeleteButton = function(onclick) {
var button = document.createElement('button');
button.type = 'button';
button.className = 'btn btn-sm btn-light';
button.textContent = '🗑';
button.title = django.gettext('Delete');
button.setAttribute('aria-label', django.gettext('Delete'));
button.addEventListener('click', onclick);
return button;
};
var getInsertIndex = function(elements, value, start) {
var i = start;
while (i < elements.length && elements[i].dataset.value < value) {
i += 1;
}
return i;
};
var addDate = function(table, date) {
var tbody = table.querySelector('tbody');
var index = getInsertIndex(tbody.children, date, 0);
var tr = document.createElement('tr');
tr.dataset.value = date;
for (let col of table.querySelectorAll('thead th')) {
var time = col.dataset.value;
var td;
if (!time) { // first column
td = document.createElement('th');
td.textContent = formatDate(date) + ' ';
td.append(createDeleteButton());
} else {
td = createCell(date, time);
}
tr.append(td);
}
if (index < tbody.children.length) {
tbody.children[index].before(tr);
} else {
tbody.append(tr);
}
};
var addTime = function(table, time) {
var index = getInsertIndex(table.querySelectorAll('thead th'), time, 1);
for (let tr of table.querySelectorAll('tr')) {
var date = tr.dataset.value;
var td;
if (!date) { // first row
td = document.createElement('th');
td.dataset.value = time;
td.textContent = formatTime(time) + ' ';
td.append(createDeleteButton(rmCol));
} else {
td = createCell(date, time);
}
if (index < tr.children.length) {
tr.children[index].before(td);
} else {
tr.append(td);
}
}
};
var rmRow = function(event) {
event.target.closest('tr').remove();
};
var rmCol = function(event) {
var table = event.target.closest('table');
var th = event.target.closest('th');
var i = getElementIndex(th);
table.querySelectorAll('tr').forEach(tr => {
tr.children[i].remove();
});
};
document.getElementById('add_date').addEventListener('submit', function(event) {
event.preventDefault();
addDate(table, event.target.input.value);
});
document.getElementById('add_time').addEventListener('submit', function(event) {
event.preventDefault();
addTime(table, event.target.input.value);
});
for (let th of table.querySelectorAll('thead th')) {
if (th.dataset.value) {
th.textContent = formatTime(th.dataset.value) + ' ';
th.append(createDeleteButton(rmCol));
}
}
for (let tr of table.querySelectorAll('tbody tr')) {
let th = tr.querySelector('th');
th.textContent = formatDate(tr.dataset.value) + ' ';
th.append(createDeleteButton(rmRow));
}
document.querySelectorAll('[type="date"]').forEach(function(e) {
if (e.type !== 'date') {
$(e).datepicker({
format: 'yyyy-mm-dd',
language: document.documentElement.lang,
autoclose: true,
calendarWeeks: true,
daysOfWeekHighlighted: '0,6',
todayHighlight: true,
});
}
});