SimpleAutocomplete/hinter.min.js

4 lines
8.1 KiB
JavaScript

// (c) Vitaliy Filippov 2011-2013
// @license MPL 2.0 http://www.mozilla.org/MPL/2.0/
// http://yourcmc.ru/wiki/SimpleAutocomplete
var SimpleAutocomplete=function(b,a,c){if(typeof(b)=="string"){b=document.getElementById(b)}if(!c){c={}}this.input=b;this.a=a;this.b=c.multipleDelimiter;this.c=c.multipleListener;this.d=c.onChangeListener;this.e=c.emptyText;this.f=c.prompt;this.g=c.delay;this.h=c.moreMarker;this.i=c.persist;this.j=c.className||"hintLayer";if(this.h===undefined){this.h="#MORE"}if(this.g===undefined){this.g=300}this.k=0;this.l=null;this.m=[];this.n=[];this.o=0;this.p=-1;this.q=false;this.r()};SimpleAutocomplete.prototype.r=function(){var f=this.input;var a=SimpleAutocomplete.s;this.t=this.input.id+a.length;a.push(this);var d=getOffset(f);var c=this.u=document.createElement("div");c.className=this.j;if(!this.i){c.style.display="none";c.style.position="absolute";c.style.top=(d.top+f.offsetHeight)+"px";c.style.zIndex=1000;c.style.left=d.left+"px";document.body.appendChild(c)}else{f.nextSibling?f.parentNode.insertBefore(c,f.nextSibling):f.parentNode.appendChild(c)}f.SimpleAutocomplete_input=this;c.SimpleAutocomplete_layer=this;if(typeof f.autocomplete!=="undefined"){f.autocomplete="off";addListener(window,"beforeunload",function(){f.autocomplete="on"})}var b=this;this.v("keydown",function(e){return b.w(e)});this.v("keyup",function(e){return b.x(e)});this.v("change",function(){return b.onChange()});this.v("focus",function(){return b.y()});this.v("blur",function(){return b.z()});addListener(c,"mousedown",function(e){return b.aa(e)});this.onChange(true)};SimpleAutocomplete.prototype.replaceItems=function(c,a){if(!a){this.u.scrollTop=0;this.p=0;this.n=[];if(!c||c.length==0){if(this.e){this.u.innerHTML='<div class="hintEmptyText">'+this.e+"</div>"}else{this.ab()}return}while(this.p<c.length&&c[this.p][2]){this.p++}this.u.innerHTML=this.f?'<div class="hintPrompt">'+this.f+"</div>":"";this.ac()}if(this.b){var e={};var b=this.input.value.split(this.b);for(var d=0;d<b.length;d++){e[b[d].trim()]=true}for(var d in c){c[d][3]=e[c[d][1]]}}for(var d in c){this.u.appendChild(this.ad(this.n.length,c[d]));this.n.push(c[d])}};SimpleAutocomplete.prototype.v=function(b,a){this.m[b]=a;addListener(this.input,b,a)};SimpleAutocomplete.prototype.remove=function(){if(!this.u){return}this.u.parentNode.removeChild(this.u);for(var a in this.m){removeListener(this.input,a,this.m[a])}for(var a=0;a<SimpleAutocomplete.s.length;a++){if(SimpleAutocomplete.s[a]==this){SimpleAutocomplete.s.splice(a,1);break}}this.m={};this.input=null;this.u=null;this.n=null};SimpleAutocomplete.prototype.ad=function(e,f){var g=document.createElement("div");g.id=this.t+"_item_"+e;g.className=f[2]?"hintDisabledItem":(this.p==e?"hintActiveItem":"hintItem");g.title=f[1];if(this.b||this.c){var h=document.createElement("input");h.type="checkbox";h.id=this.t+"_check_"+e;h.checked=f[3]&&true;h.disabled=f[2]&&true;h.value=f[1];g.appendChild(h);var a=document.createElement("label");a.htmlFor=h.id;a.innerHTML=f[0];g.appendChild(a);addListener(a,"click",this.ae)}else{g.innerHTML=f[0]}var b=this;addListener(g,"mouseover",function(){return b.af(this)});addListener(g,"click",function(c){return b.ag(c,this)});return g};SimpleAutocomplete.prototype.ah=function(b){var c=this.p+b;if(c<0){c=0}while(this.n[c]&&this.n[c][2]){c+=b}var a=document.getElementById(this.t+"_item_"+c);if(!a){return true}return this.ai(a)};SimpleAutocomplete.prototype.ai=function(b){var a=parseInt(b.id.substr(this.t.length+6));if(this.n[a][2]){return false}if(this.p>=0){var d=this.aj();if(d){d.className=this.n[this.p][2]?"hintDisabledItem":"hintItem"}}this.p=a;b.className="hintActiveItem";return false};SimpleAutocomplete.prototype.aj=function(a){if(a==null){a=this.p}if(a<0){return null}return document.getElementById(this.t+"_item_"+this.p)};SimpleAutocomplete.prototype.selectItem=function(a){if(this.n[a][2]){return false}if(this.h&&this.n[a][1]==this.h){this.n.splice(a,1);elm.parentNode.removeChild(elm);this.k++;this.onChange(true);return}if(!this.b&&!this.c){this.input.value=this.n[a][1];this.hide()}else{document.getElementById(this.t+"_check_"+a).checked=this.n[a][3]=!this.n[a][3];if(this.c&&!this.c(this,a,this.n[a])){return}this.ak(a)}this.al=this.input.value;if(this.d){this.d(this,a,this.n[a])}};SimpleAutocomplete.prototype.ak=function(c){var b=this.input.value.split(this.b);for(var d=0;d<b.length;d++){b[d]=b[d].trim()}if(!this.n[c][3]){for(var d=b.length-1;d>=0;d--){if(b[d]==this.n[c][1]){b.splice(d,1)}}this.input.value=b.join(this.b+" ")}else{var e={};for(var d=0;d<this.n.length;d++){if(this.n[d][3]){e[this.n[d][1]]=true}}var a=[];for(var d=0;d<b.length;d++){if(e[b[d]]){delete e[b[d]];a.push(b[d])}}for(var d=0;d<this.n.length;d++){if(this.n[d][3]&&e[this.n[d][1]]){a.push(this.n[d][1])}}this.input.value=a.join(this.b+" ")}};SimpleAutocomplete.prototype.hide=function(){if(!this.i){if(!this.o){this.u.style.display="none";return true}else{this.o=0}}};SimpleAutocomplete.prototype.show=function(){if(!this.q&&!this.i&&this.u.style.display=="none"){var a=getOffset(this.input);this.u.style.top=(a.top+this.input.offsetHeight)+"px";this.u.style.left=a.left+"px";this.u.style.display="";return true}};SimpleAutocomplete.prototype.ab=function(){this.q=true;this.hide()};SimpleAutocomplete.prototype.ac=function(){this.q=false;if(this.am){this.show()}};SimpleAutocomplete.prototype.ae=function(a){return stopEvent(a||window.event,false,true)};SimpleAutocomplete.prototype.aa=function(a){a=a||window.event;if(this.am){this.o++}return stopEvent(a,true,false)};SimpleAutocomplete.prototype.af=function(a){return this.ai(a)};SimpleAutocomplete.prototype.ag=function(b,c){var a=parseInt(c.id.substr(this.t.length+6));this.selectItem(a);return true};SimpleAutocomplete.prototype.onChange=function(c){var b=this.input.value.trim();if(!c){this.k=0}if(b!=this.al||c){this.al=b;if(!this.g||c){this.a(this,b,this.k)}else{if(!this.l){var a=this;this.l=setTimeout(function(){a.a(a,a.al,a.k);a.l=null},this.g)}}}return true};SimpleAutocomplete.prototype.x=function(a){a=a||window.event;if(a.keyCode==38||a.keyCode==40){this.show()}if(a.keyCode==38||a.keyCode==40||a.keyCode==10||a.keyCode==13){if(this.u.style.display==""){return stopEvent(a,true,true)}else{return true}}this.onChange();return true};SimpleAutocomplete.prototype.w=function(e){if(this.u.style.display=="none"){return true}e=e||window.event;if(e.keyCode==38){this.ah(-1)}else{if(e.keyCode==40){this.ah(1)}else{if(e.keyCode==10||e.keyCode==13){if(this.p>=0){this.selectItem(this.p)}return stopEvent(e,true,true)}else{if(e.keyCode==27){this.hide();return stopEvent(e,true,true)}else{return true}}}}if(this.p>=0){var f=this.aj();var b=this.u;var a=getOffset(f).top+b.scrollTop-b.style.top.substr(0,b.style.top.length-2);var d=f.scrollHeight;if(a+d-b.offsetHeight>b.scrollTop){b.scrollTop=a+d-b.offsetHeight}else{if(a<b.scrollTop){b.scrollTop=a}}}return stopEvent(e,true,true)};SimpleAutocomplete.prototype.y=function(){this.show();this.am=true;return true};SimpleAutocomplete.prototype.z=function(){this.hide();this.am=false;return true};SimpleAutocomplete.s=[];SimpleAutocomplete.an=function(b){var d=b.target||b.srcElement;var c;while(d){c=d.SimpleAutocomplete_input;if(c){break}else{if(d.SimpleAutocomplete_layer){return true}}d=d.parentNode}for(var a in SimpleAutocomplete.s){if(SimpleAutocomplete.s[a]!=c){SimpleAutocomplete.s[a].hide()}}return true};var stopEvent=function(c,b,a){if(b){if(c.stopPropagation){c.stopPropagation()}else{c.cancelBubble=true}}if(a&&c.preventDefault){c.preventDefault()}c.returnValue=!a;return !a};var getOffset=function(a){if(a.getBoundingClientRect){return getOffsetRect(a)}else{return getOffsetSum(a)}};var getOffsetRect=function(d){var g=d.getBoundingClientRect();var h=document.body;var b=document.documentElement;var a=window.pageYOffset||b.scrollTop||h.scrollTop;var e=window.pageXOffset||b.scrollLeft||h.scrollLeft;var f=b.clientTop||h.clientTop||0;var i=b.clientLeft||h.clientLeft||0;var j=g.top+a-f;var c=g.left+e-i;return{top:Math.round(j),left:Math.round(c)}};var getOffsetSum=function(a){var c=0,b=0;while(a){c=c+parseInt(a.offsetTop);b=b+parseInt(a.offsetLeft);a=a.offsetParent}return{top:c,left:b}};addListener(window,"load",function(){addListener(document,"mousedown",SimpleAutocomplete.an)});