Created
April 3, 2016 14:11
-
-
Save mkkeck/6315c8861600da3de9ff2114ab0ccf16 to your computer and use it in GitHub Desktop.
ComboBox Widget for jQuery UI v. 1.11.x
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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