Skip to content
scheduler.js 4.84 KiB
Newer Older
Bengfort's avatar
Bengfort committed
(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') {
Bengfort's avatar
Bengfort committed
            new Datepicker(e, {
                format: 'yyyy-mm-dd',
                language: document.documentElement.lang,
                autoclose: true,
                calendarWeeks: true,
Bengfort's avatar
Bengfort committed
                daysOfWeekHighlighted: [0, 6],
                todayHighlight: true,
            });
        }
    });
Bengfort's avatar
Bengfort committed
})();