function datagrid() {
		this.template=null;this.target=null;
		this.rawdata=null;this.data=null;this.def=null;
		this.cache=null;this.sortFunction=null;
		
		this.init = function() {
			this.data = [];
			this.indexes = [];
			for (irow in this.rawdata) {
				newrow = {};
				newrow['index']=irow;//this useful later when sorting
				for (group in this.def.objects) {
					newrow[group] = {};
					a_values = this.rawdata[irow][group].split("~");
					for (ifield in a_values) {
						field = this.def.objects[group][ifield];
						newrow[group][field] = a_values[ifield];
					}
				}	

//do the list types later here

//add new row to data
				this.data[irow] = newrow;
			}

		}
		this.load = function() {
			TemplateObj = TrimPath.parseDOMTemplate(this.template);
			result  = TemplateObj.process(this);
			SetContents(this.target,result);
		}
		this.filter = function(f_sort) {
		//Returns false if row filtered out. true if row passes thru filter.
		//We can overrided this if need more complicated filter	
			this.cache=[];
			//this.cache[0]=this.data[0];
			//this.cache[0].round.player='test';
			//test = this.data[0];
			//test.round.player = 'test';
			for (index in this.data) {
				if(this.filterFunction(this.data[index])) {
					this.cache.push(this.data[index]);
				}
			}
			this.sortGrid(f_sort);
		}
		this.sortGrid = function(f_sort) {
			if(f_sort) {this.sortFunction=f_sort;}
			if(this.sortFunction) {this.cache.sort(this.sortFunction);}
			this.load();
//			this.indexes.sort(function(a, b) {alert(this.data[0].round.player));return a.totals.score-b.totals.score;} );
//myRoundGrid.data.sort(function(a, b) {return a.totals.score- b.totals.score;} );
		}
		
		this.filterSimiliar = function(o_filters) {
		//Returns false if row filtered out. true if row passes thru filter.
		//We can overrided this if need more complicated filter			
			for (filterID in o_filters) {
				if(getObject(filterID).value) {
					re = new RegExp(getObject(filterID).value,"i");
					if(re.test(o_filters[filterID])){}else{return false;}
				}
			}
			//alert('filter' + filterID);
			return true;
		}
		this.filterRange = function(startID,endID,value) {
		//Returns true if row filtered out. false if row to be included.
		//We can overrided this if need more complicated filter
			return this.filterRangeByValue(getObject(start).value,getObject(end).value,value);
		}
		this.filterRangeByValue = function(start,end,value) {
		//Returns true if row filtered out. false if row to be included.
		//We can overrided this if need more complicated filter
			//alert('filterRange1' + value);
			if(start) {
				if(value>=start) {}else{return false;}
			}
			if(end) {
				if(value<=end) {}else{return false;}
			}
			//alert('filterRange2' + value);
			return true;
		}

		this.filterDateRange = function(startID,endID,s_value) {
		//Returns true if row filtered out. false if row to be included.
		//We can overrided this if need more complicated filter
			if(getObject(startID).value) {
				start = new Date(getObject(startID).value);
			}else{
				start = null;
			}
			if(getObject(endID).value) {
				end = new Date(getObject(endID).value);
			}else{
				end = null;
			}
			value = new Date(s_value);
			//alert('filterDate' + this.filterRangeByValue(start,end,value));
			return this.filterRangeByValue(start,end,value);
		}
	}

