mirror of
https://github.com/devbridge/jQuery-Autocomplete.git
synced 2024-11-09 23:01:00 +00:00
Add lookupLimitOverflowMessage option to local suggest
This commit is contained in:
parent
2b29ca6f64
commit
e5794fc2a9
@ -2,7 +2,7 @@
|
||||
.container { width: 800px; margin: 0 auto; }
|
||||
|
||||
.autocomplete-suggestions { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; border: 1px solid #999; background: #FFF; cursor: default; overflow: auto; -webkit-box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); -moz-box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); }
|
||||
.autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; }
|
||||
.autocomplete-suggestion, .autocomplete-limit-overflow { padding: 2px 5px; white-space: nowrap; overflow: hidden; }
|
||||
.autocomplete-no-suggestion { padding: 2px 5px;}
|
||||
.autocomplete-selected { background: #F0F0F0; }
|
||||
.autocomplete-suggestions strong { font-weight: bold; color: #000; }
|
||||
|
200
dist/jquery.autocomplete.js
vendored
200
dist/jquery.autocomplete.js
vendored
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Ajax Autocomplete for jQuery, version 1.3.0
|
||||
* Ajax Autocomplete for jQuery, version %version%
|
||||
* (c) 2017 Tomas Kirda
|
||||
*
|
||||
* Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
|
||||
@ -49,51 +49,12 @@
|
||||
UP: 38,
|
||||
RIGHT: 39,
|
||||
DOWN: 40
|
||||
};
|
||||
},
|
||||
|
||||
noop = $.noop;
|
||||
|
||||
function Autocomplete(el, options) {
|
||||
var noop = $.noop,
|
||||
that = this,
|
||||
defaults = {
|
||||
ajaxSettings: {},
|
||||
autoSelectFirst: false,
|
||||
appendTo: document.body,
|
||||
serviceUrl: null,
|
||||
lookup: null,
|
||||
onSelect: null,
|
||||
width: 'auto',
|
||||
minChars: 1,
|
||||
maxHeight: 300,
|
||||
deferRequestBy: 0,
|
||||
params: {},
|
||||
formatResult: Autocomplete.formatResult,
|
||||
formatGroup: Autocomplete.formatGroup,
|
||||
delimiter: null,
|
||||
zIndex: 9999,
|
||||
type: 'GET',
|
||||
noCache: false,
|
||||
onSearchStart: noop,
|
||||
onSearchComplete: noop,
|
||||
onSearchError: noop,
|
||||
preserveInput: false,
|
||||
containerClass: 'autocomplete-suggestions',
|
||||
tabDisabled: false,
|
||||
dataType: 'text',
|
||||
currentRequest: null,
|
||||
triggerSelectOnValidInput: true,
|
||||
preventBadQueries: true,
|
||||
lookupFilter: function (suggestion, originalQuery, queryLowerCase) {
|
||||
return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1;
|
||||
},
|
||||
paramName: 'query',
|
||||
transformResult: function (response) {
|
||||
return typeof response === 'string' ? $.parseJSON(response) : response;
|
||||
},
|
||||
showNoSuggestionNotice: false,
|
||||
noSuggestionNotice: 'No results',
|
||||
orientation: 'bottom',
|
||||
forceFixPosition: false
|
||||
};
|
||||
var that = this;
|
||||
|
||||
// Shared variables:
|
||||
that.element = el;
|
||||
@ -102,14 +63,14 @@
|
||||
that.badQueries = [];
|
||||
that.selectedIndex = -1;
|
||||
that.currentValue = that.element.value;
|
||||
that.intervalId = 0;
|
||||
that.timeoutId = null;
|
||||
that.cachedResponse = {};
|
||||
that.onChangeInterval = null;
|
||||
that.onChangeTimeout = null;
|
||||
that.onChange = null;
|
||||
that.isLocal = false;
|
||||
that.suggestionsContainer = null;
|
||||
that.noSuggestionsContainer = null;
|
||||
that.options = $.extend({}, defaults, options);
|
||||
that.options = $.extend({}, Autocomplete.defaults, options);
|
||||
that.classes = {
|
||||
selected: 'autocomplete-selected',
|
||||
suggestion: 'autocomplete-suggestion'
|
||||
@ -117,6 +78,7 @@
|
||||
that.hint = null;
|
||||
that.hintValue = '';
|
||||
that.selection = null;
|
||||
that.realSuggestionsLength = 0;
|
||||
|
||||
// Initialize and set options:
|
||||
that.initialize();
|
||||
@ -127,7 +89,53 @@
|
||||
|
||||
$.Autocomplete = Autocomplete;
|
||||
|
||||
Autocomplete.formatResult = function (suggestion, currentValue) {
|
||||
Autocomplete.defaults = {
|
||||
ajaxSettings: {},
|
||||
autoSelectFirst: false,
|
||||
appendTo: document.body,
|
||||
serviceUrl: null,
|
||||
lookup: null,
|
||||
onSelect: null,
|
||||
width: 'auto',
|
||||
minChars: 1,
|
||||
maxHeight: 300,
|
||||
deferRequestBy: 0,
|
||||
params: {},
|
||||
formatResult: _formatResult,
|
||||
formatGroup: _formatGroup,
|
||||
delimiter: null,
|
||||
zIndex: 9999,
|
||||
type: 'GET',
|
||||
noCache: false,
|
||||
onSearchStart: noop,
|
||||
onSearchComplete: noop,
|
||||
onSearchError: noop,
|
||||
preserveInput: false,
|
||||
containerClass: 'autocomplete-suggestions',
|
||||
tabDisabled: false,
|
||||
dataType: 'text',
|
||||
currentRequest: null,
|
||||
triggerSelectOnValidInput: true,
|
||||
preventBadQueries: true,
|
||||
lookupFilter: _lookupFilter,
|
||||
paramName: 'query',
|
||||
transformResult: _transformResult,
|
||||
showNoSuggestionNotice: false,
|
||||
noSuggestionNotice: 'No results',
|
||||
orientation: 'bottom',
|
||||
forceFixPosition: false,
|
||||
lookupLimitOverflowMessage: null
|
||||
};
|
||||
|
||||
function _lookupFilter(suggestion, originalQuery, queryLowerCase) {
|
||||
return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1;
|
||||
};
|
||||
|
||||
function _transformResult(response) {
|
||||
return typeof response === 'string' ? $.parseJSON(response) : response;
|
||||
};
|
||||
|
||||
function _formatResult(suggestion, currentValue) {
|
||||
// Do not replace anything if there current value is empty
|
||||
if (!currentValue) {
|
||||
return suggestion.value;
|
||||
@ -144,14 +152,12 @@
|
||||
.replace(/<(\/?strong)>/g, '<$1>');
|
||||
};
|
||||
|
||||
Autocomplete.formatGroup = function (suggestion, category) {
|
||||
return '<div class="autocomplete-group"><strong>' + category + '</strong></div>';
|
||||
function _formatGroup(suggestion, category) {
|
||||
return '<div class="autocomplete-group">' + category + '</div>';
|
||||
};
|
||||
|
||||
Autocomplete.prototype = {
|
||||
|
||||
killerFn: null,
|
||||
|
||||
initialize: function () {
|
||||
var that = this,
|
||||
suggestionSelector = '.' + that.classes.suggestion,
|
||||
@ -162,13 +168,6 @@
|
||||
// Remove autocomplete attribute to prevent native suggestions:
|
||||
that.element.setAttribute('autocomplete', 'off');
|
||||
|
||||
that.killerFn = function (e) {
|
||||
if (!$(e.target).closest('.' + that.options.containerClass).length) {
|
||||
that.killSuggestions();
|
||||
that.disableKillerFn();
|
||||
}
|
||||
};
|
||||
|
||||
// html() deals with many types: htmlString or Element or Array or jQuery
|
||||
that.noSuggestionsContainer = $('<div class="autocomplete-no-suggestion"></div>')
|
||||
.html(this.options.noSuggestionNotice).get(0);
|
||||
@ -195,12 +194,16 @@
|
||||
container.children('.' + selected).removeClass(selected);
|
||||
});
|
||||
|
||||
|
||||
// Listen for click event on suggestions list:
|
||||
container.on('click.autocomplete', suggestionSelector, function () {
|
||||
that.select($(this).data('index'));
|
||||
return false;
|
||||
});
|
||||
|
||||
container.on('click.autocomplete', function () {
|
||||
clearTimeout(that.blurTimeoutId);
|
||||
})
|
||||
|
||||
that.fixPositionCapture = function () {
|
||||
if (that.visible) {
|
||||
that.fixPosition();
|
||||
@ -228,7 +231,13 @@
|
||||
},
|
||||
|
||||
onBlur: function () {
|
||||
this.enableKillerFn();
|
||||
var that = this;
|
||||
|
||||
// If user clicked on a suggestion, hide() will
|
||||
// be canceled, otherwise close suggestions
|
||||
that.blurTimeoutId = setTimeout(function () {
|
||||
that.hide();
|
||||
}, 200);
|
||||
},
|
||||
|
||||
abortAjax: function () {
|
||||
@ -276,7 +285,7 @@
|
||||
disable: function () {
|
||||
var that = this;
|
||||
that.disabled = true;
|
||||
clearInterval(that.onChangeInterval);
|
||||
clearTimeout(that.onChangeTimeout);
|
||||
that.abortAjax();
|
||||
},
|
||||
|
||||
@ -344,39 +353,6 @@
|
||||
$container.css(styles);
|
||||
},
|
||||
|
||||
enableKillerFn: function () {
|
||||
var that = this;
|
||||
$(document).on('click.autocomplete', that.killerFn);
|
||||
},
|
||||
|
||||
disableKillerFn: function () {
|
||||
var that = this;
|
||||
$(document).off('click.autocomplete', that.killerFn);
|
||||
},
|
||||
|
||||
killSuggestions: function () {
|
||||
var that = this;
|
||||
that.stopKillSuggestions();
|
||||
that.intervalId = window.setInterval(function () {
|
||||
if (that.visible) {
|
||||
// No need to restore value when
|
||||
// preserveInput === true,
|
||||
// because we did not change it
|
||||
if (!that.options.preserveInput) {
|
||||
that.el.val(that.currentValue);
|
||||
}
|
||||
|
||||
that.hide();
|
||||
}
|
||||
|
||||
that.stopKillSuggestions();
|
||||
}, 50);
|
||||
},
|
||||
|
||||
stopKillSuggestions: function () {
|
||||
window.clearInterval(this.intervalId);
|
||||
},
|
||||
|
||||
isCursorAtEnd: function () {
|
||||
var that = this,
|
||||
valLength = that.el.val().length,
|
||||
@ -467,13 +443,13 @@
|
||||
return;
|
||||
}
|
||||
|
||||
clearInterval(that.onChangeInterval);
|
||||
clearTimeout(that.onChangeTimeout);
|
||||
|
||||
if (that.currentValue !== that.el.val()) {
|
||||
that.findBestHint();
|
||||
if (that.options.deferRequestBy > 0) {
|
||||
// Defer lookup in case when value changes very quickly:
|
||||
that.onChangeInterval = setInterval(function () {
|
||||
that.onChangeTimeout = setTimeout(function () {
|
||||
that.onValueChange();
|
||||
}, that.options.deferRequestBy);
|
||||
} else {
|
||||
@ -493,7 +469,7 @@
|
||||
(options.onInvalidateSelection || $.noop).call(that.element);
|
||||
}
|
||||
|
||||
clearInterval(that.onChangeInterval);
|
||||
clearTimeout(that.onChangeTimeout);
|
||||
that.currentValue = value;
|
||||
that.selectedIndex = -1;
|
||||
|
||||
@ -541,6 +517,8 @@
|
||||
})
|
||||
};
|
||||
|
||||
that.realSuggestionsLength = data.suggestions.length;
|
||||
|
||||
if (limit && data.suggestions.length > limit) {
|
||||
data.suggestions = data.suggestions.slice(0, limit);
|
||||
}
|
||||
@ -558,12 +536,13 @@
|
||||
ajaxSettings;
|
||||
|
||||
options.params[options.paramName] = q;
|
||||
params = options.ignoreParams ? null : options.params;
|
||||
|
||||
if (options.onSearchStart.call(that.element, options.params) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
params = options.ignoreParams ? null : options.params;
|
||||
|
||||
if ($.isFunction(options.lookup)){
|
||||
options.lookup(q, function (data) {
|
||||
that.suggestions = data.suggestions;
|
||||
@ -640,7 +619,7 @@
|
||||
|
||||
that.visible = false;
|
||||
that.selectedIndex = -1;
|
||||
clearInterval(that.onChangeInterval);
|
||||
clearTimeout(that.onChangeTimeout);
|
||||
$(that.suggestionsContainer).hide();
|
||||
that.signalHint(null);
|
||||
},
|
||||
@ -693,6 +672,16 @@
|
||||
html += '<div class="' + className + '" data-index="' + i + '">' + formatResult(suggestion, value, i) + '</div>';
|
||||
});
|
||||
|
||||
if (that.options.lookupLimitOverflowMessage != null
|
||||
&& that.realSuggestionsLength > that.suggestions.length) {
|
||||
|
||||
var lookupLimitOverflowMessage = that.options.lookupLimitOverflowMessage;
|
||||
lookupLimitOverflowMessage = lookupLimitOverflowMessage.replace("%d", that.realSuggestionsLength - that.suggestions.length);
|
||||
|
||||
html += '<div class="autocomplete-limit-overflow">' +
|
||||
lookupLimitOverflowMessage + '</div>';
|
||||
}
|
||||
|
||||
this.adjustContainerWidth();
|
||||
|
||||
noSuggestionsContainer.detach();
|
||||
@ -718,6 +707,7 @@
|
||||
|
||||
noSuggestions: function() {
|
||||
var that = this,
|
||||
beforeRender = that.options.beforeRender,
|
||||
container = $(that.suggestionsContainer),
|
||||
noSuggestionsContainer = $(that.noSuggestionsContainer);
|
||||
|
||||
@ -726,9 +716,15 @@
|
||||
// Some explicit steps. Be careful here as it easy to get
|
||||
// noSuggestionsContainer removed from DOM if not detached properly.
|
||||
noSuggestionsContainer.detach();
|
||||
container.empty(); // clean suggestions if any
|
||||
|
||||
// clean suggestions if any
|
||||
container.empty();
|
||||
container.append(noSuggestionsContainer);
|
||||
|
||||
if ($.isFunction(beforeRender)) {
|
||||
beforeRender.call(that.element, container, that.suggestions);
|
||||
}
|
||||
|
||||
that.fixPosition();
|
||||
|
||||
container.show();
|
||||
@ -862,7 +858,6 @@
|
||||
var that = this;
|
||||
that.hide();
|
||||
that.onSelect(i);
|
||||
that.disableKillerFn();
|
||||
},
|
||||
|
||||
moveUp: function () {
|
||||
@ -965,7 +960,6 @@
|
||||
dispose: function () {
|
||||
var that = this;
|
||||
that.el.off('.autocomplete').removeData('autocomplete');
|
||||
that.disableKillerFn();
|
||||
$(window).off('resize.autocomplete', that.fixPositionCapture);
|
||||
$(that.suggestionsContainer).remove();
|
||||
}
|
||||
|
2
dist/jquery.autocomplete.min.js
vendored
2
dist/jquery.autocomplete.min.js
vendored
File diff suppressed because one or more lines are too long
@ -31,6 +31,8 @@ $(function () {
|
||||
$('#autocomplete-ajax').autocomplete({
|
||||
// serviceUrl: '/autosuggest/service/url',
|
||||
lookup: countriesArray,
|
||||
lookupLimit: 2,
|
||||
lookupLimitOverflowMessage: 'And %d another countries...',
|
||||
lookupFilter: function(suggestion, originalQuery, queryLowerCase) {
|
||||
var re = new RegExp('\\b' + $.Autocomplete.utils.escapeRegExChars(queryLowerCase), 'gi');
|
||||
return re.test(suggestion.value);
|
||||
|
@ -78,6 +78,7 @@
|
||||
that.hint = null;
|
||||
that.hintValue = '';
|
||||
that.selection = null;
|
||||
that.realSuggestionsLength = 0;
|
||||
|
||||
// Initialize and set options:
|
||||
that.initialize();
|
||||
@ -122,7 +123,8 @@
|
||||
showNoSuggestionNotice: false,
|
||||
noSuggestionNotice: 'No results',
|
||||
orientation: 'bottom',
|
||||
forceFixPosition: false
|
||||
forceFixPosition: false,
|
||||
lookupLimitOverflowMessage: null
|
||||
};
|
||||
|
||||
function _lookupFilter(suggestion, originalQuery, queryLowerCase) {
|
||||
@ -515,6 +517,8 @@
|
||||
})
|
||||
};
|
||||
|
||||
that.realSuggestionsLength = data.suggestions.length;
|
||||
|
||||
if (limit && data.suggestions.length > limit) {
|
||||
data.suggestions = data.suggestions.slice(0, limit);
|
||||
}
|
||||
@ -668,6 +672,16 @@
|
||||
html += '<div class="' + className + '" data-index="' + i + '">' + formatResult(suggestion, value, i) + '</div>';
|
||||
});
|
||||
|
||||
if (that.options.lookupLimitOverflowMessage != null
|
||||
&& that.realSuggestionsLength > that.suggestions.length) {
|
||||
|
||||
var lookupLimitOverflowMessage = that.options.lookupLimitOverflowMessage;
|
||||
lookupLimitOverflowMessage = lookupLimitOverflowMessage.replace("%d", that.realSuggestionsLength - that.suggestions.length);
|
||||
|
||||
html += '<div class="autocomplete-limit-overflow">' +
|
||||
lookupLimitOverflowMessage + '</div>';
|
||||
}
|
||||
|
||||
this.adjustContainerWidth();
|
||||
|
||||
noSuggestionsContainer.detach();
|
||||
|
Loading…
Reference in New Issue
Block a user