1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
| !function( $ ) {
"use strict";
var Combobox = function ( element, options ) {
this.options = $.extend({}, $.fn.combobox.defaults, options)
this.source = this.options.source
this.$element = $(element)
this.$content = this.setup()
this.$button = this.$element.parent().find('.dropdown-toggle')
this.$menu = $(this.options.menu)
this.matcher = this.options.matcher || this.matcher
this.sorter = this.options.sorter || this.sorter
this.highlighter = this.options.highlighter || this.highlighter
this.shown = false
this.selected = false
this.listen()
}
/* NOTE: COMBOBOX EXTENDS BOOTSTRAP-TYPEAHEAD.js
========================================== */
Combobox.prototype = $.extend({}, $.fn.typeahead.Constructor.prototype, {
constructor: Combobox
, setup: function () {
var combobox = $( this.options.wrapper )
this.$element.wrap( combobox )
this.$element.after( $( this.options.template ) )
return combobox
}
, toggle: function () {
var that = this
var items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
this.$element.focus()
items = $(items).map(function (i, item) {
i = $(that.options.item).attr('data-value', item)
i.find('a').html(item)
return i[0]
})
items.first().addClass('active')
this.$menu.html(items)
this.show( )
}
// modified typeahead function adding container and target handling
, select: function () {
var val = this.$menu.find('.active').attr('data-value')
this.$element.val(this.updater(val)).trigger('change').addClass('combobox-selected')
this.selected = true
return this.hide()
}
// modified typeahead function adding button handling and remove mouseleave
, listen: function () {
this.$element
.on('focus', $.proxy(this.focus, this))
.on('blur', $.proxy(this.blur, this))
.on('keypress', $.proxy(this.keypress, this))
.on('keyup', $.proxy(this.keyup, this))
if (this.eventSupported('keydown')) {
this.$element.on('keydown', $.proxy(this.keydown, this))
}
this.$menu
.on('click', $.proxy(this.click, this))
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
.on('mouseleave', 'li', $.proxy(this.mouseleave, this))
.on('mousedown', $.proxy(this.mousedown, this))
this.$button
.on('click', $.proxy(this.toggle, this))
}
// modified typeahead function to clear on type and prevent on moving around
, keyup: function (e) {
switch(e.keyCode) {
case 40: // down arrow
case 39: // right arrow
case 38: // up arrow
case 37: // left arrow
case 36: // home
case 35: // end
case 16: // shift
case 17: // ctrl
case 18: // alt
break
case 9: // tab
case 13: // enter
if (!this.shown) return
this.select()
break
case 27: // escape
if (!this.shown) return
this.hide()
break
default:
// this.clearTarget()
this.lookup()
}
e.stopPropagation()
e.preventDefault()
}
// modified typeahead function to force a match and add a delay on hide
, blur: function (e) {
var that = this
this.focused = false
var val = this.$element.val()
if (!this.selected && val !== '' ) {
this.$element.val('').trigger('change')
}
if (!this.mousedover && this.shown) setTimeout(function () { that.hide() }, 200)
}
// modified typeahead function to not hide
, mouseleave: function (e) {
this.mousedover = false
}
, mousedown: function(e) {
e.preventDefault()
}
})
/* COMBOBOX PLUGIN DEFINITION
* =========================== */
$.fn.combobox = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('combobox')
, options = typeof option == 'object' && option
if(!data) $this.data('combobox', (data = new Combobox(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.combobox.defaults = {
wrapper: '<div class="input-append controls span11 btn-group"> </div>'
, template: '<span class="add-on btn dropdown-toggle" data-toggle="dropdown"> <span class="caret"></span> </span>'
, menu: '<ul class="typeahead typeahead-long dropdown-menu"></ul>'
, item: '<li><a href="#"></a></li>'
}
$.fn.combobox.Constructor = Combobox
}( window.jQuery ); |
Partager