aboutsummaryrefslogtreecommitdiff
path: root/static/js/dropdown.js
blob: 5b1fb258beb49391bc5a0e56958600a872fa14a5 (plain)
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
function initDropdowns() {
    document.querySelectorAll("[data-dropdown]").forEach(function (dropdown) {
        if (dropdown.dataset.initialized) return;
        dropdown.dataset.initialized = "true";

        var trigger = dropdown.querySelector("[data-dropdown-trigger]");
        var menu = dropdown.querySelector("[data-dropdown-menu]");
        var search = dropdown.querySelector("[data-dropdown-search]");
        var options = dropdown.querySelectorAll("[data-dropdown-option]");
        var empty = dropdown.querySelector("[data-dropdown-empty]");
        var hiddenInput = dropdown.querySelector("[data-dropdown-value]");
        var label = dropdown.querySelector("[data-dropdown-label]");

        trigger.addEventListener("click", function () {
            dropdown.classList.toggle("open");
            if (dropdown.classList.contains("open") && search) {
                search.value = "";
                filterOptions("");
                search.focus();
            }
        });

        if (search) {
            search.addEventListener("input", function () {
                filterOptions(search.value.toLowerCase());
            });
        }

        options.forEach(function (option) {
            option.addEventListener("click", function () {
                if (hiddenInput) {
                    hiddenInput.value = option.dataset.value;
                }
                if (label) {
                    label.textContent = option.dataset.label;
                    label.classList.remove("text-zinc-500");
                    label.classList.add("text-zinc-200");
                }

                options.forEach(function (other) {
                    other.classList.remove("selected");
                });
                option.classList.add("selected");

                dropdown.classList.remove("open");
            });
        });

        function filterOptions(query) {
            var visibleCount = 0;
            options.forEach(function (option) {
                var matches = option.dataset.label.toLowerCase().indexOf(query) !== -1;
                option.style.display = matches ? "" : "none";
                if (matches) visibleCount++;
            });
            if (empty) {
                empty.classList.toggle("hidden", visibleCount > 0);
            }
        }

        document.addEventListener("click", function (event) {
            if (!dropdown.contains(event.target)) {
                dropdown.classList.remove("open");
            }
        });
    });
}

document.addEventListener("DOMContentLoaded", initDropdowns);
document.body.addEventListener("htmx:afterSwap", initDropdowns);