Skip to content

Instantly share code, notes, and snippets.

@mkkeck
Created April 3, 2016 14:11
Show Gist options
  • Save mkkeck/6315c8861600da3de9ff2114ab0ccf16 to your computer and use it in GitHub Desktop.
Save mkkeck/6315c8861600da3de9ff2114ab0ccf16 to your computer and use it in GitHub Desktop.
ComboBox Widget for jQuery UI v. 1.11.x
/**
* ui combobox 1.1
* ComboBox Widget for jQuery UI
*
*
* Copyright (c) 2015-2016 Michael Keck
* (https://github.com/mkkeck/jquery-ui-icons)
* Licensed under the GPL license:
* http://www.gnu.org/licenses/gpl.html
*
* Modified: Michael Keck, 2016-02-23
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
* jquery.ui.autocomplete.js
* jquery.ui.button.js
*
*
* Usage:
* $('selector').combobox({
* focus: function(event, ui) {
* // ...
* },
* select: function(event, ui) {
* // ...
* }
* });
*/
(function($, undef) {
if ($.widget === undef || !$.ui.autocomplete) {
return;
}
$.widget('ui.combobox', $.ui.autocomplete, {
_create: function() {
this.wrapper = $('<span>')
.addClass('ui-combobox ui-front ui-corner-all ui-state-default')
.insertAfter(this.element);
this.element.hide();
this.elementId = this.element.attr('id') || null;
this.id = (this.elementId ? this.elementId+'-autocomplete' : null);
this.label = $('label[for="'+this.elementId+'"]') || null;
this._createAutocomplete();
this._createShowAllButton();
},
_createAutocomplete: function() {
var selected = this.element.children(':selected'),
value = selected.val() ? selected.text() : '',
wrapper = this.wrapper;
this.input = $('<input type="text" />')
.appendTo(wrapper)
.val(value)
.on('focus', function() { wrapper.addClass('ui-state-focus'); $(this).select(); })
.on('blur', function() { wrapper.removeClass('ui-state-focus'); })
.autocomplete({ delay: 0, minLength: 0, source: $.proxy(this, '_source') });
if (this.elementId && this.id) {
this.input.attr({'id':this.id});
if (this.label) {
this.label.attr({'for':this.id});
}
}
this._on( this.input, {
autocompleteselect: function(event, ui) {
ui.item.option.selected = true;
this._trigger('select', event, { item: ui.item.option });
},
autocompletechange: '_removeIfInvalid'
});
this.input.autocomplete('widget');
},
_createShowAllButton: function() {
var input = this.input,
opened = false;
$('<a>')
.attr('tabIndex', -1)
.appendTo(this.wrapper)
.button({ icons: { 'primary': 'ui-icon-triangle-1-s' }, text: false })
.on('mousedown', this, function() {
opened = input.autocomplete('widget').is(':visible');
})
.on('click', this, function() {
input.focus();
if (opened) {
return;
}
input.autocomplete('search', '');
});
},
_source: function(request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), 'i');
response(this.element.children('option').map(function() {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text))) {
return { label: text, value: text, option: this };
}
}));
},
_removeIfInvalid: function(event, ui) {
if (ui.item) {
return;
}
var v = this.input.val(), r = false, c = this.element.children(':selected').text();
this.element.children('option').each(function(k, o) {
if ($(o).text().toLowerCase() === v.toLowerCase()) {
o.selected = true; r = true;
return false;
}
});
if (r) {
return;
}
this.input.val('Item not found').addClass('ui-state-error');
this.element.val(c);
this._delay(function() {
this.input.val(c).removeClass('ui-state-error');
}, 1500);
this.input.autocomplete('instance').term = '';
},
_destroy: function() {
this.wrapper.remove();
if (this.label && this.elementId) {
this.label.attr({'id': this.elementId});
}
this.element.show();
},
widget: function() {
return this.input.autocomplete('widget');
}
});
})(jQuery, undefined);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment