﻿/*------------------------------------------------------------
 JGrid JavaScript Data Grid:
 Author:xlingFairy
 Email:xlingFairy@hotmail.com
 Blog:xling.blueidea.com
 本程序属本人原创,如果哪位要使用或在此基础上进行修改,请保留原作者信息
 谢谢使用.
------------------------------------------------------------*/
function resizeObj(){
	this.obj	=null;
	this.grabX	=null;
	this.grabY	=null;
	this.width	=null;
	this.cursor	="col-resize";
}

function clickRow(){
	this.obj		=null;
	this.rowIndex	=null;
}

function JGrid(pWidth,pHeight,pParentNode){

	/*---------------------------
	参数设置：property:debug,rowCountAreaWidth
	----------------------------*/
	var self				=this;
	var baseZIndex			=10000;	//拖动表头的分隔线时要用到。
	var titleAreaWidth;
	var resizeField			=null;	//
	var realWidth			=0;	
	var lastClickRow		=new clickRow();
	var colAlign 			=new Array();
	var clickTd				=null;
	var	edtBox				=null;

	NS="";//命名空间
	this.setNS=function(nameSpace){
		NS=nameSpace;
	};

	this.debug				=true;	//是否显示错误信息
	this.rowCountAreaWidth	="40px";
	this.fieldTitleHeight	="22px";
	this.rowHeight			="22px";
	/*---------------------------
	长宽计算，property:width,height
	----------------------------*/
	this.width	="100%";	
	this.height	="100%";
	
	pWidth	==null ? null:this.width	=pWidth;
	pHeight	==null ? null:this.height	=pHeight;
		
	if(isNaN(this.width) && this.width.indexOf("%")!=this.width.length-1)
		this.width="100%";
	if(isNaN(this.height) && this.height.indexOf("%")!=this.height.length-1)
		this.width="100%";
		
	(!isNaN(this.width))	? this.width	=this.width	+ "px" : null;
	(!isNaN(this.height))	? this.height	=this.height+ "px" : null;
	
	
	/*-------------------------
	method:$(pObjID)
	--------------------------*/
	var $=function(pObjID){
		try{
			return document.getElementById(pObjID)
		}catch(e){
			alert("here");
			showMessage("不存在ID为："+pObjID+" 的Element");	
		}
	}
	
	/*-------------------------
	method:showMessage(pMsg)
	--------------------------*/	
	var showMessage=function(pMsg){
		if(!this.debug)	return;
		
		pMsg=	pMsg || "";	//为果为null就等于""
		alert(pMsg)
	}
		
	/*-------------------------
	method:createHTMLObj　生成OBJECT
	--------------------------*/
	var createHTMLObj=function(pTag){
		return tmpObj=document.createElement(pTag);	
	}
	
	var createEdtBox=function(pObj){
		edtBox = createHTMLObj("TEXTAREA");
		edtBox.className = "oEdtBox";
		//alert(pObj.clientLeft);
		edtBox.style.position="absolute";
		edtBox.style.width = (pObj.clientWidth > 200 ? 200 : (pObj.clientWidth <100 ? 100 : pObj.clientWidth)) + "px";
		edtBox.value = (pObj.innerHTML).replace("&nbsp;"," ");
		//pObj.appendChild(edtBox)
		pObj.insertBefore(edtBox,pObj.firstChild);
		edtBox.focus();
	};
	
	/*-------------------------
	property:parentNode　父节点
	--------------------------*/
	
	this.parentNode	=$(pParentNode) || window.document.body;	//如果参数为null就等于body
	
	/*--------------------------
	method:createSplit
	--------------------------*/
	var createSplit=function(){
		var oSplit=createHTMLObj("SPAN");
			with(oSplit.style){
				styleFloat 	="right";
				cssFloat	="right";
				width		="5px";
				height		=parseInt(self.fieldTitleHeight)-8+"px";
				top			="4px";
				position	="relative";
				overflow	="hidden";
				cursor		="col-resize";
			}
			oSplit.className="oSplit";
		return oSplit;
	}
	
	/*-------------------------
	property:oOutLine 外框
	method:createOutLine 画外框
	--------------------------*/
	var oOutLine;
	var createOutLine=function(){
		oOutLine=createHTMLObj("DIV");
			
		with(oOutLine.style){
			width	=self.width;
			height	=self.height;
			position="relative";
			overflow="auto";
		}
		oOutLine.className="oOutLine";
		
		oOutLine.onscroll=function(evt){
			if(evt){//只针对fireFox
				oTopLeft.style.top = oTitleArea.style.top = oOutLine.scrollTop + "px";
			}
		}
		
		self.parentNode.appendChild(oOutLine);
		
		titleAreaWidth=oOutLine.clientWidth-parseInt(self.rowCountAreaWidth);
	}
	/*-------------------------
	左上角
	method:createTopLeft 	画左上角
	--------------------------*/
	var oTopLeft;
	var createTopLeft=function(){
		oTopLeft=createHTMLObj("DIV");
		try{
			oTopLeft.style.cssText = "top:expression(this.parentNode.scrollTop+'px');left:expression(this.parentNode.scrollLeft+'px')"
		}catch(e){}
		with(oTopLeft.style){
			width	=self.rowCountAreaWidth;
			height	=self.fieldTitleHeight;
			//left	="0px";
			//top		="0px";
			position="absolute";
			zIndex	=baseZIndex+100;
		}
		oTopLeft.className="oTopLeft";
		oTopLeft.appendChild(createSplit());
		oOutLine.appendChild(oTopLeft);
	}
	
	/*----------------------------
	表头区
	createTitleArea
	-----------------------------*/
	var oTitleArea;
	var createTitleArea=function(){
		oTitleArea=createHTMLObj("DIV");
		try{
			oTitleArea.style.cssText 	="top:expression(this.parentNode.scrollTop+'px')";
		}catch(e){}
		
		with(oTitleArea.style){
			//top		="0px";
			left	=self.rowCountAreaWidth;
			height	=self.fieldTitleHeight;
			position="relative";
			zIndex	=baseZIndex+99;
			overflow="visible";
		}
		oTitleArea.className="oTitleArea";
		
		
		oOutLine.appendChild(oTitleArea);
	}
	
	/*---------------------------
	createTitleItem
	---------------------------*/
	var titleItemTotalWidth=0;
	var createTitleItem=function(pCaption,pWidth,pAlign,pIndex){
		titleItemTotalWidth+=pWidth;
		titleItemTotalWidth>titleAreaWidth ? titleAreaWidth=titleItemTotalWidth+10 : null;
		oTitleArea.style.width=titleAreaWidth+"px";
		
		var oTitleItem=createHTMLObj("DIV");
			//oTitleItem.innerHTML=pCaption;
			var oTitleItemCaption=createHTMLObj("DIV");
				oTitleItemCaption.innerHTML=pCaption;
				
				with(oTitleItemCaption.style){
					styleFloat	="left";
					cssFloat	="left";
					overflow	="hidden";
					wordBreak	="keep-all";
					position	="absolute";
					height		=self.fieldTitleHeight;
					lineHeight	=self.fieldTitleHeight;
				}
				
				oTitleItemCaption.className="oTitleItemCaption";
			oTitleItem.appendChild(oTitleItemCaption);
			
			with(oTitleItem.style){
				styleFloat	="left";
				cssFloat	="left";
				width		=pWidth+"px";
				overflow	="hidden";
				textIndent	="3px";
				zIndex		=pIndex;
				position	="relative";
				height		=self.fieldTitleHeight;
			}
			oTitleItem.className="oTitleItem";
		oTitleItem.appendChild(createSplit());
		
		oTitleItem.onmouseover=function(){
			this.className="oTitleItemActive";
		}
		
		oTitleItem.onmouseout=function(){
			//resizeField=null;
			this.className="oTitleItem"	;
		}
		
		oTitleItem.onmousedown=function(evt){
			evt= evt || window.event;
			var obj=evt.target || evt.srcElement;
			
			if(obj.className!="oSplit") return false;
			
			obj.parentNode.style.cursor="col-resize";
			
			resizeField=new resizeObj();
			resizeField.obj	=obj;
			with(resizeField){
				obj.style.cursor=cursor;
				obj.parentNode.cursor=cursor;
				grabX	=evt.clientX;
				width	=obj.parentNode.clientWidth;
				evt.returnValue = false;
				evt.cancelBubble = true;
			}
		}
		
		oTitleItem.onmouseup=function(){
			if(resizeField){
				self.updateFieldWidth(pIndex,parseInt(resizeField.obj.parentNode.style.width)-1);
				resizeField=null;
			}
		}		
		
		
		oTitleItem.onmousemove=function(evt){
			if(resizeField){			
				var obj=resizeField.obj.parentNode;
				if(!evt) evt=event;
				var xMin=8;
				titleAreaWidth	-=obj.clientWidth;
				obj.style.width=(resizeField.width+evt.clientX-resizeField.grabX<xMin ? xMin : resizeField.width+evt.clientX-resizeField.grabX) + "px";
				titleAreaWidth+=obj.clientWidth;				
				oTitleArea.style.width=titleAreaWidth+"px";
			}
		}
		
		oTitleItem.onclick = function(evt){
			if(oDataTable.rows.length<2) return false;
			
				var tab_array=new Array();
				this.getAttribute("sortMode")==null ? this.setAttribute("sortMode",true) : this.setAttribute("sortMode",(!this.getAttribute("sortMode")));
							
				for(var j=0;j<oDataTable.rows.length;j++){
					tab_array.push(new Array(oDataTable.rows[j].cells[pIndex].innerHTML.toLowerCase(),oDataTable.rows[j]));
				}
				
				var sortMode=this.getAttribute("sortMode");
				tab_array.sort(function(){
										arr1=arguments[0];
										arr2=arguments[1];
										//var flag;
										var a = arr1[0];
										var b = arr2[0];
											//========================================
											if(/^(\+|-)?\d+($|\.\d+$)/.test(a) && /^(\+|-)?\d+($|\.\d+$)/.test(b)){
												a=eval(a);
												b=eval(b);
												//flag=sortMode?(a>b?1:(a<b?-1:0)):(a<b?1:(a>b?-1:0));
											}else{
												a=a.toString();
												b=b.toString();
												//flag=sortMode?(a>b?1:(a<b?-1:0)):(a<b?1:(a>b?-1:0));
											}
											return sortMode?(a>b?1:(a<b?-1:0)):(a<b?1:(a>b?-1:0));
											//========================================											
										//}
										});
				
				try{//这样做是为了提高排序效率．
					for(j=0;oDataTable.lastChild.appendChild(tab_array[j][1]);j++){};
				}catch(e){
					//	
				}
				reTackData();
		}
		
		oTitleArea.appendChild(oTitleItem);
	}
	
	var reTackData = function(){
		var oRow,flag = false;
		for (var i=0;oRow=oDataTable.rows[i];i++){
			if(oRow.className == "oRowClick"){
				flag = true;
			}
			oRow.className=(i % 2 ==0 ? "oRowLine2" : "oRowLine1");
			oRow.setAttribute("baseStyle",oRow.className);
			flag ? oRow.className = "oRowClick" : null;
			flag = false;
		}
	};
	
	/*---------------------------
	updateFieldWidth
	----------------------------*/
	this.updateFieldWidth=function(pIndex,pWidth){
		var obj = oDataTable.getElementsByTagName("COL")[pIndex];
		obj.width = pWidth;
	}
	
	/*---------------------------
	createTitle
	----------------------------*/
	this.createTitle=function(pTitleArray){
		//[caption,width,align];
		var i,tTitleItem;
		var tCaption,tWidth,tAlign;
		
		for(i=0;i<pTitleArray.length;i++){
			tCaption	=pTitleArray[i][0]				|| "未设置";
			tWidth		=parseInt(pTitleArray[i][1])	|| 100;
			realWidth	+=tWidth;
			tAlign		=pTitleArray[i][2]				||	"left";
			colAlign.push(tAlign);
			createTitleItem(tCaption,tWidth,tAlign,i);
		}
	}
	
	/*----------------------------
	oRowCountArea,createRowCountArea
	----------------------------*/
	var oRowCountArea;
	var createRowCountArea=function(){
		oRowCountArea=createHTMLObj("DIV");
		oRowCountArea.className="oRowCountArea";
		
		try{
			oRowCountArea.style.cssText = "left:expression(this.parentNode.scrollLeft+'px')";
		}catch(e){}
		
		with(oRowCountArea.style){
			width	=self.rowCountAreaWidth;
			height	="100%";
			position="absolute";
			//left="0px";
			top=parseInt(self.fieldTitleHeight)+1+"px";
			zIndex=baseZIndex+98;
		}
		oOutLine.appendChild(oRowCountArea);		
	}
	
	
	/*----------------------------
	oDataArea,createDataArea
	----------------------------*/
	
	var oDataArea;
	var createDataArea=function(){
		oDataArea=createHTMLObj("DIV");
		oDataArea.className="oDataArea";
		with(oDataArea.style){
			left	=parseInt(self.rowCountAreaWidth)+1+"px";
			top		=parseInt(self.fieldTitleHeight)+1+"px";
			position="absolute";
			overflow="visible";
			zIndex	=baseZIndex+97;
		}
	
		oOutLine.appendChild(oDataArea);
	}		
	
	/*----------------------------
	createRowCount
	-----------------------------*/
	var createRowCount=function(pI,pRow){
		var oRowCount=createHTMLObj("DIV");
			oRowCount.innerHTML		=pI+1;
			with(oRowCount.style){
				//height		=pRow.style.height;	
				height 		= parseInt(self.rowHeight)-1 + "px";
				width		="100%";
				lineHeight	=height;
				textAlign	="left";
				textIndent 	="3px";
			}
			oRowCount.className="oRowCount";
			
			oRowCount.onclick = function(){
				try{clickTd.removeChild(edtBox);}catch(e){};
				try{clickTd.className = "";}catch(e){}
				
				if(lastClickRow.obj!=null)
					lastClickRow.obj.className=lastClickRow.obj.getAttribute("baseStyle");
				
				var oRow = oDataTable.rows[pI];
				
				if(lastClickRow.obj!=oRow){
					lastClickRow.obj=oRow;
					oRow.className="oRowClick";
				}else{
					lastClickRow.obj=null;
					oRow.className=oRow.getAttribute("baseStyle");
				}

				clickTd = null;
			}
			
			oRowCountArea.appendChild(oRowCount);
	}
	
	
	/*----------------------------
	method:tackData
	-----------------------------*/
	var oDataTable;
	this.tackData=function(pGridID){
		oDataTable=$(pGridID);
		if(oDataTable.rows.length==0) return;		
		try{
			oDataTable.removeAttribute("width");
			oDataTable.border		=0;
			oDataTable.cellPadding	=0;
			oDataTable.cellSpacing	=0;
			oDataTable.className	="oDataTable";
			oDataTable.style.tableLayout="fixed";
			oDataArea.appendChild(oDataTable);
		}catch(e){
			//
		}
		
		//更新部分:20060523,更新内容,用col
		var oTBody = oDataTable.firstChild;
		var oColGroup = createHTMLObj("COLGROUP");
		for(var i=0;i<oDataTable.rows[0].cells.length;i++){
			var oCol = createHTMLObj("COL");
				oCol.className = "oCol";
				oCol.width = parseInt(oTitleArea.childNodes[i].style.width) -1 || 100;
				oCol.style.lineHeight = self.rowHeight;
				oCol.align = colAlign[i];
				oColGroup.appendChild(oCol);
		}
		oDataTable.insertBefore(oColGroup,oTBody);
		//-----------------------------------------------------------
		
		
		var oRow;
		for(i=0;oRow=oDataTable.rows[i];i++){
			with(oRow.style){
				height		=self.rowHeight;
				//lineHeight	=height;
			}
			
			oRow.className=(i % 2 ==0 ? "oRowLine2" : "oRowLine1");
			oRow.setAttribute("baseStyle",oRow.className);
			
			createRowCount(i,oRow);
			
			oRow.onmouseover=function(){
				with(this){
					className!="oRowClick" ? className="oRowOver" :null;
				}
			}
			
			oRow.onmouseout=function(){
				with(this){
					className!="oRowClick" ? className=getAttribute("baseStyle") : null;	
				}
			}
			
		}
		oDataTable.onclick = function(evt){
			evt = evt || window.event;
			var o = evt.target || evt.srcElement;
			if(o.tagName == "TD"){
				try{
					clickTd.className = "";
					var edtBox = clickTd.getElementsByTagName("TEXTAREA")[0];
					var value = edtBox.value;
					clickTd.removeChild(edtBox);
					clickTd.innerHTML = value;
				}catch(e){};
				o.className = "tdClick";
				clickTd = o;
			}
		}
		oDataTable.ondblclick = function(evt){
			try{
				oDataTable.removeChild(edtBox);
			}catch(e){}
			evt = evt || window.event;
			var o = evt.target || evt.srcElement;
			if(o.tagName == "TD"){
				createEdtBox(o);
			}
		}
		oDataTable.onkeypress = function(evt){
			evt = evt || window.event;//CTRL+SHIFT+F
			if(evt.keyCode == 6){
				findText();
			}
		}
	}
	
	
	findText=function(){
		try{
			var value,tParent;
			for(var i=0;oTextRange=document.getElementsByTagName("SPAN")[i];i++){
				if(oTextRange.getAttribute("name")==NS+"JGridTextRange"){
					value = oTextRange.innerHTML;
					tParent = oTextRange.parentNode;
					tParent.removeChild(oTextRange);
					tParent.innerHTML = value;					
				}
						
			}
			
			var returnStr=dialog("JGridTool.htm",300,30);
			if(returnStr=="" || returnStr==null) return;
			var keyWords=returnStr.split(",");
			
			for(var i=0;i<keyWords.length;i++){
				var oRange = document.body.createTextRange(); 
				while(oRange.findText(keyWords[i])){
					oRange.pasteHTML("<SPAN name='"+NS+"JGridTextRange' style='background-color:yellow'>" + oRange.text + "</SPAN>"); 
					oRange.moveStart("character",1); 
				}
			}
		}catch(e){
			//alert();	
		}
	}


	dialog=function(urlStr,width,height){
		return window.showModalDialog(urlStr,"","dialogHeight:" + height + "px;dialogWidth:" + width + "px;center=yes;resizable:yes;status:no")
	}	
	
	
	/*----------------------------
	method:create
	-----------------------------*/
	
	this.create=function(){
		createOutLine();
		createTopLeft();
		createTitleArea();
		createRowCountArea();
		createDataArea();
	}
}