36 lines
22 KiB
JavaScript
36 lines
22 KiB
JavaScript
|
// script.aculo.us controls.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
|
||
|
// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||
|
// (c) 2005-2009 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
||
|
// (c) 2005-2009 Jon Tirsen (http://www.tirsen.com)
|
||
|
// Contributors:
|
||
|
// Richard Livsey
|
||
|
// Rahul Bhargava
|
||
|
// Rob Wills
|
||
|
//
|
||
|
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||
|
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
||
|
// Autocompleter.Base handles all the autocompletion functionality
|
||
|
// that's independent of the data source for autocompletion. This
|
||
|
// includes drawing the autocompletion menu, observing keyboard
|
||
|
// and mouse events, and similar.
|
||
|
//
|
||
|
// Specific autocompleters need to provide, at the very least,
|
||
|
// a getUpdatedChoices function that will be invoked every time
|
||
|
// the text inside the monitored textbox changes. This method
|
||
|
// should get the text for which to provide autocompletion by
|
||
|
// invoking this.getToken(), NOT by directly accessing
|
||
|
// this.element.value. This is to allow incremental tokenized
|
||
|
// autocompletion. Specific auto-completion logic (AJAX, etc)
|
||
|
// belongs in getUpdatedChoices.
|
||
|
//
|
||
|
// Tokenized incremental autocompletion is enabled automatically
|
||
|
// when an autocompleter is instantiated with the 'tokens' option
|
||
|
// in the options parameter, e.g.:
|
||
|
// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
|
||
|
// will incrementally autocomplete with a comma as the token.
|
||
|
// Additionally, ',' in the above example can be replaced with
|
||
|
// a token array, e.g. { tokens: [',', '\n'] } which
|
||
|
// enables autocompletion on multiple tokens. This is most
|
||
|
// useful when one of the tokens is \n (a newline), as it
|
||
|
// allows smart autocompletion after linebreaks.
|
||
|
if(typeof Effect=="undefined")throw"controls.js requires including script.aculo.us' effects.js library";var Autocompleter={};Autocompleter.Base=Class.create({baseInitialize:function(e,t,n){e=$(e),this.element=e,this.update=$(t),this.hasFocus=!1,this.changed=!1,this.active=!1,this.index=0,this.entryCount=0,this.oldElementValue=this.element.value,this.setOptions?this.setOptions(n):this.options=n||{},this.options.paramName=this.options.paramName||this.element.name,this.options.tokens=this.options.tokens||[],this.options.frequency=this.options.frequency||.4,this.options.minChars=this.options.minChars||1,this.options.onShow=this.options.onShow||function(e,t){if(!t.style.position||t.style.position=="absolute")t.style.position="absolute",Position.clone(e,t,{setHeight:!1,offsetTop:e.offsetHeight});Effect.Appear(t,{duration:.15})},this.options.onHide=this.options.onHide||function(e,t){new Effect.Fade(t,{duration:.15})},typeof this.options.tokens=="string"&&(this.options.tokens=new Array(this.options.tokens)),this.options.tokens.include("\n")||this.options.tokens.push("\n"),this.observer=null,this.element.setAttribute("autocomplete","off"),Element.hide(this.update),Event.observe(this.element,"blur",this.onBlur.bindAsEventListener(this)),Event.observe(this.element,"keydown",this.onKeyPress.bindAsEventListener(this))},show:function(){Element.getStyle(this.update,"display")=="none"&&this.options.onShow(this.element,this.update),!this.iefix&&Prototype.Browser.IE&&Element.getStyle(this.update,"position")=="absolute"&&(new Insertion.After(this.update,'<iframe id="'+this.update.id+'_iefix" '+'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" '+'src="javascript:false;" frameborder="0" scrolling="no"></iframe>'),this.iefix=$(this.update.id+"_iefix")),this.iefix&&setTimeout(this.fixIEOverlapping.bind(this),50)},fixIEOverlapping:function(){Position.clone(this.update,this.iefix,{setTop:!this.update.style.height}),this.iefix.style.zIndex=1,this.update.style.zIndex=2,Element.show(this.iefix)},hide:function(){this.stopIndicator(),Element.getStyle(this.update,"display")!="none"&&this.options.onHide(this.element,this.update),this.iefix&&Element.hide(this.iefix)},startIndicator:function(){this.options.indicator&&Element.show(this.options.indicator)},stopIndicator:function(){this.options.indicator&&Element.hide(this.options.indicator)},onKeyPress:function(e){if(this.active)switch(e.keyCode){case Event.KEY_TAB:case Event.KEY_RETURN:this.selectEntry(),Event.stop(e);case Event.KEY_ESC:this.hide(),this.active=!1,Event.stop(e);return;case Event.KEY_LEFT:case Event.KEY_RIGHT:return;case Event.KEY_UP:this.markPrevious(),this.render(),Event.stop(e);return;case Event.KEY_DOWN:this.markNext(),this.render(),Event.stop(e);return}else if(e.keyCode==Event.KEY_TAB||e.keyCode==Event.KEY_RETURN||Prototype.Browser.WebKit>0&&e.keyCode==0)return;this.changed=!0,this.hasFocus=!0,this.observer&&clearTimeout(this.observer),this.observer=setTimeout(this.onObserverEvent.bind(this),this.options.frequency*1e3)},activate:function(){this.changed=!1,this.hasFocus=!0,this.getUpdatedChoices()},onHover:function(e){var t=Event.findElement(e,"LI");this.index!=t.autocompleteIndex&&(this.index=t.autocompleteIndex,this.render()),Event.stop(e)},onClick:function(e){var t=Event.findElement(e,"LI");this.index=t.autocompleteIndex,this.selectEntry(),this.hide()},onBlur:function(e){setTimeout(this.hide.bind(this),250),this.hasFocus=!1,this.active=!1},render:function(){if(this.entryCount>0){for(var e=0;e<this.entryCount;e++)this.index==e?Element.addClassName(this.getEntry(e),"selected"):Element.removeClassName(this.getEntry(e),"selected");this.hasFocus&&(this.show(),this.active=!0)}else this.active=!1,this.hide()},markPrevious:function(){this.index>0?this.index--:this.index=this.entryCount-1,this.getEntry(this.index).scrollIntoView(!0)},markNext:function(){this.index<this.entryCount-1?this.index++:this.index=0,this.getEntry(this.index).scrollIntoView(!1)},getEntry:function(e){return this.update.firstChild.childNodes[e]},getCurrentEntry:function()
|