OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

ssd.js

3 KB
/* Searchable dropdown ("ssd") – shared behaviour for UniFi pages.
 * See ssd.css for the expected markup. Selection dispatches a bubbling
 * `ssd:select` CustomEvent (detail: {id, value, label}); each page wires its
 * own reaction by listening for it. */
(function () {
    'use strict';

    window.ssdToggle = function (id) {
        var el = document.getElementById(id);
        if (!el) return;
        var panel   = el.querySelector('.ssd__panel');
        var trigger = el.querySelector('.ssd__trigger');
        if (!panel || !trigger) return;

        var isOpen = el.classList.contains('open');
        // Alle anderen schließen
        document.querySelectorAll('.ssd.open').forEach(function (o) {
            o.classList.remove('open');
            var p = o.querySelector('.ssd__panel');
            if (p) p.style.display = 'none';
        });
        if (isOpen) return;

        el.classList.add('open');
        if (el.hasAttribute('data-ssd-fixed')) {
            var r  = trigger.getBoundingClientRect();
            var vw = window.innerWidth || document.documentElement.clientWidth;
            var pw = Math.max(240, r.width);
            var left = r.left;
            if (left + pw > vw - 8) left = vw - pw - 8;
            if (left < 8) left = 8;
            panel.style.top = (r.bottom + 4) + 'px';
            panel.style.left = left + 'px';
            panel.style.minWidth = pw + 'px';
        }
        panel.style.display = '';
        var s = panel.querySelector('.ssd__search');
        if (s) { s.value = ''; window.ssdFilter(id, ''); s.focus(); }
    };

    window.ssdFilter = function (id, q) {
        var el = document.getElementById(id);
        if (!el) return;
        var lq = (q || '').toLowerCase();
        el.querySelectorAll('.ssd__item').forEach(function (it) {
            it.classList.toggle('hidden', lq !== '' && !it.textContent.toLowerCase().includes(lq));
        });
    };

    window.ssdSelect = function (id, value, label) {
        var el = document.getElementById(id);
        if (!el) return;
        var lbl = el.querySelector('.ssd__value');
        if (lbl) lbl.innerHTML = label;
        el.querySelectorAll('.ssd__item').forEach(function (it) {
            it.classList.toggle('selected', it.getAttribute('data-value') === value);
        });
        el.classList.remove('open');
        var p = el.querySelector('.ssd__panel');
        if (p) p.style.display = 'none';
        el.dispatchEvent(new CustomEvent('ssd:select', {
            bubbles: true,
            detail: { id: id, value: value, label: label }
        }));
    };

    // Klick außerhalb schließt alle Dropdowns
    document.addEventListener('click', function (e) {
        document.querySelectorAll('.ssd.open').forEach(function (el) {
            if (!el.contains(e.target)) {
                el.classList.remove('open');
                var p = el.querySelector('.ssd__panel');
                if (p) p.style.display = 'none';
            }
        });
    });
})();