Click here to Skip to main content
15,892,059 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(window.AWUI) == "undefined") alert ("AWUI is not available");

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

AWUI.Controls.OnRangeSelectorFinishMove = function (e_)	{
	var proto = AWUI.Controls.RangeSelector.prototype;
	document.onmousemove = (proto.MOUSE_MOVE_OLD ? proto.MOUSE_MOVE_OLD : null);
	document.onmouseup = (proto.MOUSE_UP_OLD ? proto.MOUSE_UP_OLD : null);
	if (proto.PROCESSED_OBJ) {
		proto.PROCESSED_OBJ.labellnk.focus();
		proto.PROCESSED_OBJ.selectedTraveler = null;
	}
	proto.PROCESSED_OBJ = null;
};
AWUI.Controls.OnRangeSelectorProcessMove = function (e_) {
	var ev = (e_ ? e_ : window.event);
	var x = ev.clientX + document.body.scrollLeft;
	var sl = AWUI.Controls.RangeSelector.prototype.PROCESSED_OBJ;
	if (sl)
		sl.move(x, false, sl.selectedTraveler);
	return AWUI.stopPropagation(e_);	
};

AWUI.Controls.OnRangeSelectorStartMove = function (e_) {
	var target = AWUI.srcEl(e_);
	while (target)	{
		if (String(target.tagName).toUpperCase() != "TABLE")
			target = target.parentNode;
		else 
			break;
	}
	var proto = AWUI.Controls.RangeSelector.prototype;
	if (!target) 
		return AWUI.Controls.RangeSelector.superclass.processError (this, 'Cannot find slider object', AWUI.ERROR_OBJECT);
	
	var sl = AWUI.getWuiObj(target.id);
	if (!sl || sl.disabled) return;
	sl.selectedTraveler = target;
	
	
	proto.MOUSE_MOVE_OLD = document.onmousemove;
	proto.MOUSE_UP_OLD = document.onmouseup;
	document.onmousemove =  AWUI.Controls.OnRangeSelectorProcessMove;
	document.onmouseup = AWUI.Controls.OnRangeSelectorFinishMove;
	
	var ev = (e_ ? e_ : window.event);
	proto.MOUSE_DOWN_X = ev.clientX + document.body.scrollLeft;
	proto.MOUSE_DOWN_Y = ev.clientY + document.body.scrollTop;
	proto.PROCESSED_OBJ = sl;
	
	var offset = AWUI.absPos(sl.selectedTraveler).left - AWUI.absPos(sl.wnd).left; 
	proto.MOUSE_START_OFFSET = offset;
	
	return AWUI.stopPropagation(e_);	
}

AWUI.Controls.OnRangeSelectorAxisClick = function(e_)	{
	var target = AWUI.srcEl(e_);

	while (target)	{
		if (String(target.tagName).toUpperCase() != "TABLE") target = target.parentNode;
		else break;
	}
	if (!target) 
		return AWUI.Controls.RangeSelector.superclass.processError (this, 'Cannot find slider object', AWUI.ERROR_OBJECT);

	var sl = AWUI.getWuiObj(target.id);
	if (!sl || sl.disabled) return;

	var ev = (e_ ? e_ : window.event);
	var x = ev.clientX + document.body.scrollLeft;
	var pos = AWUI.absPos(sl.wnd);
	var proto = AWUI.Controls.RangeSelector.prototype;
	proto.PROCESSED_OBJ = sl;
	proto.MOUSE_DOWN_X = pos.left + 20;
	proto.MOUSE_START_OFFSET = 10;
	
	sl.move(x);
	sl.labellnk.focus();
	
	if (proto.PROCESSED_OBJ)
		AWUI.Controls.OnRangeSelectorFinishMove();
	return AWUI.stopPropagation(e_);	
}

AWUI.Controls.OnRangeSelectorKeyUp = function (e_) {
	var sender = AWUI.srcEl(e_), 
		keyCode = AWUI.getKeyCode(e_);
	if (!sender) return; 
	//debugger;
	var sl = AWUI.getWuiObj(sender.id); 	
	if (!sl) return; 
	
	switch (keyCode) {
		case AWUI.KEY_RIGHT: 
			sl.move (sl.pageSize, true, sl.travelerLeft);
			break;
		case AWUI.KEY_LEFT:
			sl.move (-sl.pageSize, true, sl.travelerLeft);
			break;
		case AWUI.KEY_UP:
			sl.move (sl.pageSize, true, sl.travelerRight);
			break;
		case AWUI.KEY_DOWN:
			sl.move (-sl.pageSize, true, sl.travelerRight);
			break;
	}
}

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

AWUI.Controls.RangeSelector = function (posLeft_, posRight_, maxPos_, minPos_) {
	this.superclass.constructor.call (this);
	
	var proto = AWUI.Controls.RangeSelector.prototype;
	
	this.trHeight = proto.TRAVELER_HEIGHT;
	this.height = proto.HEIGHT;
	this.statusHeight = proto.STATUS_HEIGHT;
	this.width = proto.WIDTH;
	this.margin = proto.MARGIN;
	this.fontSize = proto.FONT_SIZE;
	this.fontFamily = proto.FONT_FAMILY;
	// objects
	this.wnd = null;
	this.axis = null;
	this.travelerLeft = null;
	this.travelerRight = null;
	this.selectedTraveler = null;
	
	this.status = null;
	this.label = null;
	this.labellnk = null;
	// target
	this.targetId = "";
	this.target = null;
	//state
	this.disabled = false;
	// properties
	
	
	this.maxPos = (maxPos_ != undefined && maxPos_ != null ? maxPos_ : proto.MAXPOS);
	this.minPos = (minPos_ != undefined && minPos_ != null ? minPos_ : proto.MINPOS);
	this.positionLeft = (posLeft_ != undefined && posLeft_ != null ? Math.min(posLeft_, this.minPos) : this.minPos);
	this.positionRight = (posRight_ != undefined && posRight_ != null ? Math.min(posRight_, this.maxPos) : this.maxPos);
	
	this.pageSize = proto.PAGE_SIZE;
	this.lCells = [];
	this.mCells = [];
	this.dCells = [];
	this.wCells = [];
	// colors
	this.colorW = proto.COLOR_WND;
	this.colorD = proto.COLOR_DARK_EDGE;
	this.colorM = proto.COLOR_MEDIUM_EDGE;
	this.colorL = proto.COLOR_LIGHT_EDGE;
	this.colorB = proto.COLOR_WND;
	this.colorE = proto.COLOR_MEDIUM_EDGE;

	// format delimiters
	this.valueDelim = proto.VALUE_DELIMITER;
	this.shownValueDelim = proto.SHOWN_VALUE_DELIMITER;
	
	// handlers
	this.onscroll = null;
}

AWUI.extend (AWUI.Controls.RangeSelector, AWUI.Controls.Object);

AWUI.Controls.RangeSelector.prototype = {
	AWUI_KEY: "Slider",
	superclass: AWUI.Controls.RangeSelector.superclass,
	
	MOUSE_MOVE_OLD: null,
	MOUSE_UP_OLD: null,
	MOUSE_DOWN_X: 0,
	MOUSE_DOWN_Y: 0,
	MOUSE_START_OFFSET: 0,
	PROCESSED_OBJ: null,
	
	TRAVELER_HEIGHT : 24,
	HEIGHT : 40,
	STATUS_HEIGHT : 20,
	WIDTH: 200,
	MARGIN: 20,
	FONT_SIZE: "9pt",
	FONT_FAMILY: "Tahoma, Arial, serif",
	
	MINPOS: 1,
	MAXPOS: 100,
	PAGE_SIZE: 10,
	
	COLOR_WND : "ButtonFace", 	COLOR_DARK_EDGE : "ThreedDarkShadow",
	COLOR_MEDIUM_EDGE : "ButtonShadow",	COLOR_LIGHT_EDGE : "ButtonHighlight",
	
	VALUE_DELIMITER : ":",
	SHOWN_VALUE_DELIMITER : " : ",
	
	createTraveler: function (axWidth_, pos_, no_) {
		if (AWUI.isEmpty(no_))
			no_ = 0;
			
		tbl = AWUI.crel("TABLE");
		tbl.id = this.id +  AWUI.ID_DELIM + (no_ == 0 ? "travelerLeft" : "travelerRight");
		tbl.ondragstart = function (e) { AWUI.stopPropagation(e) };
		
		tbl.cellPadding = tbl.cellSpacing = tbl.border = 0; 
		tbl.width = 15;
		tbl.height = this.trHeight;
		tbl.style.position = "relative";
		tbl.style.zIndex = 20 + no_;
		var offset = (this.margin - 7) + Math.round( axWidth_ * ((pos_ - this.minPos)/(this.maxPos - this.minPos) ) );
		tbl.style.left = offset;
		tbl.style.top = (this.height - this.trHeight ) / 2 - 4 - this.trHeight * no_;
		
		r = tbl.insertRow (-1);
		� = r.insertCell (-1);
		�.height = 1; �.width = 14; �.colSpan = 14; �.style.backgroundColor = this.colorL;	AWUI.push (this.lCells, �);
		� = r.insertCell (-1);
		�.height = 1; �.width = 1; �.style.backgroundColor = this.colorD; AWUI.push (this.dCells, �);
		
		r = tbl.insertRow (-1);
		� = r.insertCell (-1);
		�.height = (this.trHeight - 8); �.width = 1; �.style.backgroundColor = this.colorL; AWUI.push (this.lCells, �);
		� = r.insertCell (-1);
		�.height = (this.trHeight - 8); �.width = 12; �.colSpan = 12; �.style.backgroundColor = this.colorW; AWUI.push (this.wCells, �);
		� = r.insertCell (-1);
		�.height = (this.trHeight - 8); �.width = 1; �.style.backgroundColor = this.colorM; AWUI.push (this.mCells, �);
		� = r.insertCell (-1);
		�.height = (this.trHeight - 8); �.width = 1; �.style.backgroundColor = this.colorD; AWUI.push (this.dCells, �);
		
		for (var ndx=0; ndx<6; ndx++) {
			r = tbl.insertRow (-1);
			� = r.insertCell (-1);
			�.height = 1; �.width = ndx+1; if (ndx) �.colSpan=ndx+1;
			� = r.insertCell (-1);
			�.height = 1; �.width = 1; �.style.backgroundColor = this.colorL; AWUI.push (this.lCells, �);
			if (ndx<5) {
				� = r.insertCell (-1);
				�.height = 1; �.width = (10-ndx*2); �.colSpan = (10-ndx*2); �.style.backgroundColor = this.colorW; AWUI.push (this.wCells, �);
			}
			
			� = r.insertCell (-1);
			�.height = 1; �.width = 1; �.style.backgroundColor = this.colorM; AWUI.push (this.mCells, �);
			� = r.insertCell (-1);
			�.height = 1; �.width = 1; �.style.backgroundColor = this.colorD; AWUI.push (this.dCells, �);
			� = r.insertCell (-1);
			�.height = 1; �.width = ndx+1; if (ndx) �.colSpan=ndx+1;
		}
		
		r = tbl.insertRow (-1);
		� = r.insertCell (-1);
		�.height = 1; �.width = 7; �.colSpan = 7;
		� = r.insertCell (-1);
		�.height = 1; �.width = 1; �.style.backgroundColor = this.colorD; AWUI.push (this.dCells, �);
		� = r.insertCell (-1);
		�.height = 1; �.width = 7; �.colSpan = 7;
		
		return tbl;
	},
	
	init : function	() {
		// 15 x 97
		var tbl, r, c;
		var axWidth = this.width - this.margin * 2;
		
		this.travelerLeft = this.createTraveler (axWidth, this.positionLeft, 0);
		this.travelerRight = this.createTraveler (axWidth, this.positionRight, 1);
		
		// AXIS
		tbl = AWUI.crel("TABLE")
		tbl.id = this.id + AWUI.ID_DELIM + "axis";
		tbl.cellPadding = tbl.cellSpacing = tbl.border = 0; 
		tbl.width = "100%";
		tbl.height = 4;
		
		r = tbl.insertRow (-1);
		� = r.insertCell (-1);
		�.height = 1; �.width = axWidth-1; �.colSpan = 3; �.style.backgroundColor = this.colorM;	AWUI.push (this.mCells, �);
		� = r.insertCell (-1);
		�.height = 1; �.width = 1; �.style.backgroundColor = this.colorL; AWUI.push (this.lCells, �);
		r = tbl.insertRow (-1);
		� = r.insertCell (-1);
		�.height = 1; �.width = 1; �.style.backgroundColor = this.colorM;	AWUI.push (this.mCells, �);
		� = r.insertCell (-1);
		�.height = 1; �.width = axWidth-3; �.style.backgroundColor = this.colorD; AWUI.push (this.dCells, �);
		� = r.insertCell (-1);
		�.height = 1; �.width = 1; �.style.backgroundColor = this.colorW; AWUI.push (this.wCells, �);
		� = r.insertCell (-1);
		�.height = 1; �.width = 1; �.style.backgroundColor = this.colorL; AWUI.push (this.lCells, �);
		r = tbl.insertRow (-1);
		� = r.insertCell (-1);
		�.height = 1; �.width = 1; �.style.backgroundColor = this.colorM;	AWUI.push (this.mCells, �);
		� = r.insertCell (-1);
		�.height = 1; �.width = axWidth-2; �.colSpan = 2; �.style.backgroundColor = this.colorW; AWUI.push (this.wCells, �);
		� = r.insertCell (-1);
		�.height = 1; �.width = 1; �.style.backgroundColor = this.colorL; AWUI.push (this.lCells, �);
		
		r = tbl.insertRow (-1);
		� = r.insertCell (-1);
		�.height = 1; �.width = axWidth; �.colSpan = 4; �.style.backgroundColor = this.colorL; AWUI.push (this.lCells, �);
		this.axis = tbl;
		
		// Label - works with focus
		var lbl = AWUI.crel("DIV")
		lbl.id = this.id + AWUI.ID_DELIM + "label";
		lbl.style.height = 4;
		lbl.style.width = axWidth;
		lbl.style.position = "relative";
		lbl.style.zIndex = 10;
		lbl.style.top = this.height / 2 - 2;
		lbl.style.left = this.margin;

		var a = AWUI.crel("A")
		a.id = this.id + AWUI.ID_DELIM + "labellnk";
		a.href = "javascript:void(0)";
		a.appendChild (this.axis);
		
		this.labellnk = a;
		this.label = lbl;
		this.label.appendChild (a);
		
		var w = AWUI.crel("DIV");
		w.id = this.id + AWUI.ID_DELIM + "wnd";
		w.style.width = this.width;
		w.style.height = parseInt(this.height) + parseInt(this.statusHeight);
		w.style.overflow = "hidden";
		w.onscroll = function (e) { AWUI.stopPropagation(e) };
				
		w.style.fontSize = this.fontSize;
		w.style.fontFamily = this.fontFamily;

		if (this.colorB) w.style.backgroundColor = this.colorB;
		if (this.colorE) {
			w.style.border = "1px solid " + this.colorE;
			w.style.padding = 0;
		} else {
			w.style.padding = 1;
		}

		var sts = AWUI.crel("DIV");
		sts.id = this.id + AWUI.ID_DELIM + "status";
		sts.style.position = "relative";
		sts.style.zIndex = 10;
		sts.style.top = this.height - this.trHeight * 2 - 5;
		sts.style.left = 0;
		sts.style.width = this.width;	
		sts.style.height = this.statusHeight;
		sts.style.textAlign = "center";	sts.style.verticalAlign = "middle";
		sts.style.lineHeight = (this.statusHeight - (AWUI.IS_IE ? 2 : 0)) +"px";
		sts.innerHTML = this.formatShownValue();
		if (this.colorE) 
			sts.style.borderTop = "1px solid " + this.colorE;
		this.status = sts;

		this.wnd = w;
		this.wnd.appendChild (this.label);
		this.wnd.appendChild (this.travelerLeft);
		this.wnd.appendChild (this.travelerRight);
		this.wnd.appendChild (this.status);
	},
	
	formatShownValue: function () {
		return this.getValue (this.shownValueDelim);
	},
	
	formatValue: function (){
		return this.getValue (this.valueDelim);
	},
	
	getValue: function (delim) {
		var delim = this.valueDelim;
		
		var res = this.positionLeft + delim + this.positionRight;
		if (this.positionLeft > this.positionRight)
			res = this.positionRight + delim + this.positionLeft;
		
		return res;
	},
	
	draw : function(trgt_, w_, h_) {
	
		if (arguments.length > 1)
			this.width = w_;
		if (arguments.length > 2)
			this.height = h_;
		
		if (  AWUI.el(this.id + AWUI.ID_DELIM + "base"))
			return this.superclass.processError_DuplicateObject (this);

		this.init();
		AWUI.wr ("<DIV id='"+this.id + AWUI.ID_DELIM + "base' UNSELECTABLE='on'></DIV>");
		var bs =  AWUI.el(this.id + AWUI.ID_DELIM + "base");
		if (!bs)
			return this.superclass.processError_CreateBase (this);

		bs.appendChild (this.wnd);
		this.base = bs;
		
		this.initHandlers();

		if (typeof(trgt_) == 'object') {
			this.target = trgt_;
		
		} else if (!AWUI.isEmpty(trgt_))	{
			this.targetId = trgt_;
			this.target = AWUI.el(trgt_);
		}
		
		if ( AWUI.isEmpty(trgt_) ) {
			var input = AWUI.crel("INPUT");
			input.name = input.id = this.id;
			input.type = "hidden";
			this.base.appendChild(input);
			this.target = input;
		}
		if (this.target)
			this.target.value = this.formatValue();
	},
	
	initHandlers: function()	{
		this.travelerLeft.onmousedown = AWUI.Controls.OnRangeSelectorStartMove;
		this.travelerRight.onmousedown = AWUI.Controls.OnRangeSelectorStartMove;
		this.axis.onclick =  AWUI.Controls.OnRangeSelectorAxisClick;
		this.labellnk.onkeyup = AWUI.Controls.OnRangeSelectorKeyUp;
	},
	
	colorizeCells: function(ar_, color_)	{
		if (!ar_ || !ar_.length) return;
		for (key in ar_)
			ar_[key].style.backgroundColor = color_;
		
	},
	
	setColors: function (colorW, colorD, colorM, colorL, colorB, colorE)	{
		if (colorW)	{	this.colorW = colorW;	this.colorizeCells (this.wCells, this.colorW);	}
		if (colorD)	{	this.colorD = colorD;	this.colorizeCells (this.dCells, this.colorD);	}
		if (colorM)	{	this.colorM = colorM;	this.colorizeCells (this.mCells, this.colorM);	}
		if (colorL)	{	this.colorL = colorL;	this.colorizeCells (this.lCells, this.colorL);	}
		if (colorB) { 
			this.colorB = colorB; this.wnd.style.backgroundColor = this.colorB;
		} else {
			this.colorB = ""; this.wnd.style.backgroundColor = ""; 
		}
		if (colorE) { 
			this.colorE = colorE; this.wnd.style.border = "1px solid " + this.colorE; this.wnd.style.padding = 0;
			this.status.style.borderTop = "1px solid " + this.colorE;
		}	else { 
			this.colorE = ""; this.wnd.style.borderWidth = 0; this.wnd.style.padding = 1;
			this.status.style.borderWidth = 0;
		}
	},

	move: function(x_, isRelative_, traveler_) {
		isRelative_ = (isRelative_ || false);
		var x = parseInt(x_);
		if (AWUI.isEmpty(traveler_))
			traveler_ = this.travelerLeft;
		var val = (traveler_ == this.travelerLeft ? this.positionLeft : this.positionRight), 
			d = 0;
		var scale = (this.wnd.offsetWidth - this.margin*2 - 10) / (this.maxPos - this.minPos);
		
		if (!isRelative_) {
			d = x - AWUI.Controls.RangeSelector.prototype.MOUSE_DOWN_X + 
				AWUI.Controls.RangeSelector.prototype.MOUSE_START_OFFSET;
		} else {
			val += x_;
			d = this.margin + (this.minPos + val) * scale;
		}
		
		if (d <= (this.margin-7) ) d = (this.margin - 7);
		if (d >= this.wnd.offsetWidth - this.margin - 10) 
			d = this.wnd.offsetWidth - this.margin -10;
		
		if (!isRelative_)
			val = this.minPos + Math.round( (d - this.margin) / scale);
		
		if (val <= this.minPos) val = this.minPos;
		if (val >= this.maxPos) val = this.maxPos;
		
		var canMove = true;
		if ( typeof(this.onscroll) == "function") {
			var res = this.onscroll(this, val, traveler_);
			if (res == false)
				canMove = false;
		}
		
		if (canMove) {
			// apply offset
			if (traveler_ == this.travelerLeft) {
				this.positionLeft = val;
				this.travelerLeft.style.left = d;
			} else {
				this.positionRight = val;
				this.travelerRight.style.left = d;
			}
			
			if (this.targetId) this.target = AWUI.el(this.targetId);
			if (this.target) this.target.value = this.formatValue();
			this.status.innerHTML = this.formatShownValue();
		}
	}
}


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