Click here to Skip to main content
15,892,072 members
Articles / Web Development / HTML

AWUI - a simple web user interface library with AJAX support

Rate me:
Please Sign up or sign in to vote.
4.33/5 (5 votes)
26 Jul 2007CPOL4 min read 47.8K   382   35  
An article on creating a custom JavaScript controls set and cross-browser support library
if (typeof(AWUI) == "undefined") alert ("AWUI is not available");
////////////////////////////////////////////////////////////////////////////////////

function astRegisterMouseHandlers ()	{
	if (aSelect.prototype.REGISTERED) return;
	
	if (document.attachEvent ) {
		document.attachEvent("onmouseup", function(ev) { astOnMouseUp (ev) } );
	} else if (document.addEventListener) {
		document.addEventListener("mouseup",function(ev) { astOnMouseUp (ev) }, false);
	} else {
		aSelect.prototype.MOUSE_UP_OLD = document.onmouseup;
		document.onmouseup = astOnMouseUp;
	}
	aSelect.prototype.REGISTERED = true;
}

function astOnMouseUp (e)	{
	var sender = AWUI.srcEl(e), 
		expSel = aSelect.prototype.LAST_EXPANDED_SELECT;
	
	if (expSel) {
		expSel.pressed = false;
		expSel._redrawBtn();
		
		var fromList = false; 
		var obj = sender;
		while (obj) {
			if (obj == expSel.list) {
				fromList = true;
				break;
			}
			obj = obj.parentNode;
		}
		if (fromList) 
			expSel._showList(false);
	}
		
	if (aSelect.prototype.MOUSE_UP_OLD)	
		aSelect.prototype.MOUSE_UP_OLD (e);

}

function _astOnFocus (obj_) {
	if (!obj_) return;
	var sel = AWUI.getWuiObj(obj_.id);
	sel._onFocus();
}
function _astOnBlur (obj_) {
	if (!obj_) return;
	var sel = AWUI.getWuiObj(obj_.id);
	sel._onBlur();
}

function astOnMouseDown (e)	{
	var obj = AWUI.srcEl(e);
	var sender = obj;
	while (obj && String(obj.tagName).toUpperCase() != "TABLE")
		obj = obj.parentNode;
	if (!obj) 
		return aSelect.superclass.processError (this, "Cannot find selector object", AWUI.ERROR_OBJECT);
	
	var sel = AWUI.getWuiObj(obj.id);
	if (!sel || sel.disabled) 
		return;

	sel.pressed = true;
	sel._showList ( (sel.list.style.display == "none") );
	sel._redrawBtn();
	sel.label.focus();
	
	return AWUI.stopPropagation(e);	
}

function astOnItemMouseUp(e_, obj_) {
	if (!obj_) return;	
	var selId = obj_.getAttribute ("pid");
	var index = parseInt(obj_.getAttribute ("index"));
	var sel = AWUI.getWuiObj(selId); 	
	if (sel)
		sel._onItemClick (index);
}

function astOnItemMouseAction(e_, obj_, bIsOut_) {
	if (!obj_) return;	
	var selId = obj_.getAttribute ("pid");
	var sel = AWUI.getWuiObj(selId); 	
	if (sel)
		sel._onItemMouseAction (obj_, (bIsOut_ && true) );
}

function astOnKeyDown(e) {
	var sender = AWUI.srcEl(e), keyCode = AWUI.getKeyCode(e);
	if (!sender) return; 
	var sel = AWUI.getWuiObj(sender.id); 	
	if (!sel) return; 
	
	switch (keyCode) {
		case AWUI.KEY_ALT: 
			sel.altPressed = true; 
			break;
		case AWUI.KEY_DOWN: 
			if ( sel.altPressed) {
				sel._showList ( true );
				sel.altPressed = false;
			} else {
				sel._showNextValue ();
			}
			break;
		case AWUI.KEY_UP: 
			sel._showPrevValue ();
			break;
		case AWUI.KEY_ESC: 
			sel.setValue (sel.value);
			sel._showList ( false );
			break;
			
		case AWUI.KEY_TAB: 
		case AWUI.KEY_ENTER:
			if ((keyCode == AWUI.KEY_TAB) && (sel.shownIndex == sel.selectedIndex) )
				return;
			sel._onItemClick (sel.shownIndex);
			
			break;
	}
}

function astOnKeyUp(e) {
	var sender = AWUI.srcEl(e), keyCode = AWUI.getKeyCode(e);
	if (!sender) return; 
	var sel = AWUI.getWuiObj(sender.id); 	
	if (!sel) return; 
	
	switch (keyCode) {
		case AWUI.KEY_ALT: sel.altPressed = false; break;
	}
}

////////////////////////////////////////////////////////////////////////////////////
//

function aSelect (name_, options_, value_) {
	
	aSelect.superclass.constructor.call (this);
	
	this.name = (arguments.length ? name_ : this.id);
	// design
	this.height = this.HEIGHT;
	this.width = this.WIDTH;
	this.btnWidth = Math.max (this.BTN_WIDTH, 16);
	this.fontSize = this.FONT_SIZE;
	this.fontFamily = this.FONT_FAMILY;
		
	// objects
	this.wnd = null;
	this.body = null;
	this.btn = null;
	this.btnCell = null;
	this.label = null;
	this.labelCell = null;
	this.labelBody = null;
	this.list = null;
	this.input = null;
	
	// handlers
	this.onchange = null;
	this.onselchange = null;
	this.onblur = null;
	this.onfocus = null;
	
	// state
	this.disabled = false;
	this.focused = false;
	this.pressed = false;
	this.altPressed = false;
	this.selectedIndex = -1;
	this.shownIndex = -1;
	
	// properties
	this.valDelim = this.RE_VALUE_DELIM;
	this.optDelim = this.RE_OPT_DELIM;
	
	this.texts = [];
	this.values = [];
	
	if ( arguments.length > 1 )	
		this.loadOptions (options_);
	
	this.value = undefined;
	if (arguments.length > 2)
		this.value = this.getOptValue(value_);
	else if (this.values.length)
		this.value = this.values[0];
	this._loadSelIndex();
		
	this.is3D = true;
	
	// colored parts links
	this.btnCellsA = [];
	this.btnCellsW = [];
	this.btnCellsT1 = [];
	this.btnCellsT2 = [];
	this.btnCellsL1 = [];
	this.btnCellsL2 = [];
	this.btnCellsR1 = [];
	this.btnCellsR2 = [];
	this.btnCellsB1 = [];
	this.btnCellsB2 = [];
	
	// colors
	this.colorW = this.COLOR_WND;
	this.colorD = this.COLOR_DARK_EDGE;
	this.colorM = this.COLOR_MEDIUM_EDGE;
	this.colorL = this.COLOR_LIGHT_EDGE;
	this.colorB = this.COLOR_LISTBG;
	this.colorF = this.COLOR_LISTFG;
	this.colorA = this.COLOR_ARROW;
	
	this.colorBs = this.COLOR_LISTBG_SEL;
	this.colorFs = this.COLOR_LISTFG_SEL;
}

AWUI.extend (aSelect, aObject);

aSelect.prototype = {
	AWUI_KEY: "aSelect",
	REGISTERED : false,
	MOUSE_UP_OLD: null,
	LAST_EXPANDED_SELECT: null,
	
	RE_VALUE_DELIM : "\t",
	RE_OPT_DELIM : "\n",

	ITEM_HEIGHT : 20,
	HEIGHT: 20,
	WIDTH: 200,
	BTN_WIDTH : 16,
	FONT_SIZE : "8pt",
	FONT_FAMILY : "Tahoma, Arial",
	
	LIST_Z_INDEX: 100,
	
	COLOR_WND : "ButtonFace", 	
	COLOR_DARK_EDGE : "ThreedDarkShadow",
	COLOR_MEDIUM_EDGE : "ButtonShadow",	
	COLOR_LIGHT_EDGE : "ButtonHighlight",
	COLOR_ARROW : "ButtonText",
	COLOR_LISTBG : "Window",
	COLOR_LISTFG : "WindowText",
	COLOR_LISTBG_SEL : "Highlight",
	COLOR_LISTFG_SEL : "HighlightText",
	
	init : function	() {
		
		var tbl, r, c, btnCell;

		tbl = AWUI.crel("TABLE");
		tbl.id = this.id + AWUI.ID_DELIM + "body";
		tbl.cellPadding = tbl.cellSpacing = tbl.border = 0; 
		tbl.style.width = '100%';
		tbl.style.height = this.height - 2;
		tbl.style.tableLayout = "fixed";
		AWUI.setUnselectable(tbl);
		this.body = tbl;
		
		r = tbl.insertRow (-1);
		AWUI.setUnselectable(r);
		
		c = r.insertCell (-1);
		c.vAlign = 'top';
		c.style.padding = (AWUI.IS_MOZILLA ? "1" : (AWUI.IS_OPERA ? "0" : "0 1 0 1")); 
		c.style.backgroundColor = this.colorB;
		c.id = this.id + AWUI.ID_DELIM + "labelcell";
		AWUI.setUnselectable(c);
		this.labelCell = c;
		
		var a = AWUI.crel("A");
		a.id = this.id + AWUI.ID_DELIM + "label";
		a.style.textDecoration = "none";
		a.style.cursor = "default";
		a.href = 'javascript:void(0)';
		a.style.color = this.colorF;
		AWUI.setUnselectable(a);
		this.label = a;
		
		var div = AWUI.crel("DIV");
		div.id = this.id + AWUI.ID_DELIM + "labelbody";
		if (AWUI.IS_IE) 
			div.style.width = "100%";
		var h = (AWUI.IS_MOZILLA ? this.height - 8 : this.height - 4);
		div.style.height = h +"px";
		div.style.padding = "0 3 0 3";
		div.style.overflow = "hidden";		
		div.style.verticalAlign = "middle";
		div.style.lineHeight = (h - (AWUI.IS_IE ? 2 : 0)) +"px";
		div.style.color = this.colorF;
		
		div.innerHTML = AWUI.quoteXml (this.getOptText());
		AWUI.setUnselectable(div);
		this.labelBody = div;
		
		a.appendChild(div);
		c.appendChild(a);
		btnCell = r.insertCell (-1);
		btnCell.id = this.id + AWUI.ID_DELIM + "btncell";
		btnCell.style.width = this.btnWidth;
		btnCell.style.height = this.height - 4;
		btnCell.vAlign = 'middle';
		AWUI.setUnselectable(btnCell);
		this.btnCell = btnCell;
		
		tbl = AWUI.crel("TABLE");
		tbl.id = this.id + AWUI.ID_DELIM + "btn";
		tbl.cellPadding = tbl.cellSpacing = tbl.border = 0;
		tbl.style.width = this.btnWidth;
		AWUI.setUnselectable(tbl);

		this.btn = tbl;
		btnCell.appendChild(this.btn);
		this._createBtnBody();
		
		var div = AWUI.crel("DIV");
		div.id = this.id + AWUI.ID_DELIM + "wnd";
		div.style.width = this.width - 2;
		div.style.height = this.height -2;
		AWUI.setUnselectable(div);

		this.wnd = div;
		this.wnd.appendChild (this.body);
		
		// list creation
		var div = AWUI.crel ("DIV");
		div.id = this.id + AWUI.ID_DELIM + "list";
		div.style.zIndex = this.LIST_Z_INDEX;
		div.style.position = "absolute";
		div.style.top = div.style.left = 0;
		div.style.width = this.width - 2;
		div.style.display = "none";
		AWUI.setUnselectable(div);
		this.list = div;

		var tbl = AWUI.crel("TABLE");
		tbl.id = this.id + AWUI.ID_DELIM + "listtable";
		tbl.cellPadding = tbl.cellSpacing =	tbl.border = 0;
		tbl.style.width = "100%";
		AWUI.setUnselectable(tbl);

		this.listTable = tbl;
		var optCount = (this.texts.length>0 ? this.texts.length : 1)
		for (var ndx=0; ndx < optCount; ndx++)
			this._appendListItem();

		this.list.appendChild (this.listTable);
		document.body.appendChild (this.list);
	},

	_createBtnBody: function () {
		var firstBreakHeight = Math.round((this.height - 4) / 2) - 3;
		var arrowMargin = Math.round((this.btnWidth - 9) / 2) - 1;
		var addedRows = 0;
		var tbl = this.btn;
		var r,c;
		//	13 columns
		r = tbl.insertRow (-1); addedRows++; AWUI.setUnselectable(r);
			c = r.insertCell (-1); c.height = 1; c.width = 1; AWUI.push (this.btnCellsT1, c); AWUI.setUnselectable(c);
			c = r.insertCell (-1); c.height = 1; c.width = 1; AWUI.push (this.btnCellsT1, c); AWUI.setUnselectable(c);
			c = r.insertCell (-1); c.height = 1; c.width = arrowMargin; AWUI.push (this.btnCellsT1, c); AWUI.setUnselectable(c);
			
			for (var ndx=0; ndx<7; ndx++) {
				c = r.insertCell (-1); c.height = 1; c.width = 1; AWUI.push (this.btnCellsT1, c); AWUI.setUnselectable(c);
			}
			
			c = r.insertCell (-1); c.height = 1; c.width = this.btnWidth-arrowMargin-11; AWUI.push (this.btnCellsT1, c); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height = 1; �.width = 1; AWUI.push (this.btnCellsT1, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height = 1; �.width = 1; AWUI.push (this.btnCellsR1, �); AWUI.setUnselectable(c);
			
		r = tbl.insertRow (-1);  addedRows++; AWUI.setUnselectable(r);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsL1, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=this.btnWidth-3; �.colSpan = 10; AWUI.push (this.btnCellsT2, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsR2, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height = 1; �.width = 1; AWUI.push (this.btnCellsR1, �); AWUI.setUnselectable(c);
		
		for (var ndx=0; ndx<firstBreakHeight; ndx++)	{
			r = tbl.insertRow (-1);  addedRows++; AWUI.setUnselectable(r);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsL1, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsL2, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=this.btnWidth-4; �.colSpan = 9; AWUI.push (this.btnCellsW, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsR2, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height = 1; �.width = 1; AWUI.push (this.btnCellsR1, �); AWUI.setUnselectable(c);
		}
		
		// arrow body
		for (var ndx=0; ndx<4; ndx++)	{
			r = tbl.insertRow (-1);  addedRows++; AWUI.setUnselectable(r);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsL1, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsL2, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width = (arrowMargin+ndx); �.colSpan = ndx+1; AWUI.push (this.btnCellsW, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width = 7-ndx*2; �.colSpan = 7-ndx*2; AWUI.push (this.btnCellsA, �); AWUI.setUnselectable(c);
			
			var nWsLength = this.btnWidth - arrowMargin -4-7 + ndx;
			� = r.insertCell (-1); �.height=1; �.width = nWsLength; �.colSpan = ndx+1 ; AWUI.push (this.btnCellsW, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsR2, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width = 1; AWUI.push (this.btnCellsR1, �); AWUI.setUnselectable(c);
		}
	
		for (var ndx=0; ndx < (this.height - addedRows - 6); ndx++)	{
			r = tbl.insertRow (-1); AWUI.setUnselectable(r);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsL1, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsL2, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=this.btnWidth-4; �.colSpan = 9; AWUI.push (this.btnCellsW, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsR2, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height = 1; �.width = 1; AWUI.push (this.btnCellsR1, �); AWUI.setUnselectable(c);
		}
		
		r = tbl.insertRow (-1); AWUI.setUnselectable(r);
			� = r.insertCell (-1); �.height=1; �.width=1; AWUI.push (this.btnCellsL1, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height=1; �.width=this.btnWidth-2; �.colSpan = 11;  AWUI.push (this.btnCellsB2, �); AWUI.setUnselectable(c);
			� = r.insertCell (-1); �.height = 1; �.width = 1; AWUI.push (this.btnCellsR1, �); AWUI.setUnselectable(c);
			
		r = tbl.insertRow (-1); AWUI.setUnselectable(r);
			� = r.insertCell (-1); �.height=1; �.width=this.btnWidth; �.colSpan = 13; AWUI.push (this.btnCellsB1, �); AWUI.setUnselectable(c);

	},
	
	_appendListItem : function () {
		var list = this.listTable;
		
		var r = list.insertRow(-1);
		AWUI.setUnselectable(r);
		r.style.height = this.ITEM_HEIGHT;
		
		var c = r.insertCell (-1);
		c.setAttribute ("pid", this.id);
		c.style.padding = "1 3 1 3";
		AWUI.setUnselectable(c);

		c.onmouseup = function(e)	{ astOnItemMouseUp(e, this); return false; };
		c.onmouseover = function(e) { astOnItemMouseAction(e, this, false); return false; };
		c.onmouseout = function(e)	{ astOnItemMouseAction(e, this, true); return false; };
		
	},
	
	
	_refreshObjects: function () {
		this.wnd = AWUI.el(this.id + AWUI.ID_DELIM + "wnd");
		this.label = AWUI.el(this.id + AWUI.ID_DELIM + "label");
		this.labelCell = AWUI.el(this.id + AWUI.ID_DELIM + "labelcell");
		this.labelBody = AWUI.el(this.id + AWUI.ID_DELIM + "labelbody");
		this.body = AWUI.el(this.id + AWUI.ID_DELIM + "body");
		this.btn = AWUI.el(this.id + AWUI.ID_DELIM + "btn");
		this.list = AWUI.el(this.id + AWUI.ID_DELIM + "list");
		this.listTable = AWUI.el(this.id + AWUI.ID_DELIM + "listtable");
	},

	_updateLabel: function ()	{
		var bSelectLabel = this.focused;
		if ( !AWUI.IS_IE) {
			this.labelBody.style.border = (bSelectLabel ? "1px dotted #000000" : "1px solid " + this.colorB);
		}
	},
	
	_redrawBtn: function ()	{
		if (this.is3D) {
		
			this._colorizeCells (this.btnCellsA, this.colorA);			
			this._colorizeCells (this.btnCellsW, this.colorW);
			this._colorizeCells (this.btnCellsT1, (this.pressed ? this.colorM : this.colorW) );
			this._colorizeCells (this.btnCellsL1, (this.pressed ? this.colorM : this.colorW) );
			this._colorizeCells (this.btnCellsR1, (this.pressed ? this.colorM : this.colorD) );
			this._colorizeCells (this.btnCellsB1, (this.pressed ? this.colorM : this.colorD) );
			
			this._colorizeCells (this.btnCellsT2, (this.pressed ? this.colorW : this.colorL));
			this._colorizeCells (this.btnCellsL2, (this.pressed ? this.colorW : this.colorL));
			this._colorizeCells (this.btnCellsR2, (this.pressed ? this.colorW : this.colorM));
			this._colorizeCells (this.btnCellsB2, (this.pressed ? this.colorW : this.colorM));
		
		} else {
			this._colorizeCells (this.btnCellsA, this.colorA);			
			var color = (this.pressed ? this.colorM : this.colorW);
			
			this._colorizeCells (this.btnCellsW, color);	this._colorizeCells (this.btnCellsT1, color);	this._colorizeCells (this.btnCellsT2, color);
			this._colorizeCells (this.btnCellsL1, color);	this._colorizeCells (this.btnCellsL2, color);	this._colorizeCells (this.btnCellsR1, color);
			this._colorizeCells (this.btnCellsR2, color);	this._colorizeCells (this.btnCellsB1, color);	this._colorizeCells (this.btnCellsB2, color);
		}
	},
	
	_applyFontSettings: function () {
		if (!this.wnd || !this.body) return;
		this.labelBody.style.fontSize = this.fontSize;
		this.labelBody.style.fontFamily = this.fontFamily;
		
		this.list.style.fontSize = this.fontSize;
		this.list.style.fontFamily = this.fontFamily;
	},
	
	_applyColorizing: function () {
		if (!this.wnd || !this.body) return;
		
		if (this.is3D) {
			//this.wnd.style.padding = 0;
			this.wnd.style.borderLeft = "1px solid " + this.colorM;
			this.wnd.style.borderTop = "1px solid " + this.colorM;
			this.wnd.style.borderRight = "1px solid " + this.colorL;
			this.wnd.style.borderBottom = "1px solid " + this.colorL;
			
			this.body.style.borderLeft = "1px solid " + this.colorD;
			this.body.style.borderTop = "1px solid " + this.colorD;
			this.body.style.borderRight = "1px solid " + this.colorW;
			this.body.style.borderBottom = "1px solid " + this.colorW;
				
			this._colorizeCells (this.btnCellsA, this.colorA);			this._colorizeCells (this.btnCellsW, this.colorW);
			this._colorizeCells (this.btnCellsT1, this.colorW);			this._colorizeCells (this.btnCellsT2, this.colorL);
			this._colorizeCells (this.btnCellsL1, this.colorW);			this._colorizeCells (this.btnCellsL2, this.colorL);
			this._colorizeCells (this.btnCellsR1, this.colorD);			this._colorizeCells (this.btnCellsR2, this.colorM);
			this._colorizeCells (this.btnCellsB1, this.colorD);			this._colorizeCells (this.btnCellsB2, this.colorM);
		
		} else {
			//this.wnd.style.padding = 1;
			this.wnd.style.borderWidth = 0;
			this.body.style.border = "1px solid " + this.colorW;
			
			this._colorizeCells (this.btnCellsA, this.colorA);			this._colorizeCells (this.btnCellsW, this.colorW);
			this._colorizeCells (this.btnCellsT1, this.colorW);			this._colorizeCells (this.btnCellsT2, this.colorW);
			this._colorizeCells (this.btnCellsL1, this.colorW);			this._colorizeCells (this.btnCellsL2, this.colorW);
			this._colorizeCells (this.btnCellsR1, this.colorW);			this._colorizeCells (this.btnCellsR2, this.colorW);
			this._colorizeCells (this.btnCellsB1, this.colorW);			this._colorizeCells (this.btnCellsB2, this.colorW);
		}
		this.list.style.backgroundColor = this.colorB;
		this.list.style.color = this.colorF;
		this.list.style.border = "1px solid " + this.colorD;

		this.labelCell.style.backgroundColor = this.colorB;
		this.label.style.color = this.colorF;
		this.labelBody.style.color = this.colorF;
		// bug in Opera 9.0 - it adds border to <A> tags on focus
		if (AWUI.IS_OPERA) this.btnCell.style.backgroundColor = this.colorW;
	},
	
	
	// 3D colors: window, dark edge, med. edge, light edge, arrow, list bg, list font, list bg sel, list font sel
	// flat: accent, accent dark, listbg, listfg, arrow, list bg sel, list font sel
	setColors: function (	is3d_, colorW_, colorD_, colorM_, colorL_, 
							colorA_, colorB_, colorF_, colorBs_, colorFs_)	{
		this.is3D = (is3d_ && true);
		if (this.is3D)	{
			this.colorW = (colorW_ ? colorW_ : this.COLOR_WND);
			this.colorD = (colorD_ ? colorD_ : this.COLOR_DARK_EDGE);
			this.colorM = (colorM_ ? colorM_ : this.COLOR_MEDIUM_EDGE);
			this.colorL = (colorL_ ? colorL_ : this.COLOR_LIGHT_EDGE);
			this.colorA = (colorA_ ? colorA_ : this.COLOR_ARROW);
			this.colorB = (colorB_ ? colorB_ : this.COLOR_LISTBG);
			this.colorF = (colorF_ ? colorF_ : this.COLOR_LISTFG);
			this.colorBs = (colorBs_ ? colorBs_ : this.COLOR_LISTBG_SEL);
			this.colorFs = (colorFs_ ? colorFs_ : this.COLOR_LISTFG_SEL);
		
		} else {
			this.colorD = this.colorL = this.colorW = (colorW_ ? colorW_ : this.COLOR_MEDIUM_EDGE);
			this.colorM = (colorD_ ? colorD_ : this.COLOR_WND);
			this.colorB = (colorM_ ? colorM_ : this.COLOR_LISTBG);

			this.colorF = (colorL_ ? colorL_ : this.COLOR_LISTFG);
			this.colorA = (colorA_ ? colorA_ : this.COLOR_ARROW);

			this.colorBs = (colorB_ ? colorB_ : this.COLOR_LISTBG_SEL);
			this.colorFs = (colorF_ ? colorF_ : this.COLOR_LISTFG_SEL);
		}
		
		this._applyColorizing();
	},
		
	draw : function() {
		
		if ( AWUI.el(this.id + AWUI.ID_DELIM + "base"))
			return processError_DuplicateObject (this);
		AWUI.wr ("<div id='"+this.id + AWUI.ID_DELIM + "base' style='width:" + this.width + "px; -moz-user-select:none;' UNSELECTABLE='on'></div>");
		var base = AWUI.el(this.id + AWUI.ID_DELIM + "base");
		if (!base)
			return processError_CreateBase (this);
		this.base = base;
		this._createControl();
	},
	
	create : function (parent_, appendAfter_) {
		if (typeof (parent_) == "string")
			parent_ = AWUI.el (parent_);
		if ( !parent_)
			return aSelect.superclass.processError (this, "Invalid parent node", AWUI.ERROR_OBJECT);
		appendAfter_ = (appendAfter_ && true);
		
		var base = AWUI.crel("DIV");
		base.id = this.id + AWUI.ID_DELIM + "base";
		base.style.width = this.width + "px";
		AWUI.setUnselectable(base);
		var inserted = false;
		
		if (appendAfter_ && parent_.parentNode) {
			var gp = parent_.parentNode, nextNode = null;
			for (var ndx=0; ndx < gp.childNodes.length; ndx++) {
				if ( (gp.childNodes[ndx] == parent_) && (ndx < gp.childNodes.length-1) ) {
					nextNode = gp.childNodes[ndx + 1];
					break;
				}
			}
			if (nextNode) 
				gp.insertBefore (base, nextNode);
			else
				gp.appendChild(base);
			inserted = true;
		}

		if (!inserted)
			parent_.appendChild(base);
		this.base = base;
		this._createControl();
	},
	
	_createControl: function () {
		astRegisterMouseHandlers();
		this.init();
		
		var input = AWUI.crel("INPUT");
		input.name = this.name;
		input.type = "hidden";
		input.value = this.value;
		this.input = input;
		this.base.appendChild (this.wnd);
		this.base.appendChild (this.input);
		
		this._refreshObjects ();
		this._initHandlers();
		this._applyColorizing ();
		this._applyFontSettings ();
	},
	
	_initHandlers: function()	{
		this.label.onfocus = function() { _astOnFocus (this); return false; };
		this.label.onblur = function()  { _astOnBlur (this); return false;   };

		this.label.onmousedown = astOnMouseDown;
		this.label.ondragstart = AWUI.stopPropagation;
		this.label.onselectstart = AWUI.stopPropagation;
		this.label.onkeydown = astOnKeyDown;
		this.label.onkeyup = astOnKeyUp;
		
		this.btn.onmousedown = astOnMouseDown;
		this.btn.ondragstart = AWUI.stopPropagation;
		this.btn.onselectstart = AWUI.stopPropagation;
		
	},
	
	_colorizeCells: function(ar_, color_)	{
		if (!ar_ || !ar_.length) return;
		for (var ndx=0; ndx<ar_.length; ndx++){
			ar_[ndx].style.backgroundColor = color_;
		}
	},
	
	loadOptions: function (options_)	{
		this.texts = [];
		this.values  = [];
			
		if (typeof(options_) == "object") {
			for (var elem in options_)	{
				if (typeof(options_[elem]) == "object")	
					this.addOption (options_[elem][0], options_[elem][1]);
				else
					this.addOption (options_[elem], elem);
			}
		
		} else if (typeof(options_) == "string")	{
			var ar, text, val;
			ar = options_.split( new RegExp(this.optDelim, "g") );
			
			for (var ndx=0; ndx<ar.length; ndx++)	{
				text = val = String(ar[ndx]).split(new RegExp(this.valDelim, "g"));
				if (val.length > 1) {
					text = val[0];
					val = val[1];
				}
				this.addOption (text, val);
			}
		} 
	},
	
	getOptValue: function(value_) {
		if (value_ == undefined) value_ = this.value;
		for (var ndx=0; ndx<this.values.length; ndx++) 
			if (this.values[ndx] == value_)	
				return this.values[ndx];
		return undefined;
	},
	
	getOptText: function(value_) {
		if (value_ == undefined) value_ = this.value;
		for (var ndx=0; ndx<this.values.length; ndx++) 
			if (this.values[ndx] == value_)	
				return this.texts[ndx];
		return "";
	}, 
	setValue :function (value_) {
		var val = this.getOptValue (value_);
		var selectValue = true;
		if( AWUI.isFunction(this.onchange) )
			selectValue = (this.onchange (val, this) != false);
		if (selectValue) 
			this.value = val;
		
		if (this.input)	
			this.input.value = (this.value != undefined ? this.value : "");
		this._setText (this.value);
		this._loadSelIndex();
		
		return selectValue;
	},
	addOption: function(text_, val_) {
		this.texts[this.texts.length] = text_;
		this.values[this.values.length] = ((val_ != undefined) ? val_ : text_);
	},
	
	_setText :function (value_) {
		if (this.labelBody) {
			this.labelBody.innerHTML = "";
			this.labelBody.appendChild ( AWUI.crtext( this.getOptText (value_) ) );
		}
	},
	
	_loadSelIndex : function() {
		for (var ndx=0; ndx<this.values.length; ndx++) 
			if (this.values[ndx] == this.value)	
				return (this.shownIndex = this.selectedIndex = ndx);
				
		return (this.shownIndex = this.selectedIndex = -1);
	},
	_updateSelection : function (  ) {
		if (!this.listTable)
			return;
		if (this.listTable.rows.length != this.texts.length)
			return aSelect.superclass.processError (this, "Incorrect items list size", AWUI.ERROR_RUNTIME);
		for (var ndx=0; ndx < this.texts.length; ndx++)	{
			var c = this.listTable.rows[ndx].cells[0];
			c.style.backgroundColor = (this.shownIndex == ndx ? this.colorBs : this.colorB);
			c.style.color = (this.shownIndex == ndx ? this.colorFs : this.colorF);
		}
	},
	
	_showNextValue : function ()	{
		var ndxOld = this.shownIndex;
		for (var ndx=0; ndx<this.values.length; ndx++) {
			if (this.shownIndex == ndx && ndx<this.values.length-1) {
				this.shownIndex = ndx + 1;
				break;
			}
		}
		this._setText ( this.values[this.shownIndex] );
		this._updateSelection ( );
		if( AWUI.isFunction(this.onselchange) )
			this.onselchange (this.values[this.shownIndex], this.values[ndxOld], this);
	},
	
	_showPrevValue : function () {
		var ndxOld = this.shownIndex;
		for (var ndx=0; ndx<this.values.length; ndx++) {
			if (this.shownIndex == ndx && ndx>0) {
				this.shownIndex = ndx - 1;
				break;
			}
		}
		this._setText ( this.values[this.shownIndex] );
		this._updateSelection ( );
		
		if( AWUI.isFunction(this.onselchange) )
			this.onselchange (this.values[this.shownIndex], this.values[ndxOld], this);
	},
	
	_showList: function (show_)	{
		if (arguments.length == 0) show_ = true;
		
		if (show_)	{
			this._updateLabel ();
					
			if (aSelect.prototype.LAST_EXPANDED_SELECT)
				aSelect.prototype.LAST_EXPANDED_SELECT._showList (false);
			
			var pos = AWUI.absPos (this.base);
			this.list.style.top = pos.top + this.height - (this.is3D ? 0 : 3);
			this.list.style.left = pos.left;
			while (this.listTable.rows.length < this.texts.length)
				this._appendListItem ();
			
			for (var ndx=0; ndx < this.texts.length; ndx++)	{
				var c = this.listTable.rows[ndx].cells[0];
				c.innerHTML = this.texts[ndx];
				c.setAttribute ("index", ndx);
				c.style.backgroundColor = (this.shownIndex == ndx ? this.colorBs : this.colorB);
				c.style.color = (this.shownIndex == ndx ? this.colorFs : this.colorF);
			}
		
		} else {
			this._updateLabel ();
		} 
		
		this.list.style.display = (show_ ? "block" : "none");
		aSelect.prototype.LAST_EXPANDED_SELECT = (show_ ? this : null);
	},
	
	////////////////////////////////////////////////////////////////////////////////////////
	//
	// 					HANDLERS

	_onFocus : function()	{
		this.focused = true;
		this._updateLabel();
		if( AWUI.isFunction(this.onfocus) )
			this.onfocus (this);
	},
	_onBlur : function()	{
		this.focused = this.pressed = false;
				
		this._showList (false);
		this._updateLabel ();
		this._redrawBtn();
		if( AWUI.isFunction(this.onblur) )
			this.onblur (this);
	},
	
	_onItemClick : function (ndx_) {
		if (this.disabled) return;
		this.pressed = false;
		this._redrawBtn();
		var ndxOld = this.shownIndex;
				
		var selectItem = this.setValue (this.values[ndx_]);
		this._showList (false);
		
		if (selectItem) {
			this.label.focus();
			if( AWUI.isFunction(this.onselchange) )
				this.onselchange (this.values[this.selectedIndex], this.values[ndxOld], this);
		}
		
		aSelect.prototype.LAST_EXPANDED_SELECT = null;
	},
	
	_onItemMouseAction : function (obj_, bIsOut_) {
		if (!obj_ || !obj_.style) return;
		
		for (var ndx=0; ndx < this.listTable.rows.length; ndx++)	{
			var c = this.listTable.rows[ndx].cells[0];
			if (c == obj_) {
				obj_.style.backgroundColor = (bIsOut_ ? this.colorB : this.colorBs);
				obj_.style.color = (bIsOut_ ? this.colorF : this.colorFs);
			} else {
				c.style.backgroundColor = this.colorB;
				c.style.color = this.colorF;
			}
		}
	}
	
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Belarus Belarus
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions