var RomoSelectDropdown = RomoComponent(function(elem, optionElemsParentElem) {
this.elem = elem;
this.filterHiddenClass = 'romo-select-filter-hidden';
this.optionElemSelector = ':not(.'+this.filterHiddenClass+')';
this.optionElemsParentElem = (optionElemsParentElem || Romo.find(this.elem, '.romo-select-dropdown-options-parent')[0]);
this.doInit();
this._bindElem();
Romo.trigger(this.elem, 'romoSelectDropdown:ready', [this]);
});
RomoSelectDropdown.prototype.bodyElem = function() {
return this.romoOptionListDropdown.bodyElem();
}
RomoSelectDropdown.prototype.popupElem = function() {
return this.romoOptionListDropdown.popupElem();
}
RomoSelectDropdown.prototype.popupOpen = function() {
return this.romoOptionListDropdown.popupOpen();
}
RomoSelectDropdown.prototype.popupClosed = function() {
return this.romoOptionListDropdown.popupClosed();
}
RomoSelectDropdown.prototype.selectedItemElem = function() {
return this.romoOptionListDropdown.selectedItemElem();
}
RomoSelectDropdown.prototype.selectedItemValue = function() {
return this.romoOptionListDropdown.selectedItemValue();
}
RomoSelectDropdown.prototype.selectedItemText = function() {
return this.romoOptionListDropdown.selectedItemText();
}
RomoSelectDropdown.prototype.optionFilterValue = function() {
return this.romoOptionListDropdown.optionFilterValue();
}
RomoSelectDropdown.prototype.optItemElems = function() {
return this.romoOptionListDropdown.optItemElems();
}
RomoSelectDropdown.prototype.optgroupItemElems = function() {
return this.romoOptionListDropdown.optgroupItemElems();
}
RomoSelectDropdown.prototype.doSetSelectedItem = function(newValue) {
this.romoOptionListDropdown.doSetSelectedItem(newValue);
}
RomoSelectDropdown.prototype.doFocus = function(openOnFocus) {
this.romoOptionListDropdown.doFocus(openOnFocus);
}
// private
RomoSelectDropdown.prototype._bindElem = function() {
Romo.setData(this.elem, 'romo-option-list-focus-style-class', 'romo-select-focus');
if (Romo.data(this.elem, 'romo-select-dropdown-no-filter') !== undefined) {
Romo.setData(this.elem, 'romo-option-list-dropdown-no-filter', Romo.data(this.elem, 'romo-select-dropdown-no-filter'));
}
if (Romo.data(this.elem, 'romo-select-dropdown-filter-placeholder') !== undefined) {
Romo.setData(this.elem, 'romo-option-list-dropdown-filter-placeholder', Romo.data(this.elem, 'romo-select-dropdown-filter-placeholder'));
}
if (Romo.data(this.elem, 'romo-select-dropdown-filter-indicator') !== undefined) {
Romo.setData(this.elem, 'romo-option-list-dropdown-filter-indicator', Romo.data(this.elem, 'romo-select-dropdown-filter-indicator'));
}
if (Romo.data(this.elem, 'romo-select-dropdown-filter-indicator-width-px') !== undefined) {
Romo.setData(this.elem, 'romo-option-list-dropdown-filter-indicator-width-px', Romo.data(this.elem, 'romo-select-dropdown-filter-indicator-width-px'));
}
if (Romo.data(this.elem, 'romo-select-dropdown-open-on-focus') !== undefined) {
Romo.setData(this.elem, 'romo-option-list-dropdown-open-on-focus', Romo.data(this.elem, 'romo-select-dropdown-open-on-focus'));
}
Romo.on(this.elem, 'romoOptionListDropdown:romoDropdown:toggle', Romo.proxy(function(e, romoDropdown) {
Romo.trigger(this.elem, 'romoSelectDropdown:romoDropdown:toggle', [romoDropdown, this]);
}, this));
Romo.on(this.elem, 'romoOptionListDropdown:romoDropdown:popupOpen', Romo.proxy(function(e, romoDropdown) {
Romo.trigger(this.elem, 'romoSelectDropdown:romoDropdown:popupOpen', [romoDropdown, this]);
}, this));
Romo.on(this.elem, 'romoOptionListDropdown:romoDropdown:popupClose', Romo.proxy(function(e, romoDropdown) {
Romo.trigger(this.elem, 'romoSelectDropdown:romoDropdown:popupClose', [romoDropdown, this]);
}, this));
Romo.on(this.elem, 'romoOptionListDropdown:itemSelected', Romo.proxy(function(e, itemValue, itemDisplayText, romoOptionListDropdown) {
Romo.trigger(this.elem, 'romoSelectDropdown:itemSelected', [itemValue, itemDisplayText, this]);
}, this));
Romo.on(this.elem, 'romoOptionListDropdown:newItemSelected', Romo.proxy(function(e, itemValue, itemDisplayText, romoOptionListDropdown) {
var custOptElem = Romo.find(this.optionElemsParentElem, 'OPTION[data-romo-select-dropdown-custom-option="true"]')[0];
if (Romo.find(this.optionElemsParentElem, 'OPTION[value="'+itemValue+'"]').length === 0){
// a custom value is being selected. add a custom option elem and update its value/text
if (custOptElem === undefined) {
Romo.appendHtml(this.optionElemsParentElem, '');
custOptElem = Romo.find(this.optionElemsParentElem, 'OPTION[data-romo-select-dropdown-custom-option="true"]')[0];
}
Romo.setAttr(custOptElem, 'value', itemValue);
Romo.updateText(custOptElem, itemDisplayText);
} else if (custOptElem !== undefined) {
// a non custom value is being selected. remove any existing custom option
Romo.remove(custOptElem);
}
Romo.trigger(this.elem, 'romoSelectDropdown:newItemSelected', [itemValue, itemDisplayText, this]);
}, this));
Romo.on(this.elem, 'romoOptionListDropdown:change', Romo.proxy(function(e, newValue, prevValue, romoOptionListDropdown) {
Romo.trigger(this.elem, 'romoSelectDropdown:change', [newValue, prevValue, this]);
}, this));
Romo.on(this.elem, 'romoSelectDropdown:triggerToggle', Romo.proxy(function(e) {
Romo.trigger(this.elem, 'romoOptionListDropdown:triggerToggle', []);
}, this));
Romo.on(this.elem, 'romoSelectDropdown:triggerPopupOpen', Romo.proxy(function(e) {
Romo.trigger(this.elem, 'romoOptionListDropdown:triggerPopupOpen', []);
}, this));
Romo.on(this.elem, 'romoSelectDropdown:triggerPopupClose', Romo.proxy(function(e) {
Romo.trigger(this.elem, 'romoOptionListDropdown:triggerPopupClose', []);
}, this));
this.romoOptionListDropdown = new RomoOptionListDropdown(this.elem);
Romo.on(this.elem, 'romoOptionListDropdown:filterChange', Romo.proxy(function(e, filterValue, romoOptionListDropdown) {
var elems = Romo.find(this.optionElemsParentElem, 'OPTION');
var wbFilter = new RomoWordBoundaryFilter(filterValue, elems, function(elem) {
// The romo word boundary filter by default considers a space, "-" and "_"
// as word boundaries. We want to also consider other non-word characters
// (such as ":", "/", ".", "?", "=", "&") as word boundaries as well.
return elem.textContent.replace(/\W/g, ' ');
});
Romo.removeClass(wbFilter.matchingElems, this.filterHiddenClass);
Romo.addClass(wbFilter.notMatchingElems, this.filterHiddenClass);
this._setListItems();
if (filterValue !== '') {
Romo.trigger(this.romoOptionListDropdown.elem, 'romoOptionListDropdown:triggerListOptionsUpdate', [this.optItemElems()[0]]);
} else {
Romo.trigger(this.elem, 'romoOptionListDropdown:triggerListOptionsUpdate', [this.selectedItemElem()]);
}
}, this));
this._sanitizeOptions();
this._setListItems();
Romo.trigger(this.elem, 'romoOptionListDropdown:triggerListOptionsUpdate', [this.selectedItemElem()]);
if (Romo.attr(this.elem, 'id') !== undefined) {
var labelElem = Romo.f('label[for="'+Romo.attr(this.elem, 'id')+'"]');
Romo.on(labelElem, 'click', Romo.proxy(function(e) {
e.preventDefault();
this.elem.focus();
}, this));
}
}
RomoSelectDropdown.prototype._sanitizeOptions = function() {
// set any options without a value to value=""
// all options are required to have a value for things to work
// this and the select component assume value attrs for all options
Romo.find(this.optionElemsParentElem, 'OPTION').forEach(Romo.proxy(function(optElem) {
if (Romo.attr(optElem, 'value') === undefined) {
Romo.setAttr(optElem, 'value', '');
}
}, this));
}
RomoSelectDropdown.prototype._setListItems = function() {
var optElems = Romo.children(this.optionElemsParentElem, this.optionElemSelector);
var items = this._buildOptionListItems(optElems).concat(this._buildCustomOptionItems());
this.romoOptionListDropdown.doSetListItems(items);
}
RomoSelectDropdown.prototype._buildOptionListItems = function(optionElems) {
var list = [];
optionElems.forEach(Romo.proxy(function(optElem) {
if (optElem.tagName === "OPTION") {
list.push(this._buildOptionItem(optElem));
} else if (optElem.tagName === "OPTGROUP") {
var optGroupItem = this._buildOptGroupItem(optElem);
if (optGroupItem.items.length !== 0) {
list.push(optGroupItem);
}
}
}, this));
return list;
}
RomoSelectDropdown.prototype._buildOptionItem = function(optionElem) {
var item = {}
item['type'] = 'option';
item['value'] = (Romo.attr(optionElem, 'value') || '');
item['displayText'] = (optionElem.innerText.trim() || '');
item['displayHtml'] = (optionElem.innerText.trim() || ' ');
if (optionElem.selected) {
item['selected'] = true;
}
if (Romo.attr(optionElem, 'disabled') !== undefined) {
item['disabled'] = true;
}
return item;
}
RomoSelectDropdown.prototype._buildOptGroupItem = function(optGroupElem) {
var item = {};
item['type'] = 'optgroup';
item['label'] = Romo.attr(optGroupElem, 'label');
item['items'] = this._buildOptionListItems(Romo.children(optGroupElem, this.optionElemSelector));
return item;
}
RomoSelectDropdown.prototype._buildCustomOptionItems = function() {
var items = [];
var value = this.romoOptionListDropdown.optionFilterValue();
if (value !== '' && Romo.data(this.elem, 'romo-select-dropdown-custom-option') === true) {
var prompt = Romo.data(this.elem, 'romo-select-dropdown-custom-option-prompt');
if (prompt !== undefined) {
items.push({
'type': 'optgroup',
'label': prompt,
'items': [this._buildCustomOptionItem(value)]
});
} else {
items.push(this._buildCustomOptionItem(value));
}
}
return items;
}
RomoSelectDropdown.prototype._buildCustomOptionItem = function(value) {
return {
'type': 'option',
'value': value,
'displayText': value,
'displayHtml': value
};
}
// event functions
// init
Romo.addElemsInitSelector('[data-romo-select-dropdown-auto="true"]', RomoSelectDropdown);