+ var ComboBoxClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID ){\r
+ var elmBox = pettanr.util.getElementsByClassName( WRAPPER_ELM, 'combobox' )[ 0 ],\r
+ elmA = ELM_COMBOBOX.cloneNode( true ),\r
+ elmToggle = pettanr.util.getElementsByClassName( elmA, 'combobox-toggle' )[ 0 ],\r
+ elmValue = pettanr.util.getElementsByClassName( elmA, 'combobox-value' )[ 0 ].firstChild,\r
+ value, index = 0,\r
+ optionList = [],\r
+ instance = this,\r
+ oldBodyMouseupHandler,\r
+ focus = false,\r
+ visible = true,\r
+ enabled = true;\r
+ \r
+ elmBox.appendChild( elmA );\r
+ WRAPPER_ELM.onclick = onClick;\r
+ \r
+ function onClick(){\r
+ WRAPPER_ELM.onclick = null;\r
+ focus = true;\r
+ elmA.className = 'combobox-has-focus';\r
+ start( instance );\r
+ OptionControl.show( instance, optionList );\r
+ return false;\r
+ }\r
+ this.elm = elmBox;\r
+ this.focus = function(){\r
+ onClick();\r
+ }\r
+ this.blur = function( keyCode ){\r
+ OptionControl.hide( instance );\r
+ focus = false;\r
+ elmA.className = '';\r
+ finish( instance );\r
+ WRAPPER_ELM.onclick = onClick;\r
+ }\r
+ this.enabled = function(){\r
+ return enabled;\r
+ }\r
+ this.visible = function( _visible ){\r
+ if( _visible === true){\r
+ WRAPPER_ELM.style.display = '';\r
+ visible = true;\r
+ } else\r
+ if( _visible === false){\r
+ WRAPPER_ELM.style.display = 'none';\r
+ visible = false;\r
+ }\r
+ return visible;\r
+ }\r
+ this.value = function( _value ){\r
+ var i, j,\r
+ l=optionList.length,\r
+ _option;\r
+ if( Type.isString( _value ) === true && value !== _value ){\r
+ for( i=0; i<l; ++i ){\r
+ _option = optionList[ i ];\r
+ if( _value === _option.value ){\r
+ value = _value;\r
+ index = i;\r
+ elmValue.data = _option.displayValue;\r
+ if( focus === true ){\r
+ OptionControl.update( instance, _value );\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ return value;\r
+ }\r
+ this.selectIndex = function(){\r
+ return index;\r
+ }\r
+ this.createOption = function( displayValue, _value, isSelected ){\r
+ var exist = false,\r
+ option = null, _option,\r
+ _index;\r
+ _value = _value || displayValue;\r
+ for( var i = 0, l = optionList.length; i < l; ++i ){\r
+ if( _value === optionList[ i ].value ){\r
+ option = optionList[ i ];\r
+ _index = i;\r
+ break;\r
+ }\r
+ }\r
+ if( option === null ){\r
+ option = new OptionClass( instance, displayValue, _value );\r
+ _index = optionList.length;\r
+ optionList.push( option );\r
+ }\r
+ if( isSelected === true ){\r
+ elmValue.data = option.displayValue;\r
+ value = _value;\r
+ index = _index;\r
+ for( i = 0, l = optionList.length; i < l; ++i ){\r
+ _option = optionList[ i ];\r
+ _option.current( _option.value === _value );\r
+ }\r
+ }\r
+ return option;\r
+ }\r
+ this.groupID = GROUP_ID;\r
+ }\r
+ \r
+ var OptionControl = ( function(){\r
+ var ELM_OPTION_WRAPPER = ( function(){\r
+ var ret = document.createElement( 'ul' );\r
+ ret.className = 'option-container';\r
+ return ret;\r
+ })();\r
+ var currentCombobox = null,\r
+ optionList,\r
+ elm,\r
+ value,\r
+ currentOption,\r
+ currentIndex;\r
+ \r
+ function updateCurrrentOption( _value, _updateCombobox ){\r
+ var _option;\r
+ for( var i=0, l=optionList.length; i<l; ++i ){\r
+ _option = optionList[ i ]\r
+ if( _value === _option.value ){\r
+ currentOption && currentOption.current( false );\r
+ _option.current( true );\r
+ currentOption = _option;\r
+ currentIndex = i;\r
+ _updateCombobox === true && currentCombobox.value( _value );\r
+ }\r
+ }\r
+ }\r
+ function bodyMouseupHandler(){\r
+ currentCombobox.blur();\r
+ OptionControl.hide( currentCombobox );\r
+ }\r
+ function updateWrapperPosition(){\r
+ var position = pettanr.util.getAbsolutePosition( elm );\r
+ \r
+ ELM_OPTION_WRAPPER.style.cssText = [\r
+ 'width:', elm.offsetWidth - 2, 'px;',\r
+ 'left:', position.x, 'px;',\r
+ 'top:', position.y + elm.offsetHeight, 'px;'\r
+ ].join(''); \r
+ }\r
+ return {\r
+ show: function( _combobox, _optionList ){\r
+ if( currentItem !== _combobox || currentCombobox === _combobox ) return;\r
+ currentCombobox && currentCombobox.blur();\r
+ \r
+ currentCombobox = _combobox;\r
+ optionList = _optionList;\r
+ elm = _combobox.elm;\r
+ \r
+ updateCurrrentOption( _combobox.value(), false );\r
+ \r
+ for( var i=0, l=optionList.length; i<l; ++i ){\r
+ ELM_OPTION_WRAPPER.appendChild( optionList[ i ].elm );\r
+ }\r
+ \r
+ document.body.appendChild( ELM_OPTION_WRAPPER );\r
+ oldBodyMouseupHandler = document.body.onmouseup;\r
+ document.body.onmouseup = bodyMouseupHandler;\r
+ \r
+ updateWrapperPosition();\r
+ },\r
+ hide: function( _combobox ){\r
+ if( currentCombobox !== _combobox ) return;\r
+\r
+ ELM_OPTION_WRAPPER.parentNode && ELM_OPTION_WRAPPER.parentNode.removeChild( ELM_OPTION_WRAPPER );\r
+ while( ELM_OPTION_WRAPPER.firstChild ){\r
+ ELM_OPTION_WRAPPER.removeChild( ELM_OPTION_WRAPPER.firstChild );\r
+ }\r
+ currentCombobox = null;\r
+ currentOption = null;\r
+ currentIndex = 0;\r
+ \r
+ document.body.onmouseup = oldBodyMouseupHandler;\r
+ },\r
+ change: function( down ){\r
+ var l = optionList.length,\r
+ way = down === true ? 1 : -1;\r
+ i = currentIndex + way\r
+ if( currentCombobox === false || l < 2 ) return;\r
+ i = i < 0 ?\r
+ l - 1 :\r
+ i < l ? i : 0;\r
+ updateCurrrentOption( optionList[ i ].value, false );\r
+ },\r
+ update: function( _combobox, _value ){\r
+ if( currentCombobox !== _combobox || currentItem !== _combobox ) return;\r
+ if( currentOption.value === _value ) return;\r
+ updateCurrrentOption( _value, true );\r
+ },\r
+ decide: function(){\r
+ currentCombobox.value( currentOption.value );\r
+ currentCombobox.blur();\r
+ OptionControl.hide( currentCombobox );\r
+ },\r
+ onWindowResize: function( _w, _h ){\r
+ setTimeout( updateWrapperPosition, 0 );\r
+ }\r
+ }\r
+ })();\r
+ \r
+ var OptionClass = function( combobox, displayValue, value ){\r
+ var elm = document.createElement( 'li' ),\r
+ a = document.createElement( 'a' ),\r
+ isCurrent = undefined;\r
+ elm.appendChild( a );\r
+ a.appendChild( document.createTextNode( displayValue ));\r
+ elm.className = CLASSNAME_COMBOBOX_OPTION;\r
+ a.href = '#';\r
+ \r
+ a.onmousedown = onClick; // onclick では 選択ボックス 隠すように body に設定した onmouseup が先に動いてしまう!\r
+ function onClick(){\r
+ OptionControl.update( combobox, value );\r
+ OptionControl.hide( combobox );\r
+ combobox.blur();\r
+ return false;\r
+ }\r
+ this.elm = elm;\r
+ this.displayValue = displayValue;\r
+ this.value = value = value || displayValue;\r
+ this.current = function( _isCurrent ){\r
+ if( Type.isBoolean( _isCurrent ) === true && isCurrent !== _isCurrent ){\r
+ elm.className = CLASSNAME_COMBOBOX_OPTION + ( _isCurrent === true ? ' current-option' : '' );\r
+ isCurrent = _isCurrent;\r
+ }\r
+ return !!isCurrent;\r
+ }\r
+ }\r
+ \r