var SelectBox = $Class( { $init : function() { this.info = this._initOption( arguments[0] ); var select = $( this.info.id ); if ( !select ) return; this._getAttribute( select ); this._setEvent(); this.control = new SelectBox.Control( this ); this.input = new SelectBox.Input( this ); this.box = new SelectBox.NullBox( this ); // lazy initialization -> IE6 Renderer Bug //this.box = SelectBox.Factory.newBox( this ); this._initFirstValue(); this._realignElement(); if ( this.info.loadEvent ) { $Fn(this._initFirstValue, this).attach( window, "load" ); } }, _initOption : function( argu ) { var options = { keepTitle : false, boxType : "basic", handlerType : "basic", cols : 1, boxY : 0, align : "left", spanClass : "seljs_selected", spanTitleClass : "seljs_title", boxClass : "seljs_option", boxOverClass : "seljs_mover", iframeClass : "seljs_iframe", focusClass : "sopen", multiClass : "selcol", maxHeight : 1200, useIframe : false, loadEvent : true, BtnClick : false }; if (typeof argu == "undefined" ) argu = new Object; for(var x in argu) { options[x] = argu[x]; } if ( options.cols != 1 ) { options.boxType = "multicolumn"; options.handlerType = "multicolumn"; options.boxClass = options.boxClass + " " + options.multiClass; } return options; }, _getAttribute : function( select ) { this.info.base = select; this.info.parent = select.parentNode; this.info.agent = $Agent().navigator(); this.info.title = select.getAttribute( "title" ) || false; this.info.name = select.getAttribute( "name" ) || ""; this.info.width = 0; this.info.selected = -1; this.info.list = new Array(); this.info.optionType = new Array(); this.info.imgList = new Array(); var children = select.getElementsByTagName( "OPTION" ); for ( var i = 0, j = 0 ; i < children.length ; i++ ) { var option = children[i]; var type = SelectBox.getOptionType( option.firstChild.nodeValue ); var newValue = option.firstChild.nodeValue; if ( type != SelectBox.NORMAL ) { newValue = ( type == SelectBox.PERIOD ? this.info.periodOption.value : type == SelectBox.URL ? this.info.urlOption.value : newValue ); } this.info.optionType.push( type ); this.info.list.push( new Array( newValue, ( option.getAttribute( "value" ) || "" ) ) ); var imgSrc = ( this.info.agent.safari ? option.getAttribute( "style" ) || "none" : $Element( option ).css( "backgroundImage" ) ); var imgAlt = option.getAttribute( "title" ) || ""; if ( imgSrc != "none" ) { this.info.imgList.push( new Array( imgSrc.replace( /.*url\(\"?([^\"]+)\"?\)/, "$1" ), imgAlt ) ); } else { this.info.imgList.push( new Array( "", "" ) ); } if ( option.defaultSelected ) { this.info.selected = j; } j++; } this.info.width = parseInt( select.offsetWidth || select.style.width ); }, _setEvent : function() { var select = this.info.base; this.Onchange = ( this._isValidEvent( select.onchange ) || this._nullEvent ); this.Onkeydown = ( this._isValidEvent( select.onkeydown ) || this._nullEvent ); this.Onkeypress = ( this._isValidEvent( select.onkeypress ) || this._nullEvent ); this.Onmouseout = ( this._isValidEvent( select.onmouseout ) || this._nullEvent ); this.Onmouseover = ( this._isValidEvent( select.onmouseover ) || this._nullEvent ); this.Onclick = ( this._isValidEvent( select.onclick ) || this._nullEvent ); this.Onfocus = ( this._isValidEvent( select.onfocus ) || this._nullEvent ); this.Onblur = ( this._isValidEvent( select.onblur ) || this._nullEvent ); }, _isValidEvent : function( func ) { if ( func && typeof func == "function" ) { return func; } else { return false; } }, _initFirstValue : function() { if ( this.info.selected < 0 ) { if ( this.info.title ) { this.input.setTitle( this.info.title ); } else { this.input.setValue( this.info.list[0][0], this.info.list[0][1] ); } } else { this.input.setValue( this.info.list[ this.info.selected ][0], this.info.list[ this.info.selected ][1] ); } }, _realignElement : function() { this.info.base.style.display = "none"; this.info.base.removeAttribute( "name" ); this.info.parent.insertBefore( this.input._span, this.info.base ); }, _getIndex : function( value ) { var index = -1; var list = this.info.list; for ( var i = 0 ; i < list.length ; i++ ) { if ( list[i][1] == value ) { index = i; break; } } return index; }, length : function() { return this.info.list.length; }, getValue : function() { return { displayValue : ( this.control.index.now == -1 ? this.info.title : this.info.list[ this.control.index.now ][0] ), value : ( this.control.index.now == -1 ? "" : this.info.list[ this.control.index.now ][1] ), index : this.control.index.now }; }, setValue : function( value, initFirstValue ) { var index = this._getIndex( value ); if ( index == -1 ) return; this.control.changeIndex( index ); this.control.initAllIndex( index ); if ( initFirstValue === true ) { this.info.selected = index; } }, addValue : function( viewValue, value, imgSrc, imgAlt ) { var index = this._getIndex( value ); if ( index != -1 ) return this; this.info.list.push( new Array( viewValue, value ) ); this.info.imgList.push( new Array( imgSrc || "", imgAlt || "" ) ); if ( !this.box.nullBox ) { this.box.refresh(); } return this; }, focus : function() { this.input.focus(); }, show : function() { this.box.show(); }, hide : function() { this.box.hide(); }, _remove : function( index ) { this.info.list.splice( index, 1 ); this.info.imgList.splice( index, 1 ); if ( !this.box.nullBox ) { this.box.refresh(); if ( index == this.control.index.now ) { this.control.changeIndex( 0 ); this.box.changeChildStyle( 0 ); } } }, removeValue : function( value ) { var index = this._getIndex( value ); if ( index == -1 ) return; this._remove( index ); return this; }, removePart : function( size ) { var length = this.info.list.length; if ( length > size ) { for ( var index = length ; index >= size ; index-- ) { this._remove( index ); } } }, recovery : function() { this.input._span.display = "none"; this.info.base.style.display = "block"; this.info.base.name = this.info.name; this.input._hidden.name = ""; }, rrecovery : function() { this.info.base.style.display = "none"; this.info.base.removeAttribute( "name" ); this.input._span.display = "block"; this.input._hidden.name = this.info.name; }, Onchange : null, Onkeydown : null, Onkeypress : null, Onmouseout : null, Onmouseover : null, Onclick : null, Onfocus : null, Onblur : null, BtnClick : null, _nullEvent : function() {} } ); SelectBox.fireEvent = function( func, event, select ) { func.call( select, event, select ); }; SelectBox.EXTRA_WIDTH = { ie : 0, firefox : 0, opera : 0, safari : 0, getWidth : function( agent ) { return ( agent.ie ? this.ie : agent.firefox ? this.firefox : agent.safari ? this.safari : this.opera ); }, setWidth : function( extra ) { for ( var p in extra ) { if ( this[p] < extra[p] ) this[p] = extra[p]; } } } SelectBox.Factory = { newHandler : function( control ) { var handler = null; switch( control.select.info.handlerType ) { case "basic" : handler = new SelectBox.Handler( control ); break; case "multicolumn" : handler = new SelectBox.MultiColumnHandler( control ); break; } return handler; }, newBox : function( select ) { var box = null; switch( select.info.boxType ){ case "basic" : box = new SelectBox.Box( select ); break; case "multicolumn" : box = new SelectBox.MultiBox( select ); break; } return box; }, newOption : function( select, box, index ) { var option = null; var type = select.info.optionType[index]; switch( type ) { case SelectBox.PERIOD : option = new SelectBox.PeriodOption( select, box, index ); break; case SelectBox.URL : option = new SelectBox.URLOption( select, box, index ); break; default : option = new SelectBox.Option( select, box, index ); } return option; } }; SelectBox.getOptionType = function( value ) { var type = value.toLowerCase(); var result = SelectBox.NORMAL; switch( type ) { case SelectBox.SHARP + SelectBox.PERIOD : result = SelectBox.PERIOD; break; case SelectBox.SHARP + SelectBox.URL : result = SelectBox.URL; break; default : } return result; } SelectBox.SHARP = "#"; SelectBox.NORMAL = "normal"; SelectBox.PERIOD = "period"; SelectBox.URL = "url"; SelectBox.INDEX = "index"; SelectBox.DOCTYPE = "transitional"; SelectBox.BOX_LIST = new Array(); SelectBox.CHECK_AREA = function( event ) { var element = event.element; var elementID = []; if ( !!element ) { for ( var i = 0 ; element != null && element.nodeType == 1 ; i++ ) { elementID[i] = element.id || ""; element = element.parentNode; } } var hasID = false; for ( var i = 0 ; i < SelectBox.BOX_LIST.length ; i++, hasID = false ) { var box = SelectBox.BOX_LIST[i]; for ( var j = 0 ; j < elementID.length ; j++ ) { if ( box[0] == elementID[j] || box[1] == elementID[j] ) { hasID = true; break; } } if ( hasID == false ) { $( box[2] ).style.display = "none"; $( box[1] ).style.display = "none"; } } } $Fn( SelectBox.CHECK_AREA, window ).attach( document, "click" ); SelectBox.Input = $Class( { $init : function( select ) { this.select = select; this.info = select.info; this._createDOM(); this._addEvent(); }, _createDOM : function() { this._span = $( "" ); this._span.className = this.info.spanTitleClass; this._span.appendChild( this._input = this._createInput() ); this._span.appendChild( this._hidden = this._createHidden() ); }, _createInput : function() { var input = $( "" ); var ele = $Element( input ); ele.attr( { id : ( this.id = this.info.id + "Input" + new Date().getMilliseconds() ), //name : this.info.name + new Date().getMilliseconds(), type : "text", readOnly : "readOnly", value : "" } ); ele.css( { width : this.info.width + "px" } ); return input; }, _createHidden : function() { var hidden = $( "" ); $Element( hidden ).attr({ type : "hidden", name : this.info.name, value : "" }); hidden.style.display = "none"; return hidden; }, _addEvent : function() { $Fn(this._onfocus,this).attach(this._input, "focus"); $Fn(this._onblur,this).attach(this._input, "blur"); $Fn(this._onclick,this).attach(this._input, "click"); $Fn(this._onkeydown,this).attach(this._input, "keydown"); //$Fn(this._onmousedown,this).attach(this._input, "mousedown"); //$Fn(this._onmouseup,this).attach(this._input, "mouseup"); //$Fn(this._onmouseover,this).attach(this._input, "mouseover"); //$Fn(this._onmouseout,this).attach(this._input, "mouseout"); //$Fn(this._onkeypress,this).attach(this._input, "keypress"); }, setValue : function( viewValue, value ) { if ( this.info.keepTitle ) { this._hidden.value = value; } else { this._input.value = viewValue; this._hidden.value = value; } }, setHiddenValue : function( value ) { this._hidden.value = value; }, setTitle : function( title ) { this._input.value = title; this._hidden.value = ""; }, getPos : function() { var inputElement = $Element( this._input ); var pos = inputElement.offset(); var leftGap = Math.abs( parseInt( $Element( document.body ).css( "borderLeftWidth" ) ) ); var topGap = parseInt( inputElement.css( "borderTopWidth" ) ); var left = ( this.select.info.agent.firefox ? pos.left + ( leftGap * 2 ) : pos.left ); var top = ( this.select.info.agent.ie ? pos.top - topGap : pos.top ); return { x : parseInt( left ), y : parseInt( top ) + parseInt( this._input.offsetHeight ) }; }, getWidth : function() { return this._input.offsetWidth; }, getBorderWidth : function() { var ele = $Element( this._input ); var width = 0; if ( SelectBox.DOCTYPE == "transitional" ) { if ( !this.select.info.agent.ie ) width = parseInt( ele.css( "borderLeftWidth" ) || 0 ) + parseInt( ele.css( "borderRightWidth" ) || 0 ); } else if ( SelectBox.DOCTYPE == "loose" || SelectBox.DOCTYPE == "xhtml" ) { width -= parseInt( ele.css( "marginLeft" ) || 0 ) + parseInt( ele.css( "marginRight" ) || 0 ); width -= parseInt( ele.css( "paddingLeft" ) || 0 ) + parseInt( ele.css( "paddingRight" ) || 0 ); } return width; }, focus : function() { this._input.focus(); }, _onclick : function( e ) { this.select.box.display(); SelectBox.fireEvent( this.select.Onclick, e, this.select ); }, _onfocus : function( e ) { this._span.className = this._span.className + " " + this.info.focusClass; SelectBox.fireEvent( this.select.Onfocus, e, this.select ); }, _blurStyle : function( cName ) { return cName.replace( new RegExp( this.info.focusClass ), "" ); }, _onblur : function( e ) { this._span.className = this._blurStyle( this._span.className ); if ( !this.select.control.isFireOnchange() ) { this.select.control.firedOnchange(); this.select.Onchange( e, this.select ); } SelectBox.fireEvent( this.select.Onblur, e, this.select ); }, _onkeydown : function( e ) { this.select.control.keydown( e ); SelectBox.fireEvent( this.select.Onkeydown, e, this.select ); } /* _onmousedown : function( e ) { SelectBox.fireEvent( this.select.Onmousedown, e, this.select ); }, _onmouseup : function( e ) { SelectBox.fireEvent( this.select.Onmouseup, e, this.select ); }, _onmouseover : function( e ) { SelectBox.fireEvent( this.select.Onmouseover, e, this.select ); }, _onmouseout : function( e ) { SelectBox.fireEvent( this.select.Onmouseout, e, this.select ); }, _onkeypress : function( e ) { SelectBox.fireEvent( this.select.Onkeypress, e, this.select ); } */ } ); SelectBox.Control = $Class( { $init : function( select ) { this.select = select; this.handler = SelectBox.Factory.newHandler( this ); this.index = { now : -1, mouse : -1, old : -1, pre : -1 }; this._isBlur = true; this._initIndex(); }, _initIndex : function() { if ( this.select.info.selected < 0 ) { if ( !this.select.info.title ) { this.initAllIndex( 0 ); } } else { this.initAllIndex( this.select.info.selected ); } }, initAllIndex : function( index ) { this.setIndex( index, SelectBox.Control.NOW ); this.setIndex( index, SelectBox.Control.MOUSE ); this.setIndex( index, SelectBox.Control.OLD ); this.setIndex( index, SelectBox.Control.PRE ); }, getIndex : function() { return this.index; }, setIndex : function( index, what ) { this.index[ what ] = index; }, keydown : function( e ) { var isFireKey = false; var index = ( this.index.now == this.index.mouse ? this.index.now : this.index.mouse ); var k = e.key(); if ( k.alt && k.down ) { this.select.box.display(); } else if ( k.up || k.down || k.left || k.right || ( k.keyCode >= 33 && k.keyCode <= 36 ) ) { var keyStr = ( k.up ? SelectBox.Control.UP : k.down ? SelectBox.Control.DOWN : k.left ? SelectBox.Control.LEFT : k.right ? SelectBox.Control.RIGHT : false ); var next = -1; if ( keyStr ) { next = this.handler.nextIndex( keyStr, index ) } else { next = ( k.keyCode == 33 || k.keyCode == 36 ? 0 : this.handler.getMaxIndex() ); // 33(Home), 36(PageUP), 34(DOWN), 35(PageDown) } this.select.box.focus( next ); e.stop(); } else if ( k.enter ) { if ( this.index.mouse != -1 ) this.changeIndex( parseInt( this.index.mouse ) ); this.select.box.hide(); isFireKey = true; this.select.input.focus(); e.stop(); } else if ( k.keyCode == 9 ) { // Tab this.select.box.hide(); isFireKey = true; } else if ( k.keyCode == 27 ) { // ESC this.select.box.hide(); } SelectBox.fireEvent( this.select.Onkeydown, e, this.select ); if ( !this.isFireOnchange() ) { if ( isFireKey && k.keyCode != 27 ) { this.firedOnchange(); this.select.Onchange( e, this.select ); } } }, changeIndex : function( index ) { this.changeValue( index ); this.index.pre = this.index.now; this.index.now = index; this.index.mouse = index; }, changeValue : function( index ) { if ( index != -1 ) this.select.input.setValue( this.select.info.list[ index ][0], this.select.info.list[ index ][1] ); }, firedOnchange : function() { this.index.old = this.index.now; }, isFireOnchange : function() { if ( this._isBlur == true ) { return this.index.old == this.index.now; } else { this._isBlur = true; return true; } }, setIsBlur : function( flag ) { this._isBlur = flag; } } ); SelectBox.Control.UP = "UP"; SelectBox.Control.DOWN = "DOWN"; SelectBox.Control.LEFT = "LEFT"; SelectBox.Control.RIGHT = "RIGHT"; SelectBox.Control.NOW = "now"; SelectBox.Control.MOUSE = "mouse"; SelectBox.Control.OLD = "old"; SelectBox.Control.PRE = "pre"; SelectBox.Handler = $Class( { $init : function( control ) { this.control = control; this.list = control.select.info.list; }, nextIndex : function( key, index ) { var row = parseInt( index ); var maxRow = this.getMaxIndex(); var nextIndex = index; if ( key == "UP" ){ // || key == "LEFT" ) { nextIndex = ( index > 0 ? row - 1 : index ); } else if ( key == "DOWN" ){ // || key == "RIGHT" ) { if ( index == -1 ) { nextIndex = 0; } else { if ( row != maxRow ) { nextIndex = row + 1; } else { nextIndex = index; } } } return nextIndex; }, getMaxIndex : function() { return this.list.length - 1; } } ); /* * public function * changeStyle * getElement * focus */ SelectBox.Option = $Class( { $init : function( select, box, index ) { this.select = select; this._box = box; this._index = index; this._element = this._initElement(); }, _initElement : function() { var li = $( "
  • " ); li.setAttribute( SelectBox.INDEX, this._index ); var imgSrc = this.select.info.imgList[ this._index ][0]; var imgAlt = this.select.info.imgList[ this._index ][1]; if ( imgSrc != "" ) { var img = $( "" ); img.src = imgSrc; img.alt = imgAlt; li.appendChild( img ); } $Fn( this._onmouseover, this ).attach( li, "mouseover" ); $Fn( this._onclick, this ).attach( li, "click" ); li.appendChild( document.createTextNode( this.select.info.list[ this._index ][0] ) ); return li; }, changeStyle : function() { this._box.initLIStyle(); this._element.className = this.select.info.boxOverClass; }, focus : function() { this.changeStyle(); this.select.control.changeIndex( this._index ); }, getElement : function() { return this._element; }, _onmouseover : function( e ) { this.changeStyle( this._index ); this.select.control.index.mouse = this._index; }, _onclick : function( e ) { var isFireOnchange = false; var readIndex = this._index; if ( this.select.control.index.now != this._index ) { isFireOnchange = true; this.focus(); //this.select.input.focus(); } this._box.hide(); this.select.input.focus(); if ( isFireOnchange ) { this.select.control.firedOnchange(); this.select.Onchange( e, this.select ); } } } ); SelectBox.NullBox = $Class( { $init : function( select ) { this.select = select; }, display : function() { this.select.box = SelectBox.Factory.newBox( this.select ); this.select.box.show(); }, focus : function( index ) { this.select.control.changeIndex( index ); }, changeChildStyle : function() {}, hide : function() {}, nullBox : true } ); SelectBox.Box = $Class( { $init : function( select ) { this.select = select; this.info = select.info; this._optionList = new Array(); this._initBox(); this._addEvent(); }, _initBox : function() { this._createIframe(); this._createUL(); this._checkHeight(); }, refresh : function() { document.body.removeChild( this.element ); this.element = null; this._createUL(); this._checkHeight(); this._addEvent(); }, _createUL : function() { var ul = $( "