123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /*
- jQuery autoComplete v1.0.7
- Copyright (c) 2014 Simon Steinberger / Pixabay
- GitHub: https://github.com/Pixabay/jQuery-autoComplete
- License: http://www.opensource.org/licenses/mit-license.php
- */
- (function ($) {
- $.fn.autoComplete = function (options) {
- var o = $.extend({}, $.fn.autoComplete.defaults, options);
- // public methods
- if (typeof options == 'string') {
- this.each(function () {
- var that = $(this);
- if (options == 'destroy') {
- $(window).off('resize.autocomplete', that.updateSC);
- that.off('blur.autocomplete focus.autocomplete keydown.autocomplete keyup.autocomplete');
- if (that.data('autocomplete'))
- that.attr('autocomplete', that.data('autocomplete'));
- else
- that.removeAttr('autocomplete');
- $(that.data('sc')).remove();
- that.removeData('sc').removeData('autocomplete');
- }
- });
- return this;
- }
- return this.each(function () {
- var that = $(this);
- // sc = 'suggestions container'
- that.sc = $('<div class="autocomplete-suggestions ' + o.menuClass + '"></div>');
- that.data('sc', that.sc).data('autocomplete', that.attr('autocomplete'));
- that.attr('autocomplete', 'off');
- that.cache = {};
- that.last_val = '';
- that.updateSC = function (resize, next) {
- that.sc.css({
- top: that.offset().top + that.outerHeight() - (that.sc.css("position") == "fixed" ? $(window).scrollTop() : 0),
- left: that.offset().left,
- width: that.outerWidth()
- });
- if (!resize) {
- that.sc.show();
- if (!that.sc.maxHeight) that.sc.maxHeight = parseInt(that.sc.css('max-height'));
- if (!that.sc.suggestionHeight) that.sc.suggestionHeight = $('.autocomplete-suggestion', that.sc).first().outerHeight();
- if (that.sc.suggestionHeight)
- if (!next) that.sc.scrollTop(0);
- else {
- var scrTop = that.sc.scrollTop(), selTop = next.offset().top - that.sc.offset().top;
- if (selTop + that.sc.suggestionHeight - that.sc.maxHeight > 0)
- that.sc.scrollTop(selTop + that.sc.suggestionHeight + scrTop - that.sc.maxHeight);
- else if (selTop < 0)
- that.sc.scrollTop(selTop + scrTop);
- }
- }
- }
- $(window).on('resize.autocomplete', that.updateSC);
- that.sc.appendTo('body');
- that.on('click', function () {
- if ($(this).val().length > 0 && that.sc.is(":hidden")) {
- setTimeout(function () {
- that.sc.show();
- }, 100);
- }
- });
- that.sc.on('mouseleave', '.autocomplete-suggestion', function () {
- $('.autocomplete-suggestion.selected').removeClass('selected');
- });
- that.sc.on('mouseenter', '.autocomplete-suggestion', function () {
- $('.autocomplete-suggestion.selected').removeClass('selected');
- $(this).addClass('selected');
- });
- that.sc.on('mousedown click', '.autocomplete-suggestion', function (e) {
- var item = $(this), v = item.data('val');
- if (v || item.hasClass('autocomplete-suggestion')) { // else outside click
- that.val(v);
- o.onSelect(e, v, item);
- that.sc.hide();
- }
- return false;
- });
- that.on('blur.autocomplete', function () {
- try {
- over_sb = $('.autocomplete-suggestions:hover').length;
- } catch (e) {
- over_sb = 0;
- } // IE7 fix :hover
- if (!over_sb) {
- that.last_val = that.val();
- that.sc.hide();
- setTimeout(function () {
- that.sc.hide();
- }, 350); // hide suggestions on fast input
- } else if (!that.is(':focus')) setTimeout(function () {
- that.focus();
- }, 20);
- });
- if (!o.minChars) that.on('focus.autocomplete', function () {
- that.last_val = '\n';
- that.trigger('keyup.autocomplete');
- });
- function suggest(data) {
- var val = that.val();
- that.cache[val] = data;
- if (data.length && val.length >= o.minChars) {
- var s = '';
- if (data.length > 0) {
- s += typeof o.header === 'function' ? o.header.call(data, o, that) : o.header;
- for (var i = 0; i < data.length; i++) s += o.renderItem(data[i], val);
- s += typeof o.footer === 'function' ? o.footer.call(data, o, that) : o.footer;
- }
- that.sc.html(s);
- that.updateSC(0);
- } else
- that.sc.hide();
- }
- that.on('keydown.autocomplete', function (e) {
- // down (40), up (38)
- if ((e.which == 40 || e.which == 38) && that.sc.html()) {
- var next, sel = $('.autocomplete-suggestion.selected', that.sc);
- if (!sel.length) {
- next = (e.which == 40) ? $('.autocomplete-suggestion', that.sc).first() : $('.autocomplete-suggestion', that.sc).last();
- that.val(next.addClass('selected').data('val'));
- } else {
- next = (e.which == 40) ? sel.next('.autocomplete-suggestion') : sel.prev('.autocomplete-suggestion');
- if (next.length) {
- sel.removeClass('selected');
- that.val(next.addClass('selected').data('val'));
- } else {
- sel.removeClass('selected');
- that.val(that.last_val);
- next = 0;
- }
- }
- that.updateSC(0, next);
- return false;
- }
- // esc
- else if (e.which == 27) that.val(that.last_val).sc.hide();
- // enter or tab
- else if (e.which == 13 || e.which == 9) {
- var sel = $('.autocomplete-suggestion.selected', that.sc);
- if (sel.length && that.sc.is(':visible')) {
- o.onSelect(e, sel.data('val'), sel);
- setTimeout(function () {
- that.sc.hide();
- }, 20);
- }
- }
- });
- that.on('keyup.autocomplete', function (e) {
- if (!~$.inArray(e.which, [13, 27, 35, 36, 37, 38, 39, 40])) {
- var val = that.val();
- if (val.length >= o.minChars) {
- if (val != that.last_val) {
- that.last_val = val;
- clearTimeout(that.timer);
- if (o.cache) {
- if (val in that.cache) {
- suggest(that.cache[val]);
- return;
- }
- // no requests if previous suggestions were empty
- for (var i = 1; i < val.length - o.minChars; i++) {
- var part = val.slice(0, val.length - i);
- if (part in that.cache && !that.cache[part].length) {
- suggest([]);
- return;
- }
- }
- }
- that.timer = setTimeout(function () {
- o.source(val, suggest)
- }, o.delay);
- }
- } else {
- that.last_val = val;
- that.sc.hide();
- }
- }
- });
- });
- }
- $.fn.autoComplete.defaults = {
- source: 0,
- minChars: 3,
- delay: 150,
- cache: 1,
- menuClass: '',
- header: '',
- footer: '',
- renderItem: function (item, search) {
- // escape special characters
- search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
- var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
- return '<div class="autocomplete-suggestion" data-val="' + item + '">' + item.replace(re, "<b>$1</b>") + '</div>';
- },
- onSelect: function (e, term, item) {
- }
- };
- }(jQuery));
|