jquery-autocomplete-js
Version:
The simplest jQuery plugin for creating autocomplete boxes with dynamically generated suggestions.
36 lines (34 loc) • 14.3 kB
JavaScript
/**
autocomplete.js 1.1.0
Minified version
isis97 - Styczynsky Digital Systems
http://isis97.github.io/autocomplete-js/
**/
(function(h){h.fn.extend({autocomplete:function(a){function D(b){void 0===u&&(u=h("<span></span>").hide().css("position","fixed").css("outline","0").css("margin","0").css("padding","0").css("border","0").css("left","0").css("white-space","pre").css("font-size",a.fontSize).css("font-family",a.fontFamily).css("font-weight","normal"),h("body").append(u));u.text(b);b=u.width();u.remove();return b}var x=h(this),f={},g=function(a){return{handlers:[],__back_handler:a||function(){},push:function(a){this.handlers.push(a)},
call:function(a){t=f;a=a||[t];this.__back_handler.apply(t,a);for(var b=0;b<this.handlers.length;++b)this.handlers[b].apply(t,a)}}};if(null==a||a=={}||void 0==a)return null;if(1<x.length){for(var g=[],p=0;p>x.length;++p)g.push(h(x[p]).autocomplete(a));return g}a=a||{};if("nanoscroller"===a.scrollController){var y={scroller:null,scrollerPos:0,init:function(a){a.css("overflow","hidden");var c=h('<div class="nano-content"></div>');a.wrapInner(c);var e=h('<div class="nano"></div>');a.wrapInner(e);return c},
repaint:function(a){this.scroller||(this.scroller=a.parent(),this.scroller.nanoScroller({alwaysVisible:!0}),this.scroller.on("update",function(a,b){y.scrollerPos=b.position}));this.scroller.nanoScroller({scrollTop:0});this.scroller.nanoScroller()},scroll:function(a){if(!this.scroller)return 0;a&&this.scroller.nanoScroller({scrollTop:a});return this.scrollerPos}};a.scrollController=y}a.scrollController=a.scrollController||{init:function(a){return a},repaint:function(a){},scroll:function(a){a&&k.scrollTop(a);
return k.scrollTop()}};a.scrollController.init=a.scrollController.init||function(a){return a};a.scrollController.repaint=a.scrollController.repaint||function(){};a.scrollController.scroll=a.scrollController.scroll||function(a){a&&k.scrollTop(a);return k.scrollTop()};a.__event_hintChanged=g();a.__event_dropdownShown=g(function(a){a.show()});a.__event_dropdownHidden=g(function(a){a.hide()});a.__event_confirmed=g();a.__event_changed=g();a.__event_history_browsed=g();a.__event_key=g();if(a.animation){var A=
function(b,c){for(var e=0;e<a.animation.length;++e){var d=a.animation[e][0],f=null,f=c?a.animation[e][1]:a.animation[e][2];"height"==d?b.height(f):"width"==d?b.width(f):b.css(d,f)}},B=function(b){for(var c={},e=0;e<a.animation.length;++e){var d=a.animation[e][0],f=null,f=b?a.animation[e][1]:a.animation[e][2];c[d]=f}return c};a.__event_dropdownShown.push(function(a){var c=this;a.stop().show();A(a,!0);a.animate(B(!1),500,function(){c.repaint()})});a.__event_dropdownHidden.push(function(a){a.stop().show();
A(a,!1);a.animate(B(!0),500,function(){a.hide()})})}a.showWhenEmpty=a.showWhenEmpty||!1;a.isDisabled=a.isDisabled||!1;a.inputWidth=a.inputWidth||"100%";a.inputHeight=a.inputHeight||"25px";a.dropDownWidth=a.dropDownWidth||"50%";a.dropDownDescriptionBoxWidth=a.dropDownDescriptionBoxWidth||"50%";a.fontSize=a.fontSize||null;a.fontFamily=a.fontFamily||null;a.formPromptHTML=a.formPromptHTML||"";a.color=a.color||null;a.hintColor=a.hintColor||null;a.backgroundColor=a.backgroundColor||null;a.dropDownBorderColor=
a.dropDownBorderColor||null;a.dropDownZIndex=a.dropDownZIndex||"100";a.dropDownOnHoverBackgroundColor=a.dropDownOnHoverBackgroundColor||null;a.enableHistory=a.enableHistory||!0;a.inputHistory=a.inputHistory||[];a.classes=a.classes||{};a.classes.input=a.classes.input||null;a.classes.dropdown=a.classes.dropdown||null;a.classes.hint=a.classes.hint||null;a.classes.wrapper=a.classes.wrapper||null;a.classes.prompt=a.classes.prompt||null;a.classes.hoverItem=a.classes.hoverItem||null;a.classes.row=a.classes.row||
null;a.classes.descriptionBox=a.classes.descriptionBox||null;a.maxSuggestionsCount=a.maxSuggestionsCount||100;a.suggestionBoxHeight=a.suggestionBoxHeight||"75px";a.showDropDown=a.showDropDown||!1;a.dropDownPosition=a.dropDownPosition||"bottom";a.blockEvents=a.blockEvents||!0;a.options=a.options||{};var d=h('<input class="autocomplete autocomplete-input autocomplete-text" type="text" spellcheck="false"></input>').css("width",a.inputWidth).css("height",a.inputHeight).css("outline","0").css("border",
"0").css("margin","0").css("padding","0").css("verticalAlign","top").css("position","absolute").addClass(a.classes.input),l=d.clone().removeClass("autocomplete-input").css("background-color","").css("width",a.inputWidth).css("height",a.inputHeight).attr("disabled","").css("position","absolute").css("top","inherit").css("left","inherit").css("borderColor","transparent").css("boxShadow","none").css("color",a.hintColor).addClass("autocomplete-hint").addClass(a.classes.hint);d.css("background","none");
l.__val=l.val;l.val=function(b){if(void 0==b||null==b)return l.__val();l.__val(b);a.__event_hintChanged.call([f,b])};g=h('<div class="autocomplete autocomplete-wrapper"></div>').css("display","inline").css("width",a.inputWidth).css("height",a.inputHeight).css("position","absolute").css("bottom","0px").css("outline","0").css("border","0").css("margin","0").css("padding","0").css("paddingTop","10px").addClass(a.classes.wrapper);p=h('<div class="autocomplete autocomplete-prompt"></div>').css("position",
"absolute").css("outline","0").css("margin","0").css("padding","0").css("border","0").css("top","0").css("left","0").css("overflow","hidden").html(a.formPromptHTML).addClass(a.classes.prompt);if(void 0===h("body"))throw"document.body is undefined. The library was wired up incorrectly.";h("body").append(p);var v=p.width();g.append(p);p.show().css("left","-"+v+"px").css("marginLeft",v+"px");var k=h('<div class="autocomplete autocomplete-dropdown"></div>').css("height",a.suggestionBoxHeight).css("width",
a.dropDownWidth).hide(),v=k.height()/2;"top"==a.dropDownPosition&&(v=-(k.height()/2)-d.height());k.css("float","bottom").css("position","absolute").css("z-index","9999").css("left","0px").css("top",v+"px").css("outline","0").css("margin","0").css("padding","0").css("text-align","left").css("font-size",a.fontSize).css("font-family",a.fontFamily).css("max-height",a.suggestionBoxHeight).css("background-color",a.backgroundColor).css("z-index",a.dropDownZIndex).css("cursor","default").css("border-style",
"solid").css("border-width","1px").css("border-color",a.dropDownBorderColor).css("overflow-x","hidden").css("white-space","pre").css("overflow-y","scroll").addClass(a.classes.dropdown);var n=h('<div class="autocomplete autocomplete-dropdown-description-box"></div>').css("position","absolute").css("left",a.dropDownWidth).css("top",v+"px").hide().css("word-break","keep-all").css("white-space","normal").css("outline","0").css("margin","0").css("padding","0").css("text-align","left").css("font-size",
a.fontSize).css("font-family",a.fontFamily).css("max-height",a.suggestionBoxHeight).css("background-color",a.backgroundColor).css("z-index",a.dropDownZIndex).css("cursor","default").css("border-style","solid").css("border-width","1px").css("border-color",a.dropDownBorderColor).css("overflow-x","hidden").css("color",a.color).css("height",a.suggestionBoxHeight).css("width",a.dropDownDescriptionBoxWidth).addClass(a.classes.descriptionBox);n.hideBlock=function(){n.attr("display","none")};n.showBlock=
function(){n.attr("display","block")};var C=function(a){var c="",e=null;a=a||{};if(void 0==a.html||null==a.html)a.html=!1;void 0!=a.name&&null!=a.name?(c=a.name,a.description&&(e=a.description,a.html||e&&(e=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")))):c=a;a.html=a.html||!1;return{name:c||"",description:e||null,html:a.html}},m=function(b){var c=[],e=0,d=-1,f=function(){h(this).css("outline","1px solid #ddd")},l=function(){h(this).css("outline",
"0")},m=function(){g.hideBlock();g.onMouseSelected(this.__hint)},g={contentElem:b,hideBlock:function(){b.attr("display","none")},showBlock:function(c){var e=this.contentElem.children().length,d=!1,f=!1;1>=c&&1<e?d=!0:1<c&&1>=e&&(f=!0);b.attr("display","block");d&&a.__event_dropdownShown.call([k]);f&&(this.hideBlock(),a.__event_dropdownHidden.call([k]))},hide:function(){this.hideBlock()},refresh:function(d,k){e=0;this.contentElem.html("");var p=window.innerHeight||document.documentElement.clientHeight,
z=b.offset().top-6,p=p-(b.parent().height()-b.height()-b.offset().top)-6;c=[];for(var q=0,r=0;r<k.length;r++){var u=C(k[r]),v=u.name,u=u.description;if(0===v.toLowerCase().indexOf(d.toLowerCase())){++q;if(q>a.maxSuggestionsCount)break;var w=h("<div></div>").css("color",a.color).mouseover(f).mouseout(l).mousedown(m).addClass(a.classes.row);w[0].__hint=w.__hint=v;w.html(d+"<b>"+v.substring(d.length)+"</b>");w.description=u;c.push(w);this.contentElem.append(w)}}1<c.length?(c[0].description?(n.show(),
c[0].html?n.html(c[0].description):n.text(c[0].description)):n.hide(),0===c.length||1===c.length&&d===c[0].__hint||2>c.length||(g.highlight(0),z>3*p?b.css("maxHeight",z+"px").css("bottom","100%"):b.css("bottom","").css("maxHeight",p+"px"),b.show())):n.hide()},highlight:function(b){-1!=d&&c[d]&&c[d].css("backgroundColor",a.backgroundColor);k.find(a.classes.hoverItem).removeClass(a.classes.hoverItem);var e=k.find(".autocomplete-hover-item");e.removeClass(a.classes.hoverItem);e.removeClass("autocomplete-hover-item");
c[b].description?(n.show(),c[b].html?n.html(c[b].description):n.text(c[b].description)):n.hide();c[b].css("backgroundColor",a.dropDownOnHoverBackgroundColor);c[b].addClass(a.classes.hoverItem);c[b].addClass("autocomplete-hover-item");d=b},scrollController:a.scrollController,move:function(a){if(!b.is(":visible"))return"";if(-1===e+a||e+a===c.length)return c[e].__hint;e+=a;g.highlight(e);this.scrollController.scroll(this.scrollController.scroll()+a*this.contentElem.children().height());return c[e].__hint},
onMouseSelected:function(){}};return g}(k);m.onMouseSelected=function(a){d.val(q+a);l.val(q+a);f.onChange(d.val());r=d.val();setTimeout(function(){d.focus()},0)};a.showDropDown?(g.append(k),g.append(n)):(k.css("visibility","hidden"),k.css("display","none"),n.css("visibility","hidden"),n.css("display","none"));g.append(l);g.append(d);x.append(g);var u,q,f={status:!a.isDisabled,hintChanged:function(b){a.__event_hintChanged.push(b);return this},dropdownShown:function(b){a.__event_dropdownShown.push(b);
return this},dropdownHidden:function(b){a.__event_dropdownHidden.push(b);return this},confirmed:function(b){a.__event_confirmed.push(b);return this},changed:function(b){a.__event_changed.push(b);return this},historyBrowsed:function(b){a.__event_history_browsed.push(b);return this},key:function(b){a.__event_key.push(b);return this},onKey:function(b){a.__event_key.call([b,b.which]);return this},disable:function(){this.status=!1;return this},enable:function(){this.status=!0;return this},showDropDown:function(){k.show();
a.__event_dropdownShown.call([k]);this.repaint()},isEnabled:function(){return this.status},onArrowDown:function(){return this},onArrowUp:function(){return this},onEnter:function(){this.inputHistory.push(d.val());a.__event_confirmed.call([this,this.getText()]);return this},onTab:function(){return this},onChange:function(){a.__event_changed.call([this,this.getText()]);f.repaint();return this},onHistoryPrev:function(){a.__event_history_browsed.call([this,this.getInputHistory()]);d.val(this.historyNavigatePrev());
return this},onHistoryNext:function(){a.__event_history_browsed.call([this,this.getInputHistory()]);d.val(this.historyNavigateNext());return this},getInputHistory:function(){return this.inputHistory},getOptions:function(){if(this.options instanceof Function){var a=d.val(),c=a.substring(f.startFrom).split(" ");return this.options(this,a,c[c.length-1])}return this.options},startFrom:0,options:a.options,inputHistory:a.inputHistory,historyIndex:0,historyBrowsingActive:!1,formWrapper:g,input:d,hint:l,
dropDown:k,formPrompt:p,historyNavigateNext:function(){this.historyIndex++;this.historyIndex>=this.inputHistory.length&&(this.historyIndex=this.inputHistory.length-1);return this.inputHistory[this.historyIndex]},historyNavigatePrev:function(){this.historyIndex--;0>this.historyIndex&&(this.historyIndex=0);return this.inputHistory[this.historyIndex]},historyNavigateClear:function(){this.historyIndex=this.inputHistory.length-1},setText:function(a){l.val(a);d.val(a);return this},getText:function(){return d.val()},
pullText:function(){var a=this.getText();this.setText("");return a},hideDropDown:function(){m.hide();return this},repaint:function(){var b=d.val(),c=f.startFrom,e=f.getOptions(),g=e.length,h=b.substring(c).split(" "),b=h[h.length-1];q="";for(c=0;c<h.length-1;++c)q+=h[c]+" ";l.val("");for(c=0;c<g;c++){h=C(e[c]).name;if(void 0==h.indexOf)throw console.log(h),"NOPE!";if(0===h.indexOf(b)){l.val(q+h);break}}e=!1;g=m.contentElem.children().length;if(this.status)e=!0;else return m.hideBlock(),n.hideBlock(),
m.scrollController.repaint(m.contentElem),this;k.css("left",D(q)+"px");""==b?a.showWhenEmpty?m.refresh(b,f.getOptions()):m.refresh(b,[]):m.refresh(b,f.getOptions());e&&(m.showBlock(g),n.showBlock());m.scrollController.repaint(m.contentElem)}},r;(function(a,c){r=a.val();var d=function(){var d=a.val();r!==d&&(r=d,c(d))};a.change(d);a.keyup(d)})(d,function(a){f.onChange(a)});d.keydown(function(b){b=b||window.event;var c=b.keyCode,e=function(b){a.blockEvents&&b.preventDefault()};""==d.val()&&(f.historyBrowsingActive=
!0);if(27==c)return e(b),m.hide(),n.hide(),l.val(d.val()),d.focus(),this;if(39==c||35==c||9==c){e(b);9==c&&(b.preventDefault(),b.stopPropagation(),0==l.val().length&&(f.onTab(),f.onKey(b)));if(0<l.val().length&&(m.hide(),n.hide(),d.val(l.val()),b=r!=d.val(),r=d.val(),b))f.onChange(d.val());return this}if(13==c){e(b);if(0==l.val().length)f.onEnter();else{b=!k.is(":visible");m.hide();if(b)return l.val(d.val()),d.focus(),f.onEnter(),this;d.val(l.val());b=r!=d.val();r=d.val();if(b)f.onChange(d.val())}return this}if(40==
c)if(e(b),a.enableHistory&&f.historyBrowsingActive)f.onHistoryPrev();else{b=m.move(1);if(""==b)f.onArrowDown();l.val(q+b);return this}else{if(38==c){e(b);if(a.enableHistory&&f.historyBrowsingActive)f.onHistoryNext();else{b=m.move(-1);if(""==b)f.onArrowUp();l.val(q+b)}return this}f.historyBrowsingActive=!1;f.historyNavigateClear();f.onKey(b)}l.val("");return this});m.contentElem=m.scrollController.init(k);return f}})})($);