JavascriptDataGrid Beta版,实现了一些基本功能,高级一些的数据处理方面的下一步实现。
效果演示地址:http://www.robchen.cn/datagrid/
<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
>
<
meta
http-equiv
="Content-Type"
content
="text/html; charset=utf-8"
/>
<
title
>
DataGrid
</
title
>

<
script
type
="text/javascript"
>
...

var Class = ...{

create:function()...{

return function()...{
this.initialize.apply(this,arguments);
}
}
}

function $(id)...{
return document.getElementById(id);
}

String.prototype.trim = function()...{
return this.replace(/^s+|s+$/g,"");
}

String.prototype.escapeHTML = function()...{
var str = this;
str = str.replace("<","<");
str = str.replace(">",">");
str = str.replace(" "," ");
str = str.replace(/ ?/g,"<br/>");
return str;
}

String.prototype.unescapeHTML = function()...{
var str = this;
str = str.replace(/<s*brs*/?s*>/gi," ");
str = str.replace("<","<");
str = str.replace(">",">");
str = str.replace(" "," ");
return str;
}
//DataItem--------------------------------------------------------------
var DataItem = Class.create();

DataItem.prototype = ...{

initialize:function(td,name,dataRow/**//*,readOnly,mulitline*/)...{
this.dom = td;
this.dataRow = dataRow;
this.dom.dataItem = this;

if(arguments.length >= 4)...{
this.readOnly = arguments[3];
}

if(arguments.length >= 5)...{
this.mulitline = arguments[4];
}
this.name = name;
this.value = td.innerHTML.trim();
var _this = this;

this.dom.ondblclick = function()...{
_this.editMode();
}
},
dataRow:null,
readOnly:false,
mode:0,//0:read,1:edit
input:null,
name:null,
value:null,
dom:null,
mulitline:false,

readMode:function()...{
if(this.mode == 0)return;
this.mode == 0;
if(this.input == null)return;
this.value = this.dom.innerHTML = this.input.value.escapeHTML();
this.input = null;
},

editMode:function()...{
if((this.mode == 1 && this.input != null) || this.readOnly)return;
this.mode = 1;

if(this.mulitline)...{
var input = document.createElement("textarea");
input.style.height = this.dom.offsetHeight + 20 + "px";

}else...{
var input = document.createElement("input");
input.type = "text";
}
input.style.width = this.dom.offsetWidth + 20 + "px";
input.value = this.value.unescapeHTML();
this.dom.innerHTML = "";
this.dom.appendChild(input);
this.input = input;
this.input.focus();
var _this = this;

this.input.onblur = function()...{
_this.readMode();
}
}
}
//-----------------------------------------------------------------------
//DataRow----------------------------------------------------------------
var DataRow = Class.create();

DataRow.prototype = ...{

initialize:function(tr,dataGrid)...{
this.dom = tr;
this.dataGrid = dataGrid;
tr.dataRow = this;
var tds = tr.getElementsByTagName("td");
this.items = new Array();
this.selector = tds[0].getElementsByTagName("input")[0];
this.selector.dataRow = this;

for(var i = 1; i < tds.length ; i ++)...{
this.items.push(new DataItem(tds[i],this.dataGrid.cols.items[i],this));
}
},
dom:null,
dataGrid:null,
items:null,

getIndex:function()...{

for(var i = 0; i < this.dataGrid.rows.length; i ++)...{
if(this.dataGrid.rows[i] == this)return i;
}
},

remove:function()...{
this.dom.parentNode.removeChild(this.dom);
this.dataGrid.rows.splice(this.getIndex(),1);
}
}

//DataGrid--------------------------------------------------------------
var DataGrid = Class.create();

DataGrid.prototype = ...{

initialize:function(table)...{
this.dom = table;
table.dataGrid = this;
var trs = table.getElementsByTagName("tr");
this.cols.dom = trs[0];
this.cols.items = new Array();

this.cols.sort = ...{};
var tds = trs[0].getElementsByTagName("td");
this.selector = tds[0].getElementsByTagName("input")[0];
var _this = this;

this.selector.onclick = function()...{

for(var i = 0; i < _this.rows.length; i ++)...{
_this.rows[i].selector.checked = this.checked;
}
}

for(var i = 1; i < tds.length; i ++)...{
this.cols.items.push(tds[i].innerHTML);
this.cols.sort[tds[i].innerHTML] = -1;
}
this.rows = new Array();

for(var i = 1; i < trs.length; i ++)...{
this.rows.push(new DataRow(trs[i],this));
}
},
selector:null,
dom:null,
rows:null,

cols:...{
items:null,
sort:null,
dom:null
},

reBuild:function()...{
var tbody = this.dom.getElementsByTagName("tbody")[0];
this.dom.removeChild(tbody);
tbody = document.createElement("tbody");
tbody.appendChild(this.cols.dom);

for(var i = 0; i < this.rows.length; i ++)...{
tbody.appendChild(this.rows[i].dom);
}
this.dom.appendChild(tbody);
},

insertRow:function(args)...{

if(typeof arguments[1] != "undefined")...{
var index = arguments[1];
if(index < 0)index = 0;
if(index > this.rows.length)index = this.rows.length;

}else...{
var index = this.rows.length;
}
var tr = document.createElement("tr");
var td = document.createElement("td");
var selector = document.createElement("input");
selector.type = "checkbox";
td.appendChild(selector);
tr.appendChild(td);

for(var i = 0; i < this.cols.items.length; i ++)...{
var td = document.createElement("td");
if(args[i])td.innerHTML = args[i];
tr.appendChild(td);
}
var tbody = this.dom.getElementsByTagName("tbody")[0];

if(index == this.rows.length)...{
tbody.appendChild(tr);
this.rows.push(new DataRow(tr,this));

}else...{
tbody.insertBefore(tr,this.rows[index].dom);
this.rows.splice(index,0,new DataRow(tr,this));
}
},

selectedRows:function()...{
var s = new Array();

for(var i = 0; i < this.rows.length; i ++)...{
if(this.rows[i].selector.checked)s.push(this.rows[i]);
}
return s;
},

deleteRows:function(args)...{
if(typeof args == "undefined" || args.length == 0)return;
var a = new Array();
a = a.concat(args).sort().reverse();
var str = a.join(",");
var reg = /(^|,)([^,]+)((,d+)+)?,2/g;

while(str.match(reg))...{
str=str.replace(reg,"$1$2$3");
}
a = str.replace(/,+/g,",").split(",");

for(var i = 0; i < a.length; i ++)...{

try...{
this.rows[a[i]].remove();

}catch(e)...{}
}
},

sort:function(index,order)...{//order,1:asc,-1:desc

this.rows.sort(function(x,y)...{

if(x.items[index].value > y.items[index].value)...{
return order;

}else...{
return -1 * order;
}
});
this.reBuild();
},

customSort:function(index,formula)...{
this.rows.sort(formula);
this.reBuild();
},

exchange:function(rowA,rowB)...{
var temp = rowA;
this.rows[rowB.getIndex()] = rowA;
this.rows[temp.getIndex()] = rowB;
this.reBuild();
}
}

</
script
>

<
style
>
...

body {...}{font-size:9pt;}

#grid {...}{border:1px solid #cccccc;}

#grid tr td {...}{border:1px solid #cccccc;}

#grid .head {...}{color:#FFFFFF;background-color:#999999;cursor:pointer;text-align:center;}

#test {...}{margin:30px 0 0 0;}

#test input {...}{width:40px;height:15px;border:1px solid #cccccc;margin:0 0 0 3px;}
</
style
>

<
script
type
="text/javascript"
>
...

window.onload = function()...{
var t = new DataGrid(document.getElementById("grid"));

$("b1").onclick = function()...{t.insertRow([$("i1").value,$("i2").value,$("i3").value],$("i4").value);};

$("b2").onclick = function()...{t.deleteRows($("d1").value.split(","));};

$("b3").onclick = function()...{t.exchange(t.rows[$("e1").value],t.rows[$("e2").value]);};

$("b4").onclick = function()...{
var s = t.selectedRows();

for(var i = 0; i < s.length; i ++)...{
s[i].remove();
}
}
var cols = t.cols.dom.getElementsByTagName("td");

for(var i = 1;i < cols.length; i ++)...{

cols[i].onclick = function()...{
var n = 0;
var temp = this;

while(temp.previousSibling)...{
temp = temp.previousSibling;
n ++;
}
var sort = 1;

if(t.cols.sort[this.innerHTML])...{
t.cols.sort[this.innerHTML] = sort = -1 * t.cols.sort[this.innerHTML];

}else...{
t.cols.sort[this.innerHTML] = sort;
}
t.sort(n-1,sort);
};
}
}
</
script
>
</
head
>

<
body
>
<
table
cellpadding
="0"
cellspacing
="2"
id
="grid"
>
<
tbody
>
<
tr
class
="head"
><
td
><
input
type
="checkbox"
/></
td
><
td
>
A
</
td
><
td
>
B
</
td
><
td
>
C
</
td
></
tr
>
<
tr
><
td
><
input
type
="checkbox"
/></
td
><
td
>
22222
</
td
><
td
>
dddd
</
td
><
td
>
22222
</
td
></
tr
>
<
tr
><
td
><
input
type
="checkbox"
/></
td
><
td
>
33333
</
td
><
td
>
cccc
</
td
><
td
>
33333
</
td
></
tr
>
<
tr
><
td
><
input
type
="checkbox"
/></
td
><
td
>
22222
</
td
><
td
>
dddd
</
td
><
td
>
22222
</
td
></
tr
>
<
tr
><
td
><
input
type
="checkbox"
/></
td
><
td
>
33333
</
td
><
td
>
cccc
</
td
><
td
>
33333
</
td
></
tr
>
</
tbody
>
</
table
>
<
div
id
="test"
>
(所有行数从0开始计算)
<
br
/>
编辑:双击单元格进行数据编辑。
<
br
/>
插入行:数据
<
input
type
="text"
id
="i1"
value
="a"
/><
input
type
="text"
id
="i2"
value
="b"
/><
input
type
="text"
id
="i3"
value
="c"
/>
插入位置
<
input
type
="text"
id
="i4"
value
="0"
/><
button
id
="b1"
>
插入
</
button
><
br
/>
删除指定行数据(多行用,隔开)
<
input
type
="text"
id
="d1"
value
="0,1"
/><
button
id
="b2"
>
删除
</
button
><
br
/>
删除选定行
<
button
id
="b4"
>
删除
</
button
><
br
/>
交换:将第
<
input
type
="text"
id
="e1"
value
="0"
/>
行与第
<
input
type
="text"
id
="e2"
value
="1"
/>
行交换
<
button
id
="b3"
>
交换
</
button
><
br
/>
排序:点击标头进行默认排序,提供自定义排序接口
<
br
/>
灵活的编程支持,可扩展性强.(下一步实现:数据绑定,数据提取等)
</
div
>
</
body
>
</
html
>
效果演示地址:http://www.robchen.cn/datagrid/