mirror of
https://github.com/wintercms/winter.git
synced 2024-06-28 05:33:29 +02:00
Modify autocomplete so it can handle objects { value: 'something', label: 'Something' }
This commit is contained in:
parent
6fcc845bf9
commit
9399bc2090
@ -7,6 +7,9 @@
|
||||
* JavaScript API:
|
||||
* $('input').autocomplete()
|
||||
*
|
||||
* Forked by daftspunk:
|
||||
*
|
||||
* - Source can be an object { value: 'something', label: 'Something' }
|
||||
*/
|
||||
|
||||
!function($){
|
||||
@ -32,21 +35,21 @@
|
||||
|
||||
Autocomplete.prototype = {
|
||||
|
||||
constructor: Autocomplete
|
||||
constructor: Autocomplete,
|
||||
|
||||
, select: function () {
|
||||
select: function () {
|
||||
var val = this.$menu.find('.active').attr('data-value')
|
||||
this.$element
|
||||
.val(this.updater(val))
|
||||
.change()
|
||||
return this.hide()
|
||||
}
|
||||
},
|
||||
|
||||
, updater: function (item) {
|
||||
updater: function (item) {
|
||||
return item
|
||||
}
|
||||
},
|
||||
|
||||
, show: function () {
|
||||
show: function () {
|
||||
var pos = $.extend({}, this.$element.position(), {
|
||||
height: this.$element[0].offsetHeight
|
||||
})
|
||||
@ -61,15 +64,15 @@
|
||||
|
||||
this.shown = true
|
||||
return this
|
||||
}
|
||||
},
|
||||
|
||||
, hide: function () {
|
||||
hide: function () {
|
||||
this.$menu.hide()
|
||||
this.shown = false
|
||||
return this
|
||||
}
|
||||
},
|
||||
|
||||
, lookup: function (event) {
|
||||
lookup: function (event) {
|
||||
var items
|
||||
|
||||
this.query = this.$element.val()
|
||||
@ -81,9 +84,23 @@
|
||||
items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
|
||||
|
||||
return items ? this.process(items) : this
|
||||
}
|
||||
},
|
||||
|
||||
, process: function (items) {
|
||||
itemValue: function (item) {
|
||||
if (typeof item === 'object')
|
||||
return item.value;
|
||||
|
||||
return item;
|
||||
},
|
||||
|
||||
itemLabel: function (item) {
|
||||
if (typeof item === 'object')
|
||||
return item.label;
|
||||
|
||||
return item;
|
||||
},
|
||||
|
||||
process: function (items) {
|
||||
var that = this
|
||||
|
||||
items = $.grep(items, function (item) {
|
||||
@ -97,71 +114,73 @@
|
||||
}
|
||||
|
||||
return this.render(items.slice(0, this.options.items)).show()
|
||||
}
|
||||
},
|
||||
|
||||
, matcher: function (item) {
|
||||
return ~item.toLowerCase().indexOf(this.query.toLowerCase())
|
||||
}
|
||||
matcher: function (item) {
|
||||
return ~this.itemValue(item).toLowerCase().indexOf(this.query.toLowerCase())
|
||||
},
|
||||
|
||||
, sorter: function (items) {
|
||||
var beginswith = []
|
||||
, caseSensitive = []
|
||||
, caseInsensitive = []
|
||||
, item
|
||||
sorter: function (items) {
|
||||
var beginswith = [],
|
||||
caseSensitive = [],
|
||||
caseInsensitive = [],
|
||||
item,
|
||||
itemValue
|
||||
|
||||
while (item = items.shift()) {
|
||||
if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
|
||||
else if (~item.indexOf(this.query)) caseSensitive.push(item)
|
||||
itemValue = this.itemValue(item)
|
||||
if (!itemValue.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
|
||||
else if (~itemValue.indexOf(this.query)) caseSensitive.push(item)
|
||||
else caseInsensitive.push(item)
|
||||
}
|
||||
|
||||
return beginswith.concat(caseSensitive, caseInsensitive)
|
||||
}
|
||||
},
|
||||
|
||||
, highlighter: function (item) {
|
||||
highlighter: function (item) {
|
||||
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
|
||||
return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
|
||||
return '<strong>' + match + '</strong>'
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
, render: function (items) {
|
||||
render: function (items) {
|
||||
var that = this
|
||||
|
||||
items = $(items).map(function (i, item) {
|
||||
i = $(that.options.item).attr('data-value', item)
|
||||
i.find('a').html(that.highlighter(item))
|
||||
i = $(that.options.item).attr('data-value', that.itemValue(item))
|
||||
i.find('a').html(that.highlighter(that.itemLabel(item)))
|
||||
return i[0]
|
||||
})
|
||||
|
||||
items.first().addClass('active')
|
||||
this.$menu.html(items)
|
||||
return this
|
||||
}
|
||||
},
|
||||
|
||||
, next: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active')
|
||||
, next = active.next()
|
||||
next: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active'),
|
||||
next = active.next()
|
||||
|
||||
if (!next.length) {
|
||||
next = $(this.$menu.find('li')[0])
|
||||
}
|
||||
|
||||
next.addClass('active')
|
||||
}
|
||||
},
|
||||
|
||||
, prev: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active')
|
||||
, prev = active.prev()
|
||||
prev: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active'),
|
||||
prev = active.prev()
|
||||
|
||||
if (!prev.length) {
|
||||
prev = this.$menu.find('li').last()
|
||||
}
|
||||
|
||||
prev.addClass('active')
|
||||
}
|
||||
},
|
||||
|
||||
, listen: function () {
|
||||
listen: function () {
|
||||
this.$element
|
||||
.on('focus', $.proxy(this.focus, this))
|
||||
.on('blur', $.proxy(this.blur, this))
|
||||
@ -176,18 +195,18 @@
|
||||
.on('click', $.proxy(this.click, this))
|
||||
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
|
||||
.on('mouseleave', 'li', $.proxy(this.mouseleave, this))
|
||||
}
|
||||
},
|
||||
|
||||
, eventSupported: function(eventName) {
|
||||
eventSupported: function(eventName) {
|
||||
var isSupported = eventName in this.$element
|
||||
if (!isSupported) {
|
||||
this.$element.setAttribute(eventName, 'return;')
|
||||
isSupported = typeof this.$element[eventName] === 'function'
|
||||
}
|
||||
return isSupported
|
||||
}
|
||||
},
|
||||
|
||||
, move: function (e) {
|
||||
move: function (e) {
|
||||
if (!this.shown) return
|
||||
|
||||
switch(e.keyCode) {
|
||||
@ -209,19 +228,19 @@
|
||||
}
|
||||
|
||||
e.stopPropagation()
|
||||
}
|
||||
},
|
||||
|
||||
, keydown: function (e) {
|
||||
keydown: function (e) {
|
||||
this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
|
||||
this.move(e)
|
||||
}
|
||||
},
|
||||
|
||||
, keypress: function (e) {
|
||||
keypress: function (e) {
|
||||
if (this.suppressKeyPressRepeat) return
|
||||
this.move(e)
|
||||
}
|
||||
},
|
||||
|
||||
, keyup: function (e) {
|
||||
keyup: function (e) {
|
||||
switch(e.keyCode) {
|
||||
case 40: // down arrow
|
||||
case 38: // up arrow
|
||||
@ -247,31 +266,31 @@
|
||||
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
},
|
||||
|
||||
, focus: function (e) {
|
||||
focus: function (e) {
|
||||
this.focused = true
|
||||
}
|
||||
},
|
||||
|
||||
, blur: function (e) {
|
||||
blur: function (e) {
|
||||
this.focused = false
|
||||
if (!this.mousedover && this.shown) this.hide()
|
||||
}
|
||||
},
|
||||
|
||||
, click: function (e) {
|
||||
click: function (e) {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.select()
|
||||
this.$element.focus()
|
||||
}
|
||||
},
|
||||
|
||||
, mouseenter: function (e) {
|
||||
mouseenter: function (e) {
|
||||
this.mousedover = true
|
||||
this.$menu.find('.active').removeClass('active')
|
||||
$(e.currentTarget).addClass('active')
|
||||
}
|
||||
},
|
||||
|
||||
, mouseleave: function (e) {
|
||||
mouseleave: function (e) {
|
||||
this.mousedover = false
|
||||
if (!this.focused && this.shown) this.hide()
|
||||
}
|
||||
@ -295,11 +314,11 @@
|
||||
}
|
||||
|
||||
$.fn.autocomplete.defaults = {
|
||||
source: []
|
||||
, items: 8
|
||||
, menu: '<ul class="autocomplete dropdown-menu"></ul>'
|
||||
, item: '<li><a href="#"></a></li>'
|
||||
, minLength: 1
|
||||
source: [],
|
||||
items: 8,
|
||||
menu: '<ul class="autocomplete dropdown-menu"></ul>',
|
||||
item: '<li><a href="#"></a></li>',
|
||||
minLength: 1
|
||||
}
|
||||
|
||||
$.fn.autocomplete.Constructor = Autocomplete
|
||||
|
Loading…
x
Reference in New Issue
Block a user