/* ufd 0.6 : Unobtrusive Fast-filter Drop-down jQuery plugin. Authors: thetoolman@gmail.com Kadalashvili.Vladimir@gmail.com Version: 0.6 Website: http://code.google.com/p/ufd/ */ (function(g){g.widget("ui.ufd",{_init:function(){this.created||this._create()},_create:function(){if(!this.created){this.created=true;if(this.element[0].tagName.toLowerCase()!="select"){this.destroy();return false}this.options=g.extend(true,{},this.options);this.visibleCount=0;this.selectbox=this.element;this.logNode=g(this.options.logSelector);this.overflowCSS=this.options.allowLR?"overflow":"overflowY";var a=this.selectbox.attr("name"),b=this.options.prefix+a;a=this.options.submitFreeText?a:b;var c= "",d=this.selectbox.attr("id");if(d){c=this.options.prefix+d;this.labels=g("label[for='"+d+"']").attr("for",c)}this.options.submitFreeText&&this.selectbox.attr("name",b);if(this.options.calculateZIndex)this.options.zIndexPopup=this._calculateZIndex();this.css=b=this.options.css;this.options.useUiCss&&g.extend(this.css,this.options.uiCss);if(!b.skin)b.skin=this.options.skin;this.wrapper=g([''].join(""));this.dropdown=g(['
'].join(""));this.selectbox.after(this.wrapper);this.getDropdownContainer().append(this.dropdown);this.input=this.wrapper.find("input");this.button=this.wrapper.find("button");this.listWrapper=this.dropdown.children(":first").css("z-index",this.options.zIndexPopup); this.listScroll=this.listWrapper.children(":first");g.fn.bgiframe&&this.listWrapper.bgiframe();if(!this.options.listWidthFixed){this.listWrapper.css({width:50,"min-width":100});this.options.listWidthFixed=this.listWrapper.width()<100;this.listWrapper.css({width:null,"min-width":null})}this._populateFromMaster();this._initEvents()}},_initEvents:function(){var a=this,b=g.ui.keyCode,c,d,e,h=this.options.css;this.input.bind("keydown keypress keyup",function(f){d=f.type=="keypress";e=f.type=="keyup";c= null;if(undefined===f.which)c=f.keyCode;else if(!d&&f.which!=0)c=f.keyCode;else return;switch(c){case b.HOME:case b.END:if(a.options.homeEndForCursor)return;case b.DOWN:case b.PAGE_DOWN:case b.UP:case b.PAGE_UP:case b.ENTER:a.stopEvent(f);default:}if(!e!=(c!=b.TAB&&c!=b.ENTER)){a.lastKey=c;switch(c){case b.SHIFT:case b.CONTROL:break;case b.DOWN:a.selectNext(false);break;case b.PAGE_DOWN:a.selectNext(true);break;case b.END:a.selectLast();break;case b.UP:a.selectPrev(false);break;case b.PAGE_UP:a.selectPrev(true); break;case b.HOME:a.selectFirst();break;case b.ENTER:a.hideList();a.tryToSetMaster();a.inputFocus();break;case b.TAB:a.realLooseFocusEvent();break;case b.ESCAPE:a.hideList();a.revertSelected();break;default:a.showList();a.filter(false,true);break}}});this.input.bind("click",function(f){if(a.isDisabled)a.stopEvent(f);else if(!a.listVisible()){a.filter(true);a.inputFocus();a.showList()}});this.input.bind("focus",function(f){if(a.isDisabled)a.stopEvent(f);else a.internalFocus||a.realFocusEvent()});this.button.bind("mouseover", function(){a.button.addClass(h.buttonHover)});this.button.bind("mouseout",function(){a.button.removeClass(h.buttonHover)});this.button.bind("mousedown",function(){a.button.addClass(h.buttonMouseDown)});this.button.bind("mouseup",function(){a.button.removeClass(h.buttonMouseDown)});this.button.bind("click",function(f){if(a.isDisabled)a.stopEvent(f);else if(a.listVisible()){a.hideList();a.inputFocus()}else{a.filter(true);a.inputFocus();a.showList()}});this.listScroll.bind("DOMMouseScroll mousewheel", function(f){a.stopEvent(f);f=f?f:window.event;f=f.detail?f.detail*-1:f.wheelDelta/40;f=a.listScroll.scrollTop()+(f>0?-1*a.itemHeight:1*a.itemHeight);a.listScroll.scrollTop(f)});this.listScroll.bind("mouseover mouseout click",function(f){if("LI"==f.target.nodeName.toUpperCase()){a.setActiveTimeout&&clearTimeout(a.setActiveTimeout);if("mouseout"==f.type){g(f.target).removeClass(h.liActive);a.setActiveTimeout=setTimeout(function(){g(a.selectedLi).addClass(h.liActive)},a.options.delayYield)}else if("mouseover"== f.type){a.selectedLi!=f.target&&g(a.selectedLi).removeClass(h.liActive);g(f.target).addClass(h.liActive)}else{a.stopEvent(f);var j=g.trim(g(f.target).text());a.input.val(j);a.setActive(f.target);if(a.tryToSetMaster()){a.hideList();a.filter(true)}a.inputFocus()}}return true});this.selectbox.bind("change.ui.ufd",function(){if(a.isUpdatingMaster){a.isUpdatingMaster=false;return true}a.revertSelected()});this._myDocClickHandler=function(f){a.button.get(0)==f.target||a.input.get(0)==f.target||a.internalFocus&& a.realLooseFocusEvent()};g(document).bind("click.ui.ufd",this._myDocClickHandler);if(this.options.polling){a=this;this._myPollId=setInterval(function(){a.dimensioned||a.setDimensions();if(a.selectbox[0].disabled!=a.isDisabled)a.selectbox[0].disabled?a.disable():a.enable()},a.options.polling)}},realFocusEvent:function(){this.internalFocus=true;this._triggerEventOnMaster("focus");this.wrapper.addClass(this.options.css.skin+"-"+this.options.css.inputFocus);this.input.addClass(this.options.css.inputFocus); this.button.addClass(this.options.css.inputFocus);this.filter(true);this.inputFocus();this.showList()},realLooseFocusEvent:function(){this.internalFocus=false;this.hideList();this.wrapper.removeClass(this.options.css.skin+"-"+this.options.css.inputFocus);this.input.removeClass(this.options.css.inputFocus);this.button.removeClass(this.options.css.inputFocus);this.tryToSetMaster();this._triggerEventOnMaster("blur")},_triggerEventOnMaster:function(a){if(document.createEvent){var b=document.createEvent("HTMLEvents"); b.initEvent(a,true,true);this.selectbox.get(0).dispatchEvent(b)}else document.createEventObject&&this.selectbox.get(0).fireEvent("on"+a)},inputFocus:function(){this.input.focus();this.getCurrentTextValue().length&&this.selectAll()},inputBlur:function(){this.input.blur()},showList:function(){if(!this.listVisible()){this.listWrapper.removeClass(this.css.hidden);this.setListDisplay()}},hideList:function(){if(this.listVisible()){this.listWrapper.addClass(this.css.hidden);this.listItems.removeClass(this.css.hidden)}}, filter:function(a,b){var c=this;this.updateOnTimeout&&clearTimeout(this.updateOnTimeout);this.filterOnTimeout&&clearTimeout(this.filterOnTimeout);this.filterOnTimeout=this.updateOnTimeout=null;var d=c.getCurrentTextValue(),e=function(){var f=c.trie.find(d);c.trie.matches=f.matches;c.trie.misses=f.misses;c.updateOnTimeout=setTimeout(function(){h()},c.options.delayYield)},h=function(){var f=c.getActive();c.options.addEmphasis&&c.emphasis(c.trie.matches,true,d);c.visibleCount=c.overwriteClass(c.trie.matches, "");if(a||!c.trie.matches.length){c.visibleCount+=c.overwriteClass(c.trie.misses,"");c.options.addEmphasis&&c.emphasis(c.trie.misses,false,d)}else c.overwriteClass(c.trie.misses,c.css.hidden);if(!f.hasClass(c.css.hidden)&&f.length&&c.trie.matches.length)c.setActive(f.get(0));else{f=c.listItems.filter(":visible:first");c.setActive(f.get(0))}c.setListDisplay()};if(b)this.filterOnTimeout=setTimeout(function(){e()},this.options.delayFilter);else e()},_encodeDom:g("
"),_encodeString:function(a){return g.trim(this._encodeDom.text(a).html())}, emphasis:function(a,b,c){var d,e,h,f,j;e=c.length||0;var k=this.selectbox.get(0).options;d=a.length;if(b=b&&e>0){j=this._encodeString(c).replace(/([\\\^\$*+[\]?{}.=!:(|)])/g,"\\$1");j=new RegExp("("+j+")","gi");this.hasEmphasis=true}for(;d--;){c=a[d];for(e=c.length;e--;){h=c[e];f=g.trim(k[h.getAttribute("name")].innerHTML);h.innerHTML=b?f.replace(j,"$1"):f}}},_timingMeasure_firebug:function(a,b){a?console.time(b):console.timeEnd(b)},_timingMeasure:function(a,b){this._timingMeasure_firebug(a, b)},removeEmphasis:function(){if(this.hasEmphasis){this.hasEmphasis=false;for(var a=this.selectbox.get(0).options,b=this.list.get(0).getElementsByTagName("LI"),c=b.length,d;c--;){d=b[c];d.innerHTML=g.trim(a[d.getAttribute("name")].innerHTML)}}},tryToSetMaster:function(){var a=null,b=this.getActive();if(b.length)a=b.attr("name");if(a==null||a==""||a<0){this.options.submitFreeText||this.revertSelected();return false}b=this.selectbox.get(0);var c=b.selectedIndex,d=b.options[a];if(!this.options.submitFreeText|| this.input.val()==d.text){this.input.val(d.text);if(a!=c){this.isUpdatingMaster=true;b.selectedIndex=a;this._triggerEventOnMaster("change")}return true}return false},_populateFromMaster:function(){var a=!this.selectbox.filter("[disabled]").length;this.disable();this.trie=new i(this.options.infix,this.options.caseSensitive);this.trie.matches=[];this.trie.misses=[];var b=this,c=[];c.push("");this.listScroll.html(c.join(""));this.list=this.listScroll.find("ul:first");c=this.list.get(0).getElementsByTagName("LI");this.listItems=g(c);h=c.length;for(f=0;h--;){e=d[f];b.trie.add(g.trim(e.text),c[f++])}this.visibleCount=c.length;this.setInputFromMaster();this.selectedLi=null;this.dimensioned=false;this.setDimensions();a&&this.enable();this._moveAttrs(this.selectbox,this.input,this.options.moveAttrs)},_moveAttrs:function(a, b,c){for(var d=0;dthis.options.maxWidth)a=this.options.maxWidth}var b=this.options.mimicCSS;for(propPtr in b){var c=b[propPtr];!b.hasOwnProperty(propPtr)||typeof c==="function"||this.wrapper.css(c,this.selectbox.css(c))}if(!this.selectIsWrapped){this.wrapper.get(0).appendChild(this.selectbox.get(0));this.selectIsWrapped=true}this.wrapper.removeClass(this.css.hidden);this.listWrapper.removeClass(this.css.hidden); var d=this.button.outerWidth(true);b=this.wrapper.outerWidth()-this.wrapper.width();var e=this.input.outerWidth(true)-this.input.width();c=this.listScroll.outerWidth()-this.listScroll.width();this.input.width(a-d-e);this.wrapper.width(a);d=this.options.listWidthFixed?"width":"min-width";this.listWrapper.css(d,a+b);this.listScroll.css(d,a+b-c);this.listWrapper.addClass(this.css.hidden);this.dimensioned=true}},setInputFromMaster:function(){var a=this.selectbox.get(0),b="";try{b=a.options[a.selectedIndex].text}catch(c){}this.input.val(b)}, revertSelected:function(){this.setInputFromMaster();this.filter(true)},setListDisplay:function(){if(!this.itemHeight)this.itemHeight=this.listItems.filter("li:first").outerHeight(true);var a;if(this.visibleCount>this.options.listMaxVisible){a=this.options.listMaxVisible*this.itemHeight;this.listScroll.css(this.overflowCSS,"scroll")}else{a=this.visibleCount*this.itemHeight;this.listScroll.css(this.overflowCSS,"hidden")}this.listScroll.height(a);var b=this.listScroll.outerHeight();this.listWrapper.height(b); var c=this.wrapper.offset(),d=this.wrapper.outerHeight(),e=c.top+d+b,h=g(window).height()+g(document).scrollTop(),f=c.left;if(e>h){this.listWrapper.addClass(this.css.listWrapperUp);b=c.top-b}else{this.listWrapper.removeClass(this.css.listWrapperUp);b=c.top+d}this.listWrapper.css("left",f);this.listWrapper.css("top",b);this.scrollTo();return a},getActive:function(){if(this.selectedLi==null)return g([]);return g(this.selectedLi)},setActive:function(a){g(this.selectedLi).removeClass(this.css.liActive); this.selectedLi=a;g(this.selectedLi).addClass(this.css.liActive)},selectFirst:function(){this.afterSelect(this.listItems.filter(":not(.invisible):first"))},selectLast:function(){this.afterSelect(this.listItems.filter(":not(.invisible):last"))},selectPrev:function(a){this.afterSelect(this.searchRelativeVisible(false,a?this.options.pageLength:1))},selectNext:function(a){this.afterSelect(this.searchRelativeVisible(true,a?this.options.pageLength:1))},afterSelect:function(a){if(a!=null){this.setActive(a); this.input.val(a.text());this.scrollTo();this.tryToSetMaster();this.inputFocus();this.removeEmphasis()}},searchRelativeVisible:function(a,b){var c=this.getActive();if(!c.length){this.selectFirst();return null}var d;do{d=c;do d=a?d.next():d.prev();while(d.length&&d.hasClass(this.css.hidden));if(d.length)c=d}while(--b);return c},scrollTo:function(){if("scroll"!=this.listScroll.css(this.overflowCSS))return false;var a=this.getActive();if(!a.length)return false;var b=Math.floor(a.position().top);a=a.outerHeight(true); var c=this.listWrapper.height(),d=this.listScroll.scrollTop(),e=this.options.viewAhead*a;if(b=c-e)b=d+b-c+a+e;else return false;this.listScroll.scrollTop(b);return true},getCurrentTextValue:function(){return g.trim(this.input.val())},stopEvent:function(a){a=a?a:window.event;a.cancel=true;a.cancelBubble=true;a.returnValue=false;a.stopPropagation&&a.stopPropagation();a.preventDefault&&a.preventDefault()},overwriteClass:function(a,b){var c,d,e,h=0;for(d=a.length;d--;){c=a[d];e= c.length;for(h+=e;e--;)c[e].setAttribute(g.ui.ufd.classAttr,b)}return h},listVisible:function(){return!this.listWrapper.hasClass(this.css.hidden)},disable:function(){this.hideList();this.isDisabled=true;this.button.addClass(this.css.buttonDisabled);this.input.addClass(this.css.inputDisabled);this.input.attr("disabled","disabled");this.selectbox.attr("disabled","disabled")},enable:function(){this.isDisabled=false;this.button.removeClass(this.css.buttonDisabled);this.input.removeClass(this.css.inputDisabled); this.input.removeAttr("disabled");this.selectbox.removeAttr("disabled")},selectAll:function(){this.input.get(0).select()},getDropdownContainer:function(){var a=g("#"+this.options.dropDownID);a.length||(a=g("
").appendTo("body").css("height",0).attr("id",this.options.dropDownID));return a},log:function(a){if(this.options.log){window.console&&window.console.log&&console.log(a);this.logNode&&this.logNode.length&&this.logNode.prepend("
"+a+"
")}},_calculateZIndex:function(){var a,b= this.options.zIndexPopup;this.selectbox.parents().each(function(){a=parseInt(g(this).css("zIndex"),10);if(a>b)b=a});return b+1},changeOptions:function(){this._populateFromMaster()},destroy:function(){this.selectIsWrapped&&this.wrapper.before(this.selectbox);this._moveAttrs(this.input,this.selectbox,this.options.moveAttrs);this.labels.attr("for",this.selectbox.attr("id"));this.labels=null;this.selectbox.unbind("change.ui.ufd");g(document).unbind("click.ui.ufd",this._myDocClickHandler);this._myPollId&& clearInterval(this._myPollId);this.wrapper.remove();this.listWrapper.remove();if(g.ui.version<"1.8"){this.selectbox.unbind("setData.ui.ufd");this.selectbox.unbind("getData.ui.ufd");this.selectbox.unbind("remove");g.widget.prototype.destroy.apply(this,arguments)}else g.Widget.prototype.destroy.apply(this,arguments);this._encodeDom=this.selectbox=null},dimensioned:false,selectIsWrapped:false,internalFocus:false,lastKey:null,selectedLi:null,isUpdatingMaster:false,created:false,hasEmphasis:false,isDisabled:false}); var i=function(a,b){this.isInfix=!!a;this.isCaseSensitive=!!b;this.root=[null,{},false];this.infixRoots=a?{}:null};i.prototype.add=function(a,b){a=this.cleanString(a);for(var c=a.length,d=this.root,e,h=0;h0;){var d=b.pop();if(d[2]!=c){d[2]=c;d[0]&&a.unshift(d[0]);for(chr in d[1])d[1].hasOwnProperty(chr)&&b.push(d[1][chr])}}};i.prototype.cleanString=function(a){this.isCaseSensitive||(a=a.toLowerCase());return a};g.ui.ufd.getNewTrie=function(a,b){return new i(a,b)};g.extend(g.ui.ufd,{version:"0.6",getter:"", classAttr:g.support.style?"class":"className",defaults:{skin:"plain",prefix:"ufd-",dropDownID:"ufd-container",logSelector:"#log",mimicCSS:["float","tabindex","marginLeft","marginTop","marginRight","marginBottom"],moveAttrs:["tabindex","title"],infix:true,addEmphasis:false,caseSensitive:false,submitFreeText:false,homeEndForCursor:false,allowLR:false,calculateZIndex:false,useUiCss:false,log:false,unwrapForCSS:false,listWidthFixed:true,polling:250,listMaxVisible:10,minWidth:50,maxWidth:null,manualWidth:null, viewAhead:1,pageLength:10,delayFilter:g.support.style?1:150,delayYield:1,zIndexPopup:101,css:{input:"",inputDisabled:"disabled",inputFocus:"focus",button:"",buttonIcon:"icon",buttonDisabled:"disabled",buttonHover:"hover",buttonMouseDown:"mouseDown",li:"",liActive:"active",hidden:"invisible",wrapper:"ufd",listWrapper:"list-wrapper",listWrapperUp:"list-wrapper-up",listScroll:"list-scroll"},uiCss:{skin:"uiCss",input:"ui-widget-content",inputDisabled:"disabled",button:"ui-button",buttonIcon:"ui-icon ui-icon-triangle-1-s", buttonDisabled:"disabled",buttonHover:"ui-state-focus",buttonMouseDown:"ui-state-active",li:"ui-menu-item",liActive:"ui-state-hover",hidden:"invisible",wrapper:"ufd ui-widget ui-widget-content",listWrapper:"list-wrapper ui-widget ui-widget",listWrapperUp:"list-wrapper-up",listScroll:"list-scroll ui-widget-content"}}});g.ui.ufd.prototype.options=g.ui.ufd.defaults})(jQuery);