mirror of
https://github.com/devbridge/jQuery-Autocomplete.git
synced 2024-11-09 23:01:00 +00:00
Update dist source.
This commit is contained in:
parent
74ea7e35f4
commit
3e7fb81cf3
171
dist/jquery.autocomplete.js
vendored
171
dist/jquery.autocomplete.js
vendored
@ -54,7 +54,7 @@
|
|||||||
that = this,
|
that = this,
|
||||||
defaults = {
|
defaults = {
|
||||||
autoSelectFirst: false,
|
autoSelectFirst: false,
|
||||||
appendTo: 'body',
|
appendTo: document.body,
|
||||||
serviceUrl: null,
|
serviceUrl: null,
|
||||||
lookup: null,
|
lookup: null,
|
||||||
onSelect: null,
|
onSelect: null,
|
||||||
@ -76,13 +76,18 @@
|
|||||||
dataType: 'text',
|
dataType: 'text',
|
||||||
currentRequest: null,
|
currentRequest: null,
|
||||||
triggerSelectOnValidInput: true,
|
triggerSelectOnValidInput: true,
|
||||||
|
preventBadQueries: true,
|
||||||
lookupFilter: function (suggestion, originalQuery, queryLowerCase) {
|
lookupFilter: function (suggestion, originalQuery, queryLowerCase) {
|
||||||
return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1;
|
return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1;
|
||||||
},
|
},
|
||||||
paramName: 'query',
|
paramName: 'query',
|
||||||
transformResult: function (response) {
|
transformResult: function (response) {
|
||||||
return typeof response === 'string' ? $.parseJSON(response) : response;
|
return typeof response === 'string' ? $.parseJSON(response) : response;
|
||||||
}
|
},
|
||||||
|
showNoSuggestionNotice: false,
|
||||||
|
noSuggestionNotice: 'No results',
|
||||||
|
orientation: 'bottom',
|
||||||
|
forceFixPosition: false
|
||||||
};
|
};
|
||||||
|
|
||||||
// Shared variables:
|
// Shared variables:
|
||||||
@ -98,6 +103,7 @@
|
|||||||
that.onChange = null;
|
that.onChange = null;
|
||||||
that.isLocal = false;
|
that.isLocal = false;
|
||||||
that.suggestionsContainer = null;
|
that.suggestionsContainer = null;
|
||||||
|
that.noSuggestionsContainer = null;
|
||||||
that.options = $.extend({}, defaults, options);
|
that.options = $.extend({}, defaults, options);
|
||||||
that.classes = {
|
that.classes = {
|
||||||
selected: 'autocomplete-selected',
|
selected: 'autocomplete-selected',
|
||||||
@ -131,7 +137,8 @@
|
|||||||
suggestionSelector = '.' + that.classes.suggestion,
|
suggestionSelector = '.' + that.classes.suggestion,
|
||||||
selected = that.classes.selected,
|
selected = that.classes.selected,
|
||||||
options = that.options,
|
options = that.options,
|
||||||
container;
|
container,
|
||||||
|
noSuggestionsContainer;
|
||||||
|
|
||||||
// Remove autocomplete attribute to prevent native suggestions:
|
// Remove autocomplete attribute to prevent native suggestions:
|
||||||
that.element.setAttribute('autocomplete', 'off');
|
that.element.setAttribute('autocomplete', 'off');
|
||||||
@ -143,6 +150,10 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
that.suggestionsContainer = Autocomplete.utils.createNode(options.containerClass);
|
that.suggestionsContainer = Autocomplete.utils.createNode(options.containerClass);
|
||||||
|
|
||||||
container = $(that.suggestionsContainer);
|
container = $(that.suggestionsContainer);
|
||||||
@ -170,8 +181,6 @@
|
|||||||
that.select($(this).data('index'));
|
that.select($(this).data('index'));
|
||||||
});
|
});
|
||||||
|
|
||||||
that.fixPosition();
|
|
||||||
|
|
||||||
that.fixPositionCapture = function () {
|
that.fixPositionCapture = function () {
|
||||||
if (that.visible) {
|
if (that.visible) {
|
||||||
that.fixPosition();
|
that.fixPosition();
|
||||||
@ -211,6 +220,8 @@
|
|||||||
options.lookup = that.verifySuggestionsFormat(options.lookup);
|
options.lookup = that.verifySuggestionsFormat(options.lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.orientation = that.validateOrientation(options.orientation, 'bottom');
|
||||||
|
|
||||||
// Adjust height, width and z-index:
|
// Adjust height, width and z-index:
|
||||||
$(that.suggestionsContainer).css({
|
$(that.suggestionsContainer).css({
|
||||||
'max-height': options.maxHeight + 'px',
|
'max-height': options.maxHeight + 'px',
|
||||||
@ -219,6 +230,7 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
clearCache: function () {
|
clearCache: function () {
|
||||||
this.cachedResponse = {};
|
this.cachedResponse = {};
|
||||||
this.badQueries = [];
|
this.badQueries = [];
|
||||||
@ -243,27 +255,62 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
fixPosition: function () {
|
fixPosition: function () {
|
||||||
var that = this,
|
// Use only when container has already its content
|
||||||
offset,
|
|
||||||
styles;
|
|
||||||
|
|
||||||
// Don't adjsut position if custom container has been specified:
|
var that = this,
|
||||||
if (that.options.appendTo !== 'body') {
|
$container = $(that.suggestionsContainer),
|
||||||
|
containerParent = $container.parent().get(0);
|
||||||
|
// Fix position automatically when appended to body.
|
||||||
|
// In other cases force parameter must be given.
|
||||||
|
if (containerParent !== document.body && !that.options.forceFixPosition)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Choose orientation
|
||||||
|
var orientation = that.options.orientation,
|
||||||
|
containerHeight = $container.outerHeight(),
|
||||||
|
height = that.el.outerHeight(),
|
||||||
|
offset = that.el.offset(),
|
||||||
|
styles = { 'top': offset.top, 'left': offset.left };
|
||||||
|
|
||||||
|
if (orientation == 'auto') {
|
||||||
|
var viewPortHeight = $(window).height(),
|
||||||
|
scrollTop = $(window).scrollTop(),
|
||||||
|
top_overflow = -scrollTop + offset.top - containerHeight,
|
||||||
|
bottom_overflow = scrollTop + viewPortHeight - (offset.top + height + containerHeight);
|
||||||
|
|
||||||
|
if (Math.max(top_overflow, bottom_overflow) === top_overflow)
|
||||||
|
orientation = 'top';
|
||||||
|
else
|
||||||
|
orientation = 'bottom';
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = that.el.offset();
|
if (orientation === 'top')
|
||||||
|
styles.top += -containerHeight;
|
||||||
|
else
|
||||||
|
styles.top += height;
|
||||||
|
|
||||||
styles = {
|
// If container is not positioned to body,
|
||||||
top: (offset.top + that.el.outerHeight()) + 'px',
|
// correct its position using offset parent offset
|
||||||
left: offset.left + 'px'
|
if(containerParent !== document.body) {
|
||||||
};
|
var opacity = $container.css('opacity'),
|
||||||
|
parentOffsetDiff;
|
||||||
|
if (!that.visible)
|
||||||
|
$container.css('opacity', 0).show();
|
||||||
|
|
||||||
|
parentOffsetDiff = $container.offsetParent().offset();
|
||||||
|
styles.top -= parentOffsetDiff.top;
|
||||||
|
styles.left -= parentOffsetDiff.left;
|
||||||
|
|
||||||
|
if (!that.visible)
|
||||||
|
$container.css('opacity', opacity).hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -2px to account for suggestions border.
|
||||||
if (that.options.width === 'auto') {
|
if (that.options.width === 'auto') {
|
||||||
styles.width = (that.el.outerWidth() - 2) + 'px';
|
styles.width = (that.el.outerWidth() - 2) + 'px';
|
||||||
}
|
}
|
||||||
|
|
||||||
$(that.suggestionsContainer).css(styles);
|
$container.css(styles);
|
||||||
},
|
},
|
||||||
|
|
||||||
enableKillerFn: function () {
|
enableKillerFn: function () {
|
||||||
@ -473,11 +520,11 @@
|
|||||||
that = this,
|
that = this,
|
||||||
options = that.options,
|
options = that.options,
|
||||||
serviceUrl = options.serviceUrl,
|
serviceUrl = options.serviceUrl,
|
||||||
data,
|
params,
|
||||||
cacheKey;
|
cacheKey;
|
||||||
|
|
||||||
options.params[options.paramName] = q;
|
options.params[options.paramName] = q;
|
||||||
data = options.ignoreParams ? null : options.params;
|
params = options.ignoreParams ? null : options.params;
|
||||||
|
|
||||||
if (that.isLocal) {
|
if (that.isLocal) {
|
||||||
response = that.getSuggestionsLocal(q);
|
response = that.getSuggestionsLocal(q);
|
||||||
@ -485,7 +532,7 @@
|
|||||||
if ($.isFunction(serviceUrl)) {
|
if ($.isFunction(serviceUrl)) {
|
||||||
serviceUrl = serviceUrl.call(that.element, q);
|
serviceUrl = serviceUrl.call(that.element, q);
|
||||||
}
|
}
|
||||||
cacheKey = serviceUrl + '?' + $.param(data || {});
|
cacheKey = serviceUrl + '?' + $.param(params || {});
|
||||||
response = that.cachedResponse[cacheKey];
|
response = that.cachedResponse[cacheKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,13 +548,15 @@
|
|||||||
}
|
}
|
||||||
that.currentRequest = $.ajax({
|
that.currentRequest = $.ajax({
|
||||||
url: serviceUrl,
|
url: serviceUrl,
|
||||||
data: data,
|
data: params,
|
||||||
type: options.type,
|
type: options.type,
|
||||||
dataType: options.dataType
|
dataType: options.dataType
|
||||||
}).done(function (data) {
|
}).done(function (data) {
|
||||||
|
var result;
|
||||||
that.currentRequest = null;
|
that.currentRequest = null;
|
||||||
that.processResponse(data, q, cacheKey);
|
result = options.transformResult(data);
|
||||||
options.onSearchComplete.call(that.element, q);
|
that.processResponse(result, q, cacheKey);
|
||||||
|
options.onSearchComplete.call(that.element, q, result.suggestions);
|
||||||
}).fail(function (jqXHR, textStatus, errorThrown) {
|
}).fail(function (jqXHR, textStatus, errorThrown) {
|
||||||
options.onSearchError.call(that.element, q, jqXHR, textStatus, errorThrown);
|
options.onSearchError.call(that.element, q, jqXHR, textStatus, errorThrown);
|
||||||
});
|
});
|
||||||
@ -515,6 +564,10 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
isBadQuery: function (q) {
|
isBadQuery: function (q) {
|
||||||
|
if (!this.options.preventBadQueries){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var badQueries = this.badQueries,
|
var badQueries = this.badQueries,
|
||||||
i = badQueries.length;
|
i = badQueries.length;
|
||||||
|
|
||||||
@ -537,7 +590,7 @@
|
|||||||
|
|
||||||
suggest: function () {
|
suggest: function () {
|
||||||
if (this.suggestions.length === 0) {
|
if (this.suggestions.length === 0) {
|
||||||
this.hide();
|
this.options.showNoSuggestionNotice ? this.noSuggestions() : this.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,6 +601,7 @@
|
|||||||
className = that.classes.suggestion,
|
className = that.classes.suggestion,
|
||||||
classSelected = that.classes.selected,
|
classSelected = that.classes.selected,
|
||||||
container = $(that.suggestionsContainer),
|
container = $(that.suggestionsContainer),
|
||||||
|
noSuggestionsContainer = $(that.noSuggestionsContainer),
|
||||||
beforeRender = options.beforeRender,
|
beforeRender = options.beforeRender,
|
||||||
html = '',
|
html = '',
|
||||||
index,
|
index,
|
||||||
@ -566,15 +620,9 @@
|
|||||||
html += '<div class="' + className + '" data-index="' + i + '">' + formatResult(suggestion, value) + '</div>';
|
html += '<div class="' + className + '" data-index="' + i + '">' + formatResult(suggestion, value) + '</div>';
|
||||||
});
|
});
|
||||||
|
|
||||||
// If width is auto, adjust width before displaying suggestions,
|
this.adjustContainerWidth();
|
||||||
// because if instance was created before input had width, it will be zero.
|
|
||||||
// Also it adjusts if input width has changed.
|
|
||||||
// -2px to account for suggestions border.
|
|
||||||
if (options.width === 'auto') {
|
|
||||||
width = that.el.outerWidth() - 2;
|
|
||||||
container.width(width > 0 ? width : 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
noSuggestionsContainer.detach();
|
||||||
container.html(html);
|
container.html(html);
|
||||||
|
|
||||||
// Select first value by default:
|
// Select first value by default:
|
||||||
@ -587,12 +635,49 @@
|
|||||||
beforeRender.call(that.element, container);
|
beforeRender.call(that.element, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
that.fixPosition();
|
||||||
|
|
||||||
container.show();
|
container.show();
|
||||||
that.visible = true;
|
that.visible = true;
|
||||||
|
|
||||||
that.findBestHint();
|
that.findBestHint();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
noSuggestions: function() {
|
||||||
|
var that = this,
|
||||||
|
container = $(that.suggestionsContainer),
|
||||||
|
noSuggestionsContainer = $(that.noSuggestionsContainer);
|
||||||
|
|
||||||
|
this.adjustContainerWidth();
|
||||||
|
|
||||||
|
// 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
|
||||||
|
container.append(noSuggestionsContainer);
|
||||||
|
|
||||||
|
that.fixPosition();
|
||||||
|
|
||||||
|
container.show();
|
||||||
|
that.visible = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
adjustContainerWidth: function() {
|
||||||
|
var that = this,
|
||||||
|
options = that.options,
|
||||||
|
width,
|
||||||
|
container = $(that.suggestionsContainer);
|
||||||
|
|
||||||
|
// If width is auto, adjust width before displaying suggestions,
|
||||||
|
// because if instance was created before input had width, it will be zero.
|
||||||
|
// Also it adjusts if input width has changed.
|
||||||
|
// -2px to account for suggestions border.
|
||||||
|
if (options.width === 'auto') {
|
||||||
|
width = that.el.outerWidth() - 2;
|
||||||
|
container.width(width > 0 ? width : 300);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
findBestHint: function () {
|
findBestHint: function () {
|
||||||
var that = this,
|
var that = this,
|
||||||
value = that.el.val().toLowerCase(),
|
value = that.el.val().toLowerCase(),
|
||||||
@ -637,18 +722,24 @@
|
|||||||
return suggestions;
|
return suggestions;
|
||||||
},
|
},
|
||||||
|
|
||||||
processResponse: function (response, originalQuery, cacheKey) {
|
validateOrientation: function(orientation, fallback) {
|
||||||
|
orientation = orientation.trim().toLowerCase();
|
||||||
|
if(['auto', 'bottom', 'top'].indexOf(orientation) == '-1')
|
||||||
|
orientation = fallback;
|
||||||
|
return orientation
|
||||||
|
},
|
||||||
|
|
||||||
|
processResponse: function (result, originalQuery, cacheKey) {
|
||||||
var that = this,
|
var that = this,
|
||||||
options = that.options,
|
options = that.options;
|
||||||
result = options.transformResult(response, originalQuery);
|
|
||||||
|
|
||||||
result.suggestions = that.verifySuggestionsFormat(result.suggestions);
|
result.suggestions = that.verifySuggestionsFormat(result.suggestions);
|
||||||
|
|
||||||
// Cache results if cache is not disabled:
|
// Cache results if cache is not disabled:
|
||||||
if (!options.noCache) {
|
if (!options.noCache) {
|
||||||
that.cachedResponse[cacheKey] = result;
|
that.cachedResponse[cacheKey] = result;
|
||||||
if (result.suggestions.length === 0) {
|
if (options.preventBadQueries && result.suggestions.length === 0) {
|
||||||
that.badQueries.push(cacheKey);
|
that.badQueries.push(originalQuery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,7 +845,11 @@
|
|||||||
suggestion = that.suggestions[index];
|
suggestion = that.suggestions[index];
|
||||||
|
|
||||||
that.currentValue = that.getValue(suggestion.value);
|
that.currentValue = that.getValue(suggestion.value);
|
||||||
that.el.val(that.currentValue);
|
|
||||||
|
if (that.currentValue !== that.el.val()) {
|
||||||
|
that.el.val(that.currentValue);
|
||||||
|
}
|
||||||
|
|
||||||
that.signalHint(null);
|
that.signalHint(null);
|
||||||
that.suggestions = [];
|
that.suggestions = [];
|
||||||
that.selection = suggestion;
|
that.selection = suggestion;
|
||||||
@ -794,7 +889,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create chainable jQuery plugin:
|
// Create chainable jQuery plugin:
|
||||||
$.fn.autocomplete = function (options, args) {
|
$.fn.autocomplete = function (options, args) {
|
||||||
var dataKey = 'autocomplete';
|
var dataKey = 'autocomplete';
|
||||||
// If function invoked without argument return
|
// If function invoked without argument return
|
||||||
// instance of the first matched element:
|
// instance of the first matched element:
|
||||||
|
Loading…
Reference in New Issue
Block a user