diff --git a/app/assets/javascripts/shared/combobox.js b/app/assets/javascripts/shared/combobox.js
index c675f8454..1adad9ddd 100644
--- a/app/assets/javascripts/shared/combobox.js
+++ b/app/assets/javascripts/shared/combobox.js
@@ -39,15 +39,26 @@ class ComboBox {
if (this.config.includes('filter')) {
const idSuffix = Math.random().toString(36);
this.$comboboxMenu.append(
- `
\
+ `
\
\
- \
+ \
No results.
`
);
this.$filter = this.$comboboxMenu.find(
'[data-behavior~=combobox-filter]'
);
+
+ if (this.config.includes('add-options')) {
+ this.$filter.parent().append(
+ `
\
+ \
+ Create ${this.$filter.val()} option\
+ `
+ );
+ this.$filter.attr('placeholder', 'Filter or create options...');
+ this.$addOption = this.$filter.siblings('[data-behavior~=add-option]');
+ }
}
this.$target.children().each(function () {
@@ -125,6 +136,13 @@ class ComboBox {
});
}
+ if (this.$addOption) {
+ this.$addOption.on('click', function () {
+ const value = $(this).find('strong').text();
+ that.appendCustomOption(value);
+ });
+ }
+
this.$target.on('change', function () {
let $options = [];
@@ -153,12 +171,34 @@ class ComboBox {
`
\
- ${$option.text()}\
+ data-value="${$option.attr('value')}"\
+ >\
+ ${$option.text()}\
`
);
}
+ appendCustomOption(value) {
+ this.$target.append(`
`);
+
+ const $option = this.$target.children().last(),
+ that = this;
+
+ this.appendOption(this.$comboboxMenu, $option);
+
+ this.$comboboxOptions = this.$comboboxMenu.find(
+ '[data-behavior~=combobox-option]'
+ );
+
+ const $comboboxOption = this.$comboboxOptions.last();
+ this.selectOptions($comboboxOption);
+
+ $comboboxOption.on('click', function (event) {
+ event.stopPropagation();
+ that.selectOptions($comboboxOption);
+ });
+ }
+
handleFiltering() {
clearTimeout(this.debounceTimeout);
@@ -181,9 +221,18 @@ class ComboBox {
this.$comboboxMenu.find('[data-behavior~=combobox-optgroup]');
- this.$filter
- .next('[data-behavior~=no-results]')
- .toggleClass('d-none', matchedOptions > 0);
+ if (this.config.includes('add-options')) {
+ this.$filter
+ .nextAll('[data-behavior~=add-option]')
+ .find('strong')
+ .text(this.$filter.val())
+ .end()
+ .toggleClass('d-none', matchedOptions > 0);
+ } else {
+ this.$filter
+ .next('[data-behavior~=no-results]')
+ .toggleClass('d-none', matchedOptions > 0);
+ }
}, this.debounceTimer);
}