diff --git a/static/css/base.css b/static/css/base.css index 2bec08b..305e738 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -11,62 +11,6 @@ border-radius: 4px; } -select.card-multiselect { - height: calc(var(--spacing) * 35); - /*background-image: linear-gradient(45deg, #0000 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, #0000 50%); */ - background-image: none; -} - -.choices.is-disabled .choices__inner, -.choices.is-disabled .choices__input { - background-color: var(--color-neutral); -} -.choices[data-type*=select-one] .choices__input { - border-bottom: 1px solid var(--btn-shadow); - background-color: var(--color-base-100); -} -.choices[data-type*=select-one] .choices__button:focus { - box-shadow: 0 0 0 2px #005F75; -} -.choices__inner { - background-color: var(--color-base-100); - border: 1px solid var(--btn-shadow); -} -.is-focused .choices__inner, .is-open .choices__inner { - border-color: var(--btn-shadow); -} -.choices__list--multiple .choices__item { - background-color: var(--color-base-100); - border: 1px solid var(--btn-shadow); - color: var(--color-primary); -} -.choices__list--multiple .choices__item.is-highlighted { - background-color: var(--color-base-100); - border: 1px solid var(--btn-shadow); -} -.is-disabled .choices__list--multiple .choices__item { - background-color: var(--color-neutral); - border: 1px solid var(--btn-shadow); -} -.choices__list--dropdown, .choices__list[aria-expanded] { - background-color: var(--color-base-100); - border: 1px solid var(--btn-shadow); -} -.is-open .choices__list--dropdown, .is-open .choices__list[aria-expanded] { - border-color: var(--btn-shadow); -} -.choices__list--dropdown .choices__item--selectable.is-highlighted, .choices__list[aria-expanded] .choices__item--selectable.is-highlighted { - background-color: var(--color-base-100); - border: 1px solid var(--btn-shadow); -} -.choices__heading { - border-bottom: 1px solid var(--btn-shadow); - color: var(--color-neutral); -} -.choices__input { - background-color: var(--color-base-100); -} - .gravatar-hovercard .gravatar-hovercard__inner { background-color: var(--color-base-100) !important; border-color: var(--color-base-300) !important; diff --git a/static/css/card-multiselect.css b/static/css/card-multiselect.css new file mode 100644 index 0000000..cd14427 --- /dev/null +++ b/static/css/card-multiselect.css @@ -0,0 +1,88 @@ +select.card-multiselect { + height: calc(var(--spacing) * 35); + /*background-image: linear-gradient(45deg, #0000 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, #0000 50%); */ + background-image: none; +} +.choices.is-disabled .choices__inner, +.choices.is-disabled .choices__input { + background-color: var(--color-neutral); +} +.choices[data-type*=select-one] .choices__input { + border-bottom: 1px solid var(--btn-shadow); + background-color: var(--color-base-100); +} +.choices[data-type*=select-one] .choices__button:focus { + box-shadow: 0 0 0 2px #005F75; +} +.choices__inner { + background-color: var(--color-base-100); + border: 1px solid var(--btn-shadow); +} +.is-focused .choices__inner, .is-open .choices__inner { + border-color: var(--btn-shadow); +} +.choices__list--multiple .choices__item { + background-color: var(--color-base-100); + border: 1px solid var(--btn-shadow); + color: var(--color-primary); +} +.choices__list--multiple .choices__item.is-highlighted { + background-color: var(--color-base-100); + border: 1px solid var(--btn-shadow); +} +.is-disabled .choices__list--multiple .choices__item { + background-color: var(--color-neutral); + border: 1px solid var(--btn-shadow); +} +.choices__list--dropdown, .choices__list[aria-expanded] { + background-color: var(--color-base-100); + border: 1px solid var(--btn-shadow); +} +.is-open .choices__list--dropdown, .is-open .choices__list[aria-expanded] { + border-color: var(--btn-shadow); +} +.choices__list--dropdown .choices__item--selectable.is-highlighted, .choices__list[aria-expanded] .choices__item--selectable.is-highlighted { + background-color: var(--color-base-100); + border: 1px solid var(--btn-shadow); +} +.choices__heading { + border-bottom: 1px solid var(--btn-shadow); + color: var(--color-neutral); +} +.choices__input { + background-color: var(--color-base-100); +} +.choices.select { + height: inherit; + padding-inline-start: 0; +} +.choices__inner { + border: 1px solid var(--color-gray-500) !important; +} +.choices__list { + border: none !important; +} +.choices__list--dropdown { + border-left: 1px solid var(--color-gray-500) !important; + border-right: 1px solid var(--color-gray-500) !important; + border-bottom: 1px solid var(--color-gray-500) !important; + border-top: none !important; +} +.choices.select[data-type*="select-one"]::after { + display: none; +} +.choices__inner.bg-secondary { + background-color: var(--color-secondary); + border: none; + z-index: 10; +} +.choices__item.mx-auto.w-max:hover { + background-color: #e2e8f0; +} +.choices__input, +.choices__input--cloned { + width: 100% !important; +} +.choices__list--dropdown span.card-quantity-badge { + display: none; +} \ No newline at end of file diff --git a/static/js/base.js b/static/js/base.js index 88a6164..e0465d1 100644 --- a/static/js/base.js +++ b/static/js/base.js @@ -119,7 +119,6 @@ const $$ = selector => Array.from(document.querySelector(selector)); */ function processMarqueeElements() { document.querySelectorAll('.marquee-calc').forEach(element => { - console.log(element.innerHTML, element.offsetWidth, element.scrollWidth); if (element.offsetWidth >= 148 || element.offsetWidth < element.scrollWidth) { element.innerHTML = '' + element.innerHTML + ''; } diff --git a/static/js/card-multiselect.js b/static/js/card-multiselect.js new file mode 100644 index 0000000..a649398 --- /dev/null +++ b/static/js/card-multiselect.js @@ -0,0 +1,219 @@ +document.addEventListener('DOMContentLoaded', function() { + if (!window.updateGlobalCardFilters) { + window.updateGlobalCardFilters = function() { + const selects = document.querySelectorAll('.card-multiselect'); + + // Rebuild global selections and rarity filtering. + const globalSelectedIds = []; + let globalRarity = null; + + selects.forEach(select => { + const selectedValues = select.choicesInstance ? select.choicesInstance.getValue(true) : []; + selectedValues.forEach(cardId => { + if (cardId && globalSelectedIds.indexOf(cardId) === -1) { + globalSelectedIds.push(cardId); + } + }); + if (selectedValues.length > 0 && globalRarity === null) { + const option = select.querySelector('option[value="${selectedValues[0]}"]'); + if (option) { + globalRarity = option.getAttribute('data-rarity'); + } + } + }); + + selects.forEach(select => { + if (select.choicesInstance && select.choicesInstance.dropdown.element) { + // Reset all options to enabled. + select.querySelectorAll('option').forEach(function(option) { + option.disabled = false; + }); + // Reset all items to visible. + select.choicesInstance.dropdown.element.querySelectorAll('[data-card-id]').forEach(function(item) { + item.style.display = ''; + }); + // Filter out options/items that do not match the global rarity. + if (globalRarity) { + select.querySelectorAll('option[data-rarity]:not([data-rarity="'+globalRarity+'"])').forEach(function(option) { + option.disabled = true; + }); + select.choicesInstance.dropdown.element.querySelectorAll('[data-rarity]:not([data-rarity="'+globalRarity+'"])').forEach(function(item) { + item.style.display = 'none'; + }); + } + // Filter out options/items that match the global selected card IDs. + for (const cardId of globalSelectedIds) { + select.choicesInstance.dropdown.element.querySelectorAll('[data-card-id="' + cardId + '"]').forEach(function(item) { + item.style.display = 'none'; + }); + select.querySelectorAll('option[data-card-id="'+cardId+'"]:not(option[selected])').forEach(function(option) { + option.disabled = true; + }); + } + } + }); + }; + } + + if (!window.updateOptionQuantity) { + window.updateOptionQuantity = function(item, quantity) { + const cardId = item.getAttribute('data-card-id'); + const option = item.closest('.choices__inner').querySelector('option[value="' + cardId + '"]'); + if (option) { + option.setAttribute('data-quantity', quantity); + } + } + } + + if (!window.getOptionQuantity) { + window.getOptionQuantity = function(item) { + const cardId = item.getAttribute('data-card-id'); + const option = item.closest('.choices__inner').querySelector('option[value="' + cardId + '"]'); + return option ? parseInt(option.getAttribute('data-quantity')) : ""; + } + } + + + const selectFields = document.querySelectorAll('.card-multiselect'); + selectFields.forEach(selectField => { + const placeholder = selectField.getAttribute('data-placeholder') || ''; + + const choicesInstance = new Choices(selectField, { + removeItemButton: false, + placeholderValue: placeholder, + searchEnabled: true, + shouldSort: false, + allowHTML: true, + closeDropdownOnSelect: true, + removeItemButton: true, + searchFields: ['label'], + resetScrollPosition: false, + callbackOnCreateTemplates: function(template) { + const getCardContent = (data) => { + let htmlContent = (data.element && data.element.getAttribute('data-html-content')) || data.label; + let quantity = data.element.getAttribute('data-quantity'); + quantity = quantity ? parseInt(quantity) : 1; + htmlContent = htmlContent.replace('__QUANTITY__', quantity); + return htmlContent; + }; + + const renderCard = (classNames, data, type) => { + const rarity = data.element ? data.element.getAttribute('data-rarity') : ''; + const cardId = data.element ? data.element.getAttribute('data-card-id') : 0; + const cardname = data.element ? data.element.getAttribute('data-name') : ''; + const content = getCardContent(data); + if (type === 'item') { + return template(` +
+ + +
${content}
+
+ `); + } else { + const extraAttributes = `data-select-text="${this.config.itemSelectText}" data-choice ${ + data.disabled ? 'data-choice-disabled aria-disabled="true"' : 'data-choice-selectable' + }`; + const extraClasses = classNames.itemChoice; + return template(` +
+ ${content} +
+ `); + } + }; + + return { + choice: function(classNames, data) { + return renderCard(classNames, data, 'choice'); + }, + item: function(classNames, data) { + return renderCard(classNames, data, 'item'); + } + }; + } + }); + + // Associate the Choices instance with the select field. + selectField.choicesInstance = choicesInstance; + + if (!window.cardMultiselectInstances) { + window.cardMultiselectInstances = []; + } + window.cardMultiselectInstances.push(selectField); + + selectField.addEventListener('change', function() { + if (window.updateGlobalCardFilters) { + window.updateGlobalCardFilters(); + } + }); + + // Listen for increment/decrement clicks (scoped to the choices container). + const choicesContainer = selectField.closest('.choices') || document; + + choicesContainer.addEventListener('click', function(e) { + if (e.target.classList.contains('increment')) { + e.preventDefault(); + e.stopPropagation(); + e.stopImmediatePropagation(); + const container = e.target.closest('[data-item]'); + if (container) { + let quantityBadge = container.querySelector('.card-quantity-badge'); + let quantity = window.getOptionQuantity(container); + quantity = quantity + 1; + quantityBadge.innerText = quantity; + window.updateOptionQuantity(container, quantity); + } + } + if (e.target.classList.contains('decrement')) { + e.preventDefault(); + e.stopPropagation(); + e.stopImmediatePropagation(); + const container = e.target.closest('[data-item]'); + if (container) { + let quantityBadge = container.querySelector('.card-quantity-badge'); + let quantity = window.getOptionQuantity(container); + const cardId = container.getAttribute('data-card-id'); + if (quantity === 1) { + const option = selectField.querySelector('option[value="' + cardId + '"]'); + if (option) { + choicesInstance.removeActiveItemsByValue(option.value); + option.selected = false; + } + if (window.updateGlobalCardFilters) { + window.updateGlobalCardFilters(); + } + } else { + quantity = quantity - 1; + quantityBadge.innerText = quantity; + window.updateOptionQuantity(container, quantity); + } + } + } + if (e.target.closest('[data-item]') && + !e.target.classList.contains('increment') && + !e.target.classList.contains('decrement')) { + e.stopPropagation(); + e.stopImmediatePropagation(); + } + }); + }); + + if (choicesInstance.getValue(true).length > 0 && window.updateGlobalCardFilters) { + window.updateGlobalCardFilters(); + } +}); \ No newline at end of file diff --git a/theme/templates/base.html b/theme/templates/base.html index 3f3dac8..709bc84 100644 --- a/theme/templates/base.html +++ b/theme/templates/base.html @@ -41,6 +41,9 @@ + + + {% block css %}{% endblock %} diff --git a/theme/templatetags/card_multiselect.html b/theme/templatetags/card_multiselect.html index 8753601..2dfd671 100644 --- a/theme/templatetags/card_multiselect.html +++ b/theme/templatetags/card_multiselect.html @@ -19,256 +19,4 @@ {% endfor %} {% endcache %} - - - - - \ No newline at end of file + \ No newline at end of file