var SmartSelector = Class.create(); SmartSelector.prototype = { initialize: function( selector_id, options ) { this.id = selector_id; this.select = $(this.id); if( !( this.select && this.select.options.length) ) return false; this.time_delay = 400; //time of delay when mouse pointed out this.hidden_class = 'hidden'; // class to hide drop down list this.css_class = 'smartselector'; // defines the css class to be applied to new drop down list this.use_list_styles = false; //defines whether to use css classes of replaced option to created li. this.use_pointers = false; // option to enanble/disable displaying of arrow pointers this.parent_box = 'div';//html tag containing Select input this.input_class_name = ''; this.show_empty_items = false; this.width = false; this.max_height = false; this.margin = 40; this.debug = false; this.usetext = false; this.apply_item_class = false; //defines whether to apply css classes of selected option to created li. this.default_text = false;//default hint text, e.g.: -- Select one option -- this.disable_reset = false; this.suggest = false; this.observed = false; this.title = false; this.onchange = false; Object.extend(this, options || {}); this.parent_box = this.select.up(this.parent_box); if( !this.parent_box ) { //alert( ('No block for'+this.id) ); return false; } this.width = (this.width) ? parseInt(this.width) : this.select.getWidth(); if( !this.width ) this.width = 110; this.elements = new Array(); this.elements_data = {}; this.list_visible = true; this.list = ''; this.t = {};//temporary storage for objects, reseted after initialization; this.t.dv = $( (this.id+'_selected') );//temporarely used in quick cv, in base module it's deprecated this.default_value = false; if( this.t.dv ) { this.default_value = this.t.dv.value; } this.t.templates = new Array(); this.t.templates[0] = new Template('
  • #{text}
  • '); this.t.templates[1] = new Template('
    #{arrow_pointers}#{text}
    ' ); this.t.optgroup = false; for( var i=0, n=this.select.options.length; i'+ (this.t.optgroup.label || this.t.optgroup.title || '---------------') +''; } } else { if( this.t.optgroup ) { this.t.optgroup = false; this.list += '
  • -------------
  • '; } } this.list += this.t.templates[0].evaluate(this.t.data); this.elements_data[('v'+i)] = this.t.option.value; } if( this.default_value && this.t.option.value == this.default_value )//temporarely used in quick cv, in base module it's deprecated { this.t.option.selected = true; } } if( !this.default_text && ( !this.select.options[0].value || this.select.options[0].value == '' || this.select.options[0].value === 0 ) ) { this.default_text = this.select.options[0].text; } this.index = this.select.selectedIndex; this.t.data = { input_name: this.select.name, input_id: this.select.id, value: this.select[this.index].value, text: this.select[this.index].text, elements: this.list, arrow_pointers: ( this.use_pointers ) ? '' : '', input_class_name: ( this.input_class_name != '' ) ? 'class="'+this.input_class_name+'"' : '' } if( this.index < 1 && this.default_text ) { this.index = -1; } this.parent_box.setStyle( this.suggest && ( !Prototype.Browser.IE || Prototype.Browser.IE8 ) ? { width: 'auto' } : { width: (this.width+this.margin+'px') } ); Element.addClassName( this.parent_box, this.css_class ); Element.update( this.parent_box, this.t.templates[1].evaluate(this.t.data) ); if( this.use_pointers ) { this.arrows = this.parent_box.getElementsByTagName('b'); if( this.arrows.length ) { Event.observe( this.arrows[0], 'click', this.previous.bind(this) ); Event.observe( this.arrows[1], 'click', this.next.bind(this) ); } } if( this.other ) { name = this.select.name.substr(0,this.select.name.length-1)+'name]'; new Insertion.After( this.parent_box, '' ); this.other = $( this.id+'_other' ); Event.observe( this.other, 'change', this.checkOther.bind(this) ); Event.observe( this.other, 'blur', this.checkOther.bind(this) ); } this.display = $( this.id+'_display' ); if( this.select.title ) this.display.title = this.select.title; this.select = $( this.id+'_hidden' ); this.list = $( this.id+'_list' ); this.list.setStyle( this.suggest ? { width: 'auto', minWidth: '110px' } : { width: (this.width+'px') } ); this.elements = this.list.getElementsByTagName('li'); for( var i=0, n=this.elements.length; i this.max_height ) { Element.setStyle( this.list, { width: (this.width+15+'px'), height: (this.max_height+'px') } ); Element.addClassName(this.list,'scroll'); } this.hideList(); Event.observe( this.display, 'mouseover', this.toggleList.bind(this) ); Event.observe( this.display, 'mouseout', this.hideListSlowly.bind(this) ); Event.observe( this.list, 'mouseout', this.hideListSlowly.bind(this) ); Event.observe( this.list, 'mouseover', this.showList.bind(this) ); this.display.up('div').observe( 'click', this.next.bind(this) ); this.t = {}; }, _reset: function() { if( this.other ) { this.other.addClassName('hidden').addClassName('disabled'); this.parent_box.removeClassName('hidden'); } if( this.disable_reset ) return true; if( !this.default_text ) return false; this.display.update( this.default_text ); this.select.value = ''; this.select.title = ( this.title !== false ? this.title : '' ); this.index = -1; if( this.apply_item_class ) { this.select.className = this.input_class_name || ''; } return true; }, next: function() { ++this.index; if( this.index > (this.elements.length-1) ) this.index = 0; this.setValue(this.index); }, previous: function() { --this.index; if( this.index < 0 ) this.index = this.elements.length-1; this.setValue(this.index); }, hideListSlowly: function() { if( !this.list_visible ) return false; if( this.timeout ) { clearTimeout(this.timeout); } this.timeout = setTimeout( this.hideList.bind(this), this.time_delay ); }, showList: function() { if( this.timeout ) clearTimeout(this.timeout); Element.removeClassName( this.list, this.hidden_class ); this.list_visible = true; }, hideList: function() { Element.addClassName( this.list, this.hidden_class ); this.list_visible = false; if( this.timeout ) clearTimeout(this.timeout); }, toggleList: function() { if( this.list_visible ) this.hideList(); else this.showList(); }, checkOther: function() { if( !this.other.value ) { this.other.addClassName('hidden').addClassName('disabled'); this.parent_box.removeClassName('hidden'); this.setValue(0); return true; } this.select.value = -1; this.select.title = this.other.value; }, setValue: function(index) { this.index = index; if( this.title === false ) { this.title = this.select.title; } this.tnode = this.elements[this.index]; this.t.index = this.tnode.id.split( this.id + '__' )[1]; this.t.text = this.tnode.title || this.tnode.innerHTML.stripTags(); if( this.usetext ){ this.t.text = this.tnode.innerHTML.stripTags(); } if( this.other && this.elements_data[this.t.index] < 0 ) { this.other.removeClassName('hidden').removeClassName('disabled').focus(); this.parent_box.addClassName('hidden'); if( this.apply_item_class ) { this.t.class_name = ( this.input_class_name ) ? this.input_class_name : ''; this.t.class_name_2 = ( this.tnode.className ) ? ' APPLICABLE_CSS_CLASS_'+this.tnode.className.strip().replace(' ', '__') : ''; this.select.className = this.t.class_name+this.t.class_name_2; } return false; } this.select.value = this.elements_data[this.t.index]; this.select.title = this.t.text; if( this.apply_item_class ) { this.t.class_name = ( this.input_class_name ) ? this.input_class_name : ''; this.t.class_name_2 = ( this.tnode.className ) ? ' APPLICABLE_CSS_CLASS_'+this.tnode.className.strip().replace(' ', '__') : ''; this.select.className = this.t.class_name+this.t.class_name_2; } if( this.suggest ) { id = this.id.replace( '_select', '' ); if( ( _display = $( id + '_suggest' ) ) && ( _value = $( id ) ) ) { _value.value = this.select.title; if( _display.hasClassName('parent') ) { next_display = _display.next('.sg'); next_float = this.parent_box.next('div.floatbox'); next_display.hide(); next_float.show(); } if( this.select.value == 'other' || this.tnode.title == 'other' ) { _value.value = ''; this.parent_box.hide(); _display.show(); _value.focus(); if( _display.hasClassName('parent') ) { next_float.hide( this.next_parent ); next_display.show( this.suggest_span ); next_display.down('input').value = ''; } return true; } } } Element.update(this.display, this.t.text ); this.hideList(); this.t = {}; if( this.suggest ) { this._outFunc( '_onBlur("'+this.id+'_display")' ); if( this.onchange ) { this._outFunc( this.onchange+'("'+this.select.value+'")' ); } } }, _outFunc: function( func_name ) { timeout = setTimeout( func_name, 0 ); }, _rebuild: function( element, request ) { text = ''; list = $( element + '_list' ); display = $( element + '_display' ); if( request === false ) { display.update('Загрузка...'); list.update(); return false; } result = eval('('+request.responseText+')'); if( !result ) { display.update('нет данных'); list.update('
  • нет данных
  • '); return true; } for( i=0, n=result.list.length; i'+result.list[i]['caption']+''; } var req = new Ajax.Request( 'ajax/save/locations', { method: 'post', parameters: { id: result.list[0]['caption'] }, onComplete: function() { refreshWithout( 'ct' ); } } ); if( result.other ) { text += '
  • другой город
  • '; } display.update( result.list[0]['caption'] ); list.update( text ); } }