Skip to content

Commit

Permalink
IBX-2622: As a developer I want to have dynamic Dropdown (#381)
Browse files Browse the repository at this point in the history
Co-authored-by: Dariusz Szut <dew326@gmail.com>
  • Loading branch information
GrabowskiM and dew326 authored Apr 5, 2022
1 parent 2d16538 commit 8be701c
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 5 deletions.
64 changes: 62 additions & 2 deletions src/bundle/Resources/public/js/scripts/core/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@
this.selectedItemTemplate = this.selectedItemsContainer.dataset.template;
this.selectedItemIconTemplate = this.selectedItemsContainer.dataset.iconTemplate;
this.selectedItemLabel = this.selectedItemsContainer.dataset.selectedItemLabel;
this.itemTemplate = this.itemsListContainer.dataset.template;
this.sourceOptionsObserver = new MutationObserver((mutationsList) => {
if (this.hasChangedOptions(mutationsList)) {
this.recreateOptions();
}
});

this.createSelectedItem = this.createSelectedItem.bind(this);
this.hideOptions = this.hideOptions.bind(this);
Expand All @@ -76,15 +82,14 @@
container.insertAdjacentHTML('beforeend', selectedItemRendered);

const selectedItemNode = container.querySelector('.ibexa-dropdown__selected-item');

if (icon) {
const iconWrapper = container.querySelector('.ibexa-dropdown__selected-item-icon');
const selectedItemIconRendered = this.selectedItemIconTemplate.replace('{{ icon }}', icon);

iconWrapper.insertAdjacentHTML('beforeend', selectedItemIconRendered);
}

selectedItemNode.classList.toggle('ibexa-dropdown__selected-item--has-icon', icon);
selectedItemNode.classList.toggle('ibexa-dropdown__selected-item--has-icon', !!icon);

return selectedItemNode;
}
Expand Down Expand Up @@ -303,6 +308,57 @@
return this.itemsContainer;
}

hasChangedOptions(mutationList) {
return mutationList.some((mutationRecord) => mutationRecord.addedNodes.length || mutationRecord.removedNodes.length);
}

getSelectedItems() {
return [...this.sourceInput.querySelectorAll(':checked')];
}

recreateOptions() {
const optionsToRecreate = this.sourceInput.querySelectorAll('option');

this.itemsListContainer.querySelectorAll('.ibexa-dropdown__item').forEach((item) => {
this.removeOption(item.dataset.value);
});

optionsToRecreate.forEach((option) => {
this.createOption(option.value, option.innerHTML);
});

const selectedItems = this.getSelectedItems();

this.clearCurrentSelection();
this.fitItems();
selectedItems.forEach((selectedItem) => {
this.selectOption(selectedItem.value);
});
this.container.classList.toggle('ibexa-dropdown--disabled', !optionsToRecreate.length);

if (!optionsToRecreate.length) {
this.selectedItemsContainer.insertAdjacentHTML('afterbegin', this.selectedItemsContainer.dataset.placeholderTemplate);
}
}

removeOption(value) {
const optionNode = this.itemsListContainer.querySelector(`[data-value="${value}"]`);

optionNode.remove();
}

createOption(value, label) {
const container = doc.createElement('div');
const itemRendered = this.itemTemplate.replaceAll('{{ value }}', value).replaceAll('{{ label }}', label);

container.insertAdjacentHTML('beforeend', itemRendered);

const optionNode = container.firstElementChild;

optionNode.addEventListener('click', this.onOptionClick, false);
this.itemsListContainer.append(optionNode);
}

init() {
if (this.container.dataset.initialized) {
console.warn('Dropdown has already been initialized!');
Expand Down Expand Up @@ -349,6 +405,10 @@
this.itemsFilterInput.addEventListener('keyup', this.filterItems, false);
this.itemsFilterInput.addEventListener('input', this.filterItems, false);
}

this.sourceOptionsObserver.observe(this.sourceInput, {
childList: true,
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
{{ source|default(null)|raw }}
</div>
<div class="ibexa-dropdown__wrapper">
{% set placeholder_list_item %}
<li class="ibexa-dropdown__selected-item ibexa-dropdown__selected-item--predefined ibexa-dropdown__selected-placeholder">
{{ 'dropdown.placeholder.empty'|trans|desc("No options available") }}
</li>
{% endset %}
<ul
class="ibexa-dropdown__selection-info"
data-min-item-width="{{ min_item_width }}"
Expand All @@ -47,12 +52,11 @@
value: '{{ value }}',
label: '{{ label }}',
})|e('html_attr') }}"
data-placeholder-template="{{ placeholder_list_item|e('html_attr') }}"
>
{% if no_items %}
{% if not is_dynamic %}
<li class="ibexa-dropdown__selected-item ibexa-dropdown__selected-item--predefined ibexa-dropdown__selected-placeholder">
{{ 'dropdown.placeholder.empty'|trans|desc("No options available") }}
</li>
{{ placeholder_list_item }}
{% endif %}
{% else %}
{% if value is empty %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
is_disabled: attr.disabled|default(false) or disabled|default(false),
is_hidden: attr.dropdown_hidden|default(false),
is_small: attr.is_small|default(false),
is_ghost: attr.is_ghost|default(false),
} %}
{% endif %}
{%- endblock choice_widget -%}

0 comments on commit 8be701c

Please sign in to comment.