Skip to content
Snippets Groups Projects
Commit 24b69f72 authored by Chris Hallberg's avatar Chris Hallberg
Browse files

Update to autocomplete.js v0.17.0

parent ed2621c4
No related merge requests found
...@@ -246,10 +246,8 @@ function setupAutocomplete() { ...@@ -246,10 +246,8 @@ function setupAutocomplete() {
if (searchbox.length < 1) { if (searchbox.length < 1) {
return; return;
} }
var cacheObj = {};
// Search autocomplete // Search autocomplete
searchbox.autocomplete({ searchbox.autocomplete({
cacheObj: cacheObj,
maxResults: 10, maxResults: 10,
loadingString: VuFind.translate('loading') + '...', loadingString: VuFind.translate('loading') + '...',
handler: function vufindACHandler(input, cb) { handler: function vufindACHandler(input, cb) {
...@@ -285,11 +283,7 @@ function setupAutocomplete() { ...@@ -285,11 +283,7 @@ function setupAutocomplete() {
}); });
// Update autocomplete on type change // Update autocomplete on type change
$('#searchForm_type').change(function searchTypeChange() { $('#searchForm_type').change(function searchTypeChange() {
for (var i in cacheObj) { searchbox.autocomplete().clearCache();
for (var j in cacheObj[i]) {
delete cacheObj[i][j];
}
}
}); });
} }
......
/* https://github.com/vufind-org/autocomplete.js 1.0b */ /* https://github.com/vufind-org/autocomplete.js 1.0b2 */
(function autocomplete( $ ) { (function autocomplete($) {
var element = false, var element = false,
cache = {},
optionStorage = {},
xhr = false; xhr = false;
function Factory(_input, settings) { function Factory(_input, settings) {
var cache = (typeof(settings) === "object" && typeof(settings.cacheObj) === "object") return function acClosure() {
? settings.cacheObj : {}; var input = $(this);
return (function acClosure() { var options = optionStorage[input.data('ac-id')];
var input = $(this),
options;
var _align = function _align() { var _align = function _align() {
var position = input.offset(); var position = input.offset();
...@@ -17,61 +17,67 @@ ...@@ -17,61 +17,67 @@
left: position.left, left: position.left,
minWidth: input.width() minWidth: input.width()
}); });
} };
var show = function show() { var _show = function _show() {
element.removeClass(options.hidingClass); element.removeClass(options.hidingClass);
} };
var hide = function hide() { var hide = function hide() {
element.addClass(options.hidingClass); element.addClass(options.hidingClass);
} };
var _populate = function _populate(item, eventType) { var _populate = function _populate(item, eventType) {
input.trigger('ac:select', [item, eventType]);
var ret;
if (options.callback) { if (options.callback) {
if (options.callback(item, input, eventType) === true && typeof item.href !== 'undefined') { ret = options.callback(item, input, eventType);
if (ret === true && typeof item.href !== 'undefined') {
return window.location.assign(item.href); return window.location.assign(item.href);
} }
if (ret === false) {
return false;
}
} else if (typeof item.href !== 'undefined') { } else if (typeof item.href !== 'undefined') {
return window.location.assign(item.href); return window.location.assign(item.href);
} }
input.val(item.value); input.val(typeof ret === 'undefined' ? item.value : ret);
// Reset // Reset
element.find('.ac-item.selected').removeClass('selected'); element.find('.ac-item.selected').removeClass('selected');
$(this).data('selected', -1); $(this).data('ac-selected', -1);
setTimeout(function acPopulateDelay() { setTimeout(function acPopulateDelay() {
input.focus(); input.focus();
hide(); hide();
}, 10); }, 10);
} };
var _listToHTML = function _listToHTML(list, regex) { var _listToHTML = function _listToHTML(list, regex) {
var shell = $('<div/>'); var shell = $('<div/>');
for (var i = 0; i < list.length; i++) { for (var i = 0; i < list.length; i++) {
if (typeof list[i] === 'string') { if (typeof list[i] === 'string') {
list[i] = {value: list[i]}; list[i] = { value: list[i] };
} }
var content = list[i].label || list[i].value; var content = list[i].label || list[i].value;
if (options.highlight) { if (options.highlight) {
content = content.replace(regex, '<b>$1</b>'); content = content.replace(regex, '<b>$1</b>');
} }
var item = typeof list[i].href === 'undefined' var item = typeof list[i].href === 'undefined' ? $('<div/>') : $('<a/>').attr('href', list[i].href);
? $('<div/>')
: $('<a/>').attr('href', list[i].href);
// list // list
item.data(list[i]) item
.addClass('ac-item') .data(list[i])
.html(content); .addClass('ac-item')
.html(content);
if (typeof list[i].description !== 'undefined') { if (typeof list[i].description !== 'undefined') {
item.append($('<small/>').html( item.append(
options.highlight $('<small/>').html(
? list[i].description.replace(regex, '<b>$1</b>') options.highlight ? list[i].description.replace(regex, '<b>$1</b>') : list[i].description
: list[i].description )
)); );
} }
shell.append(item); shell.append(item);
} }
input.trigger('ac:render', [shell[0]]);
return shell; return shell;
} };
var _createList = function _createList(data) { var _createList = function _createList(data) {
// highlighting setup // highlighting setup
// escape term for regex - https://github.com/sindresorhus/escape-string-regexp/blob/master/index.js // escape term for regex - https://github.com/sindresorhus/escape-string-regexp/blob/master/index.js
...@@ -87,10 +93,12 @@ ...@@ -87,10 +93,12 @@
shell.append($('<hr/>', { class: 'ac-section-divider' })); shell.append($('<hr/>', { class: 'ac-section-divider' }));
} }
if (typeof data.groups[i].label !== 'undefined') { if (typeof data.groups[i].label !== 'undefined') {
shell.append($('<header>', { shell.append(
class: 'ac-section-header', $('<header>', {
html: data.groups[i].label class: 'ac-section-header',
})); html: data.groups[i].label
})
);
} }
if (typeof data.groups[i].label !== 'undefined' && data.groups[i].items.length > 0) { if (typeof data.groups[i].label !== 'undefined' && data.groups[i].items.length > 0) {
shell.append(_listToHTML(data.groups[i].items, regex)); shell.append(_listToHTML(data.groups[i].items, regex));
...@@ -100,29 +108,31 @@ ...@@ -100,29 +108,31 @@
} }
} }
element.html(shell); element.html(shell);
input.data('length', shell.find('.ac-item').length); input.data('ac-length', shell.find('.ac-item').length);
element.find('.ac-item').mousedown(function acItemClick() { element.find('.ac-item').mousedown(function acItemClick() {
_populate($(this).data(), {mouse: true}); _populate($(this).data(), { mouse: true });
}); });
_align(); _align();
} };
var _handleResults = function _handleResults(term, _data) { var _handleResults = function _handleResults(term, _data) {
// Limit results // Limit results
var data = typeof _data.groups === 'undefined' var data =
? _data.slice(0, Math.min(options.maxResults, _data.length)) typeof _data.groups === 'undefined'
: _data; ? _data.slice(0, Math.min(options.maxResults, _data.length))
var cid = input.data('cacheId'); : _data;
var cid = input.data('ac-id');
cache[cid][term] = data; cache[cid][term] = data;
if (data.length === 0 || (typeof data.groups !== 'undefined' && data.groups.length === 0)) { if (data.length === 0 || (typeof data.groups !== 'undefined' && data.groups.length === 0)) {
hide(); hide();
} else { } else {
_createList(data); _createList(data);
} }
} };
var _defaultStaticSort = function _defaultStaticSort(a, b) { // .bind(lcterm) var _defaultStaticSort = function _defaultStaticSort(a, b) {
// .bind(lcterm)
return a.match.indexOf(this) - b.match.indexOf(this); return a.match.indexOf(this) - b.match.indexOf(this);
} };
var _staticGroups = function _staticGroups(lcterm) { var _staticGroups = function _staticGroups(lcterm) {
var matches = []; var matches = [];
for (var i = 0; i < options.static.groups.length; i++) { for (var i = 0; i < options.static.groups.length; i++) {
...@@ -156,24 +166,26 @@ ...@@ -156,24 +166,26 @@
} }
} }
return matches; return matches;
} };
var search = function search() { var search = function search() {
if (xhr) { xhr.abort(); } if (xhr) {
xhr.abort();
}
if (input.val().length >= options.minLength) { if (input.val().length >= options.minLength) {
element.html('<i class="ac-item loading">' + options.loadingString + '</i>'); element.html('<i class="ac-item loading">' + options.loadingString + '</i>');
show(); _show();
_align(); _align();
input.data('selected', -1); input.data('ac-selected', -1);
var term = input.val(); var term = input.val();
// Check cache (only for handler-based setups) // Check cache (only for handler-based setups)
var cid = input.data('cacheId'); var cid = input.data('ac-id');
if (options.cache && typeof cache[cid][term] !== "undefined") { if (options.cache && typeof cache[cid][term] !== 'undefined') {
if (cache[cid][term].length === 0) { if (cache[cid][term].length === 0) {
hide(); hide();
} else { } else {
_createList(cache[cid][term]); _createList(cache[cid][term]);
} }
// Check for static list // Check for static list
} else if (typeof options.static !== 'undefined') { } else if (typeof options.static !== 'undefined') {
var lcterm = term.toLowerCase(); var lcterm = term.toLowerCase();
var matches; var matches;
...@@ -190,7 +202,7 @@ ...@@ -190,7 +202,7 @@
} }
} }
_handleResults(term, matches); _handleResults(term, matches);
// Call handler // Call handler
} else { } else {
options.handler(input, function achandlerCallback(data) { options.handler(input, function achandlerCallback(data) {
_handleResults(term, data); _handleResults(term, data);
...@@ -199,16 +211,26 @@ ...@@ -199,16 +211,26 @@
} else { } else {
hide(); hide();
} }
} };
function preprocessStatic(_item) { function preprocessStatic(_item) {
var item = typeof _item === 'string' var item = typeof _item === 'string' ? { value: _item } : _item;
? { value: _item }
: _item;
item.match = (item.label || item.value).toLowerCase(); item.match = (item.label || item.value).toLowerCase();
return item; return item;
} }
var _setup = function _setup() { var _setup = function _setup(settings) {
var cid = Math.floor(Math.random() * 1000);
input.data('ac-id', cid);
input.data('ac-selected', -1);
input.data('ac-length', 0);
options = $.extend({}, $.fn.autocomplete.defaults, settings);
optionStorage[input.data('ac-id')] = options;
if (options.cache) {
cache[cid] = {};
}
element = $('.autocomplete-results'); element = $('.autocomplete-results');
if (element.length === 0) { if (element.length === 0) {
element = $('<div/>') element = $('<div/>')
...@@ -218,15 +240,6 @@ ...@@ -218,15 +240,6 @@
$(document.body).append(element); $(document.body).append(element);
} }
input.data('selected', -1);
input.data('length', 0);
if (options.cache) {
var cid = Math.floor(Math.random() * 1000);
input.data('cacheId', cid);
cache[cid] = {};
}
input.blur(function acinputBlur(e) { input.blur(function acinputBlur(e) {
if (e.target.acitem) { if (e.target.acitem) {
setTimeout(hide, 10); setTimeout(hide, 10);
...@@ -240,6 +253,9 @@ ...@@ -240,6 +253,9 @@
input.focus(function acinputFocus() { input.focus(function acinputFocus() {
search(); search();
}); });
input.on('paste', function acinputPaste() {
requestAnimationFrame(search);
});
input.keyup(function acinputKeyup(event) { input.keyup(function acinputKeyup(event) {
// Ignore navigation keys // Ignore navigation keys
// - Ignore control functions // - Ignore control functions
...@@ -251,26 +267,26 @@ ...@@ -251,26 +267,26 @@
return; return;
} }
switch (event.which) { switch (event.which) {
case 9: // tab case 9: // tab
case 13: // enter case 13: // enter
case 16: // shift case 16: // shift
case 20: // caps lock case 20: // caps lock
case 27: // esc case 27: // esc
case 33: // page up case 33: // page up
case 34: // page down case 34: // page down
case 35: // end case 35: // end
case 36: // home case 36: // home
case 37: // arrows case 37: // arrows
case 38: case 38:
case 39: case 39:
case 40: case 40:
case 45: // insert case 45: // insert
case 144: // num lock case 144: // num lock
case 145: // scroll lock case 145: // scroll lock
case 19: // pause/break case 19: // pause/break
return; return;
default: default:
search(); search();
} }
}); });
input.keydown(function acinputKeydown(event) { input.keydown(function acinputKeydown(event) {
...@@ -278,69 +294,63 @@ ...@@ -278,69 +294,63 @@
if (event.ctrlKey || event.which === 17) { if (event.ctrlKey || event.which === 17) {
return; return;
} }
var position = $(this).data('selected'); var position = $(this).data('ac-selected');
switch (event.which) { switch (event.which) {
// arrow keys through items // arrow keys through items
case 38: // up key case 38: // up key
event.preventDefault(); event.preventDefault();
element.find('.ac-item.selected').removeClass('selected'); element.find('.ac-item.selected').removeClass('selected');
if (position > -1) { if (position > -1) {
if (position-- > 0) { if (position-- > 0) {
element.find('.ac-item:eq(' + position + ')').addClass('selected');
}
$(this).data('ac-selected', position);
}
break;
case 40: // down key
event.preventDefault();
if (element.hasClass(options.hidingClass)) {
search();
} else if (position < input.data('ac-length') - 1) {
position++;
element.find('.ac-item.selected').removeClass('selected');
element.find('.ac-item:eq(' + position + ')').addClass('selected'); element.find('.ac-item:eq(' + position + ')').addClass('selected');
$(this).data('ac-selected', position);
} }
$(this).data('selected', position); break;
}
break;
case 40: // down key
event.preventDefault();
if (element.hasClass(options.hidingClass)) {
search();
} else if (position < input.data('length') - 1) {
position++;
element.find('.ac-item.selected').removeClass('selected');
element.find('.ac-item:eq(' + position + ')').addClass('selected');
$(this).data('selected', position);
}
break;
// enter to nav or populate // enter to nav or populate
case 9: case 9:
case 13: case 13:
var selected = element.find('.ac-item.selected'); var selected = element.find('.ac-item.selected');
if (selected.length > 0) { if (selected.length > 0) {
event.preventDefault(); event.preventDefault();
if (event.which === 13 && selected.attr('href')) { if (event.which === 13 && selected.attr('href') && options.callback === 'undefined') {
return window.location.assign(selected.attr('href')); return window.location.assign(selected.attr('href'));
} else { } else {
_populate(selected.data(), $(this), {key: true}); _populate(selected.data(), $(this), { key: true });
}
} }
} break;
break;
// hide on escape // hide on escape
case 27: case 27:
hide(); hide();
$(this).data('selected', -1); $(this).data('ac-selected', -1);
break; break;
} }
}); });
window.addEventListener("resize", hide, false); window.addEventListener('resize', hide, false);
} };
if (typeof settings === "string") { // Setup
if (settings === "show") { if (!input.data('ac-id')) {
show(); if (typeof settings === 'undefined') {
_align(); console.error('Autocomplete not initialized, please pass setup parameters.');
} else if (settings === "hide") { }
hide(); if (typeof settings.handler === 'undefined' && typeof settings.static === 'undefined') {
} else if (options.cache && settings === "clear cache") { console.error('Neither handler function nor static result list provided for autocomplete');
var cid = parseInt(input.data('cacheId'), 10); return null;
cache[cid] = {};
} }
return input;
} else if (typeof settings.handler === 'undefined' && typeof settings.static === 'undefined') {
console.error('Neither handler function nor static result list provided for autocomplete');
return input;
} else {
if (typeof settings.static !== 'undefined') { if (typeof settings.static !== 'undefined') {
// Preprocess strings into items // Preprocess strings into items
if (typeof settings.static.groups !== 'undefined') { if (typeof settings.static.groups !== 'undefined') {
...@@ -355,18 +365,29 @@ ...@@ -355,18 +365,29 @@
settings.static = settings.static.map(preprocessStatic); settings.static = settings.static.map(preprocessStatic);
} }
} }
options = $.extend( {}, $.fn.autocomplete.defaults, settings ); _setup(settings);
_setup();
} }
return input; return {
}.bind(_input))(); show: function show() {
_show();
_align();
},
hide: hide,
search: search,
clearCache: function clearCache() {
cache[input.data('ac-id')] = {};
}
};
}.bind(_input)();
} }
$.fn.autocomplete = function acJQuery(settings) { $.fn.autocomplete = function acJQuery(settings) {
return this.each(function acJQueryEach() { var ac;
return Factory(this, settings); this.each(function acJQueryEach() {
ac = Factory(this, settings);
}); });
return ac;
}; };
$.fn.autocomplete.defaults = { $.fn.autocomplete.defaults = {
...@@ -380,12 +401,14 @@ ...@@ -380,12 +401,14 @@
var timer = false; var timer = false;
$.fn.autocomplete.ajax = function acAjax(ops) { $.fn.autocomplete.ajax = function acAjax(ops) {
if (timer) { clearTimeout(timer); } if (timer) {
if (xhr) { xhr.abort(); } clearTimeout(timer);
timer = setTimeout( }
function acajaxDelay() { xhr = $.ajax(ops); }, if (xhr) {
200 xhr.abort();
); }
timer = setTimeout(function acajaxDelay() {
xhr = $.ajax(ops);
}, 200);
}; };
})(jQuery);
}( jQuery ));
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment