diff --git a/inventory/static/css/components/dropdown.css b/inventory/static/css/components/dropdown.css new file mode 100644 index 0000000..25c514f --- /dev/null +++ b/inventory/static/css/components/dropdown.css @@ -0,0 +1,4 @@ +.inventory-dropdown { + border-color: rgb(222, 226, 230); + overflow-y: auto; +} diff --git a/inventory/static/js/components/dropdown.js b/inventory/static/js/components/dropdown.js new file mode 100644 index 0000000..cc8068d --- /dev/null +++ b/inventory/static/js/components/dropdown.js @@ -0,0 +1,95 @@ +const DropDown = globalThis.DropDown ?? (globalThis.DropDown = {}); + +DropDown.utilities = { + filterList(id) { + value = document.getElementById(`${id}-filter`).value; + list = document.querySelectorAll(`#${id}-dropdown li`); + + list.forEach(item => { + const txt = item.textContent.toLowerCase(); + if (txt.includes(value)) { + item.style.display = 'list-item'; + } else { + item.style.display = 'none'; + }; + }); + }, + + selectItem(id, value) { + const btn = document.getElementById(`${id}-button`); + const txt = document.getElementById(`${id}-${value}`).textContent; + const inp = document.getElementById(id); + + btn.dataset.value = value; + btn.textContent = txt; + + inp.value = value; + }, +}; + +(() => { + const VISIBLE_ITEMS = 10; + + function setMenuMaxHeight(buttonEl) { + const menu = buttonEl?.nextElementSibling; + if (!menu || !menu.classList.contains('dropdown-menu')) return; + + const input = menu.querySelector('input.form-control'); + const firstItem = menu.querySelector('.dropdown-item'); + if (!firstItem) return; + + // Measure even if the menu is closed + const computed = getComputedStyle(menu); + const wasHidden = computed.display === 'none' || computed.visibility === 'hidden'; + if (wasHidden) { + menu.style.visibility = 'hidden'; + menu.style.display = 'block'; + } + + const inputH = input ? input.getBoundingClientRect().height : 0; + const itemH = firstItem.getBoundingClientRect().height || 0; + const itemCount = Math.min( + VISIBLE_ITEMS, + menu.querySelectorAll('.dropdown-item').length + ); + + const target = Math.ceil(inputH + itemH * itemCount); + menu.style.maxHeight = `${target + 10}px`; + menu.style.overflowY = 'auto'; + + if (wasHidden) { + menu.style.display = ''; + menu.style.visibility = ''; + } + } + + function onShow(e) { + setMenuMaxHeight(e.target); + } + + function onResize() { + document.querySelectorAll('.dropdown-toggle[data-bs-toggle="dropdown"]').forEach(btn => { + const menu = btn.nextElementSibling; + if (menu && menu.classList.contains('dropdown-menu') && menu.classList.contains('show')) { + setMenuMaxHeight(btn); + } + }); + } + + function init(root = document) { + // Delegate so dynamically-added dropdowns work too + root.addEventListener('show.bs.dropdown', onShow); + window.addEventListener('resize', onResize); + } + + // Expose for manyal calls or tests + DropDown.utilities.setMenuMaxHeight = setMenuMaxHeight; + DropDown.init = init; + + // Auto-init + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => init()); + } else { + init(); + } +})(); diff --git a/inventory/templates/crudkit/field.html b/inventory/templates/crudkit/field.html index 4ca1420..5c8e9a5 100644 --- a/inventory/templates/crudkit/field.html +++ b/inventory/templates/crudkit/field.html @@ -1,91 +1,84 @@ {% if field_type != 'hidden' and field_label %} - + + {% endif %} + {% endif %} {% if field_type == 'select' %} {# - -#} - {% if value %} - {% set sel_label = (options | selectattr('value', 'equalto', value) | first)['label'] %} + +#} +{% if value %} +{% set sel_label = (options | selectattr('value', 'equalto', value) | first)['label'] %} +{% else %} +{% set sel_label = "-- Select --" %} +{% endif %} + + + {% elif field_type == 'textarea' %} - + {% elif field_type == 'checkbox' %} - + {% elif field_type == 'hidden' %} - + {% elif field_type == 'display' %} -
{{ value_label if value_label else (value if value else "") }}
+
{{ value_label if value_label else (value if value else "") }}
{% elif field_type == "date" %} - + {% elif field_type == "time" %} - + {% elif field_type == "datetime" %} - + {% else %} - + {% endif %} {% if help %} -
{{ help }}
-{% endif %} +
{{ help }}
+{% endif %} \ No newline at end of file diff --git a/inventory/templates/entry.html b/inventory/templates/entry.html index 3c8c6bf..edc939b 100644 --- a/inventory/templates/entry.html +++ b/inventory/templates/entry.html @@ -1,8 +1,16 @@ {% extends 'base.html' %} +{% block styleincludes %} + +{% endblock %} + {% block main %}
{{ form | safe }}
-{% endblock %} \ No newline at end of file +{% endblock %} + +{% block scriptincludes %} + +{% endblock %}