Easy Grid 最简单的Javascript 表格控件
表格是很常用的html控件之一, 为了使用的方便以及美观, Easy就出现了Easy.Grid ,这个表格简单易用,符号Easy的宗旨。
用户只要会html 、Javascript ,看了Easy.Grid 的Demo 就不使用,并且运用自如。演示地址:http://easy.apphb.com/unit/ui/index.htm
都是程序员就不多说了,看源码(一下常用的方法封装在Easy的核心库里):
Easy.data.Store = function (cfg) {
var me = this;
Easy.apply(me, cfg);
me.callback = function () { };
var pubs = {
start: 0,
load: function (params) {
var pms = Easy.applyIf(params || {}, me.baseParams);
me.start = pms.start;
var mk = new Easy.UI.Mask({
message: '正在加载数据...'
});
mk.show();
me.loader = Easy.Ajax.post({
url: me.url,
params: pms,
callback: function (rsp, cfg) {
try {
if (this.status == 200) {
me.callback();
var json = Easy.decode(rsp);
if (json.exception) {
alert(json.message);
return false;
}
me.processResponse.call(me, rsp);
} else {
me.exception.call(me, rsp, this.statue);
}
} catch (e) {
mk.close();
} finally {
mk.close();
}
}
});
},
on: function (en, fn, scope) {
var me = this;
(scope || me)["on" + Easy.String.toPascal(en)] = Easy.delegate(fn, scope || me, Easy.slice(arguments, 3));
},
fireEvent: function (eventName, scope) {
return (scope["on" + Easy.String.toPascal(eventName)] || Easy.emptyFn).apply(scope, Easy.slice(arguments, 2));
},
processResponse: function (resText, option) {
var o = Easy.decode(resText);
if (o && !o.exception)
me.drawRow(o);
else {
me.exception.call(resText, me.loader.statue);
}
me.fireEvent('load', me);
},
exception: function (resT, state) {
me.fireEvent('exception', me);
}
};
Easy.apply(me, pubs);
return me;
}
Easy.UI.Grid = Easy.extend(Easy.UI.Base, {
url: "/base.ashx",
root: 'Records',
count: "Count",
tpl: "",
noPaging: false,
mutilSelect: false,
model: 'remote',
rows: [],
checkboxs: [],
headerTDs: [],
mutilSelectTip: "你选择了多条数据!",
noSelectTip: "你没有选择要操作的数据!",
constructor: function (cfg) {
var me = this;
Easy.apply(me, cfg);
if (!me.store && me.model === "remote") {
if (me.url) {
me.store = new Easy.data.Store({
url: me.url,
baseParams: Easy.apply({
className: me.className,
methodName: me.methodName || "PageData",
start: 0, limit: me.limit || 17, sort: '', dir: 'desc'
}, me.baseParams)
});
}
}
if (me.store)
me.store.drawRow = Easy.delegate(me.drawRow, me);
Easy.UI.Grid.superclass.constructor.call(this);
},
initComponent: function () {
var me = this;
var tpl = "<table class='e-grid' border='0' cellpadding='0' cellspacing='0'>" +
"<tbody>" +
(Easy.isArray(me.header) ? me.header.join("\n") : me.header) +
"</tbody>" +
"</table><div class='clear'></div>";
var wrap = Easy.get(me.renderTo);
wrap.innerHTML = tpl;
if (wrap.firstChild && Easy.isElement(wrap.firstChild) && wrap.firstChild.tagName == "TABLE")
me.table = wrap.firstChild;
if (me.model === 'remote')
me.store.load();
me.initGrid = true;
me.wrap = wrap;
me.headerTDs = [];
me.clearDiv = me.table.nextSibling;
Easy.each(me.table.firstChild.rows[0].cells, function (td, i) {
var w = Easy.DOM.getStyle(td, "width");
if (Easy.DOM.hasClass(td, "e-row"))
w = 30;
w = w || (td.offsetWidth - 10);
me.headerTDs.push(w);
})
},
drawRow: function (rows) {
var me = this, wrap = Easy.get(me.renderTo);
me.data = {};
me.getCount = function () {
return rows[me.Count];
};
me.tplStr = Easy.isArray(me.tpl) ? me.tpl.join("\n") : me.tpl;
wrap.innerHTML = "";
me.rows = [];
me.checkboxs = [];
var tpl = "<table class='e-grid' border='0' cellpadding='0' cellspacing='0'>" +
"<tbody>" +
(Easy.isArray(me.header) ? me.header.join("\n") : me.header) +
(function () {
var sb = [], tmp, cutIndex = 0, orow = me.root ? rows[me.root] : rows;
Easy.each(orow, function (it) {
me.data[it["FID"]] = it;
tmp = me.tplStr;
var optn = /\{(\w+)\}[.](\w+)/i, m = optn.exec(tmp);
while (m != null) {
tmp = tmp.replace(m[0], it[m[1]][m[2]]);
m = optn.exec(tmp);
}
Easy.each(it, function (v, k) {
v = v == null ? "" : v;
if (Easy.isDate(v)) {
v = Easy.Date.format(v, "yyyy-MM-dd hh:mm");
}
tmp = tmp.replace(new RegExp("{" + k + "}", "g"), v);
});
cutIndex += 1 + (me.model === 'remote' ? me.store.baseParams.start : 0);
if (tmp.indexOf("{fn:") > -1) {
var ptn = /\{fn:(.*)\/fn\}/i, match = ptn.exec(tmp);
while (match != null) {
var fn = match[1];
var rel = (new Function(fn));
tmp = tmp.replace(match[0], rel);
match = ptn.exec(tmp);
}
}
tmp = tmp.replace("{rowIndex}", cutIndex).replace(/\{\w*\}/ig, " ");
sb.push(tmp);
});
return sb.join("");
})() +
"</tbody>" +
"</table><div class='clear'></div>";
wrap.innerHTML = tpl;
if (wrap.firstChild && Easy.isElement(wrap.firstChild) && wrap.firstChild.tagName == "TABLE")
me.table = wrap.firstChild;
me.initEvent.call(me);
if (!me.noPaging) {
var p = new Easy.UI.Pagingbar(Easy.apply(me.pagingbar || {}, {
renderTo: wrap,
data: rows,
pageSize: me.store.baseParams.limit,
start: me.store.baseParams.start,
store: me.store,
width: wrap.scrollWidth || wrap.offsetWidth || "auto"
}));
p.currentPageCtl.value = Math.ceil(me.store.start / me.store.baseParams.limit + 1);
}
me.clearDiv = me.table.nextSibling;
me.wrap = wrap;
me.fireEvent("render", me);
},
on: function (en, fn, scope) {
var me = this;
if (en == "rowdblclick") {
Easy.each(me.rows, function (r, i) {
Easy.DOM.on(r, "dblclick", Easy.delegate(fn, scope || me, [r, i]));
})
}
(scope || me)["on" + Easy.String.toPascal(en)] = Easy.delegate(fn, scope || me, Easy.slice(arguments, 3));
},
onRender: function () {
var me = this, style = {};
if (me.height) {
style.height = Math.max(me.height - me.table.offsetHeight - 75, 0);
}
Easy.DOM.setStyle(me.clearDiv, style);
},
initEvent: function () {
var me = this, tb = me.table.firstChild;
var ths = tb.rows[0].cells, rows = tb.childNodes;
me.checkboxs = [];
for (var i = 0, len = ths.length; i < len; i++) {
var cel = ths[i];
if (cel && cel.sort) {
Easy.DOM.on(cel, "click", Easy.delegate(me.sort, me, [cel.sort, cel]));
if (me.initGrid) {
var sortFlag = Easy.DOM.create({
tag: "span",
cls: 'e-sort-asc'
}, cel);
Easy.DOM.addClass(cel, "e-cansort");
}
}
}
var ck = rows[0].getElementsByTagName("input")[0];
if (ck && ck.type.toLowerCase() === "checkbox") {
// me.checkboxs.push(ck);
Easy.DOM.on(ck, "click", Easy.delegate(me.selectAll, me, [ck]));
}
for (var i = 1, len = rows.length; i < len; i++) {
var r = rows[i];
me.rows.push(r);
var ckb = r.getElementsByTagName("input")[0];
if (ckb && ckb.type.toLowerCase() === "checkbox") {
me.checkboxs.push(ckb)
Easy.DOM.on(ckb, "click", Easy.delegate(me.checkClick, me, [ckb, r]));
}
Easy.DOM.on(r, "mouseover", Easy.delegate(me.toogleClass, me, [r, "e-row-over"]));
Easy.DOM.on(r, "mouseout", Easy.delegate(me.toogleClass, me, [r, "e-row-over"]));
Easy.DOM.on(r, "click", Easy.delegate(me.rowClick, me, [r, i]));
Easy.DOM.on(r, "dblclick", Easy.delegate(me.rowDblClick, me, [r, i]));
Easy.each(r.cells, function (c, colIndex) {
var sp = c.firstChild;
if (sp && sp.tagName.toLowerCase() == "span") {
Easy.DOM.setStyle(sp, {
width: me.headerTDs[colIndex] || "auto"
});
}
Easy.DOM.on(c, "click", Easy.delegate(me.cellClick, me, [c, r, colIndex, i]));
Easy.DOM.on(c, "dblclick", Easy.delegate(me.cellDblClick, me, [c, r, colIndex, i]));
});
}
},
load: function (params) {
this.store.load(params);
},
refresh: function (p) {
this.store.load(p);
},
sort: function (sort, cel) {
var me = this;
me.initGrid = false;
Easy.DOM.toogleClass(cel.lastChild, "e-sort-desc");
var params = { sort: sort, dir: "desc" };
if (Easy.DOM.hasClass(cel.lastChild, "e-sort-desc")) {
params["dir"] = "desc";
} else {
params["dir"] = "asc";
}
me.header = me.table.firstChild.firstChild.outerHTML;
me.load(params);
},
selectAll: function (ck) {
var me = this;
Easy.each(me.checkboxs, function (c, i) {
c.checked = ck.checked;
Easy.DOM[ck.checked ? "addClass" : "removeClass"](me.rows[i], "e-row-select");
});
},
checkClick: function (c, r) {
Easy.DOM.toogleClass(r, "e-row-select");
Easy.Event.stopPropagation(window.event);
this.fireEvent('check', this, r, c);
},
rowClick: function (r, i, cked) {
if (!window.event.ctrlKey && !this.mutilSelect)
Easy.each(this.rows, function (r) {
Easy.DOM.removeClass(r, "e-row-select");
r.cells(0).firstChild.checked = false;
});
Easy.DOM.addClass(r, "e-row-select");
this.rows[i - 1].cells(0).firstChild.checked = cked !== false ? true : cked;
this.fireEvent('click', this, r, i, cked);
},
rowDblClick: function (row, idex) {
this.fireEvent('rowdblclick', this, row, idex);
},
cellClick: function (cell, row, colIndex, rowIndex) {
this.fireEvent('cellclick', this, cell, row, colIndex, rowIndex);
},
cellDblClick: function (cell, row, colIndex, rowIndex) {
this.fireEvent('celldblclick', this, cell, row, colIndex, rowIndex);
},
toogleClass: function (r, cls) {
Easy.DOM.toogleClass(r, cls);
},
getSelection: function () {
var me = this, sel = [];
Easy.each(me.rows, function (r) {
var ck = r.cells(0).firstChild;
if (ck.checked === true) {
sel.push(me.data[ck.value]);
}
});
return sel;
},
getValues: function (key, canempty) {
var me = this, v = [];
var sls = me.getSelection.call(me);
Easy.each(sls, function (s) {
v.push(s[key]);
});
if (v.length == 0 && !canempty) {
alert(me.noSelectTip);
v = false;
}
return v;
},
getValue: function (key, canempty) {
var me = this, v = [];
var sls = me.getSelection.call(me);
if (sls.length == 1) {
return sls[0][key];
} else if (!canempty) {
alert(me[sls.length == 0 ? "noSelectTip" : "mutilSelectTip"]);
return false;
}
}
});
var me = this;
Easy.apply(me, cfg);
me.callback = function () { };
var pubs = {
start: 0,
load: function (params) {
var pms = Easy.applyIf(params || {}, me.baseParams);
me.start = pms.start;
var mk = new Easy.UI.Mask({
message: '正在加载数据...'
});
mk.show();
me.loader = Easy.Ajax.post({
url: me.url,
params: pms,
callback: function (rsp, cfg) {
try {
if (this.status == 200) {
me.callback();
var json = Easy.decode(rsp);
if (json.exception) {
alert(json.message);
return false;
}
me.processResponse.call(me, rsp);
} else {
me.exception.call(me, rsp, this.statue);
}
} catch (e) {
mk.close();
} finally {
mk.close();
}
}
});
},
on: function (en, fn, scope) {
var me = this;
(scope || me)["on" + Easy.String.toPascal(en)] = Easy.delegate(fn, scope || me, Easy.slice(arguments, 3));
},
fireEvent: function (eventName, scope) {
return (scope["on" + Easy.String.toPascal(eventName)] || Easy.emptyFn).apply(scope, Easy.slice(arguments, 2));
},
processResponse: function (resText, option) {
var o = Easy.decode(resText);
if (o && !o.exception)
me.drawRow(o);
else {
me.exception.call(resText, me.loader.statue);
}
me.fireEvent('load', me);
},
exception: function (resT, state) {
me.fireEvent('exception', me);
}
};
Easy.apply(me, pubs);
return me;
}
Easy.UI.Grid = Easy.extend(Easy.UI.Base, {
url: "/base.ashx",
root: 'Records',
count: "Count",
tpl: "",
noPaging: false,
mutilSelect: false,
model: 'remote',
rows: [],
checkboxs: [],
headerTDs: [],
mutilSelectTip: "你选择了多条数据!",
noSelectTip: "你没有选择要操作的数据!",
constructor: function (cfg) {
var me = this;
Easy.apply(me, cfg);
if (!me.store && me.model === "remote") {
if (me.url) {
me.store = new Easy.data.Store({
url: me.url,
baseParams: Easy.apply({
className: me.className,
methodName: me.methodName || "PageData",
start: 0, limit: me.limit || 17, sort: '', dir: 'desc'
}, me.baseParams)
});
}
}
if (me.store)
me.store.drawRow = Easy.delegate(me.drawRow, me);
Easy.UI.Grid.superclass.constructor.call(this);
},
initComponent: function () {
var me = this;
var tpl = "<table class='e-grid' border='0' cellpadding='0' cellspacing='0'>" +
"<tbody>" +
(Easy.isArray(me.header) ? me.header.join("\n") : me.header) +
"</tbody>" +
"</table><div class='clear'></div>";
var wrap = Easy.get(me.renderTo);
wrap.innerHTML = tpl;
if (wrap.firstChild && Easy.isElement(wrap.firstChild) && wrap.firstChild.tagName == "TABLE")
me.table = wrap.firstChild;
if (me.model === 'remote')
me.store.load();
me.initGrid = true;
me.wrap = wrap;
me.headerTDs = [];
me.clearDiv = me.table.nextSibling;
Easy.each(me.table.firstChild.rows[0].cells, function (td, i) {
var w = Easy.DOM.getStyle(td, "width");
if (Easy.DOM.hasClass(td, "e-row"))
w = 30;
w = w || (td.offsetWidth - 10);
me.headerTDs.push(w);
})
},
drawRow: function (rows) {
var me = this, wrap = Easy.get(me.renderTo);
me.data = {};
me.getCount = function () {
return rows[me.Count];
};
me.tplStr = Easy.isArray(me.tpl) ? me.tpl.join("\n") : me.tpl;
wrap.innerHTML = "";
me.rows = [];
me.checkboxs = [];
var tpl = "<table class='e-grid' border='0' cellpadding='0' cellspacing='0'>" +
"<tbody>" +
(Easy.isArray(me.header) ? me.header.join("\n") : me.header) +
(function () {
var sb = [], tmp, cutIndex = 0, orow = me.root ? rows[me.root] : rows;
Easy.each(orow, function (it) {
me.data[it["FID"]] = it;
tmp = me.tplStr;
var optn = /\{(\w+)\}[.](\w+)/i, m = optn.exec(tmp);
while (m != null) {
tmp = tmp.replace(m[0], it[m[1]][m[2]]);
m = optn.exec(tmp);
}
Easy.each(it, function (v, k) {
v = v == null ? "" : v;
if (Easy.isDate(v)) {
v = Easy.Date.format(v, "yyyy-MM-dd hh:mm");
}
tmp = tmp.replace(new RegExp("{" + k + "}", "g"), v);
});
cutIndex += 1 + (me.model === 'remote' ? me.store.baseParams.start : 0);
if (tmp.indexOf("{fn:") > -1) {
var ptn = /\{fn:(.*)\/fn\}/i, match = ptn.exec(tmp);
while (match != null) {
var fn = match[1];
var rel = (new Function(fn));
tmp = tmp.replace(match[0], rel);
match = ptn.exec(tmp);
}
}
tmp = tmp.replace("{rowIndex}", cutIndex).replace(/\{\w*\}/ig, " ");
sb.push(tmp);
});
return sb.join("");
})() +
"</tbody>" +
"</table><div class='clear'></div>";
wrap.innerHTML = tpl;
if (wrap.firstChild && Easy.isElement(wrap.firstChild) && wrap.firstChild.tagName == "TABLE")
me.table = wrap.firstChild;
me.initEvent.call(me);
if (!me.noPaging) {
var p = new Easy.UI.Pagingbar(Easy.apply(me.pagingbar || {}, {
renderTo: wrap,
data: rows,
pageSize: me.store.baseParams.limit,
start: me.store.baseParams.start,
store: me.store,
width: wrap.scrollWidth || wrap.offsetWidth || "auto"
}));
p.currentPageCtl.value = Math.ceil(me.store.start / me.store.baseParams.limit + 1);
}
me.clearDiv = me.table.nextSibling;
me.wrap = wrap;
me.fireEvent("render", me);
},
on: function (en, fn, scope) {
var me = this;
if (en == "rowdblclick") {
Easy.each(me.rows, function (r, i) {
Easy.DOM.on(r, "dblclick", Easy.delegate(fn, scope || me, [r, i]));
})
}
(scope || me)["on" + Easy.String.toPascal(en)] = Easy.delegate(fn, scope || me, Easy.slice(arguments, 3));
},
onRender: function () {
var me = this, style = {};
if (me.height) {
style.height = Math.max(me.height - me.table.offsetHeight - 75, 0);
}
Easy.DOM.setStyle(me.clearDiv, style);
},
initEvent: function () {
var me = this, tb = me.table.firstChild;
var ths = tb.rows[0].cells, rows = tb.childNodes;
me.checkboxs = [];
for (var i = 0, len = ths.length; i < len; i++) {
var cel = ths[i];
if (cel && cel.sort) {
Easy.DOM.on(cel, "click", Easy.delegate(me.sort, me, [cel.sort, cel]));
if (me.initGrid) {
var sortFlag = Easy.DOM.create({
tag: "span",
cls: 'e-sort-asc'
}, cel);
Easy.DOM.addClass(cel, "e-cansort");
}
}
}
var ck = rows[0].getElementsByTagName("input")[0];
if (ck && ck.type.toLowerCase() === "checkbox") {
// me.checkboxs.push(ck);
Easy.DOM.on(ck, "click", Easy.delegate(me.selectAll, me, [ck]));
}
for (var i = 1, len = rows.length; i < len; i++) {
var r = rows[i];
me.rows.push(r);
var ckb = r.getElementsByTagName("input")[0];
if (ckb && ckb.type.toLowerCase() === "checkbox") {
me.checkboxs.push(ckb)
Easy.DOM.on(ckb, "click", Easy.delegate(me.checkClick, me, [ckb, r]));
}
Easy.DOM.on(r, "mouseover", Easy.delegate(me.toogleClass, me, [r, "e-row-over"]));
Easy.DOM.on(r, "mouseout", Easy.delegate(me.toogleClass, me, [r, "e-row-over"]));
Easy.DOM.on(r, "click", Easy.delegate(me.rowClick, me, [r, i]));
Easy.DOM.on(r, "dblclick", Easy.delegate(me.rowDblClick, me, [r, i]));
Easy.each(r.cells, function (c, colIndex) {
var sp = c.firstChild;
if (sp && sp.tagName.toLowerCase() == "span") {
Easy.DOM.setStyle(sp, {
width: me.headerTDs[colIndex] || "auto"
});
}
Easy.DOM.on(c, "click", Easy.delegate(me.cellClick, me, [c, r, colIndex, i]));
Easy.DOM.on(c, "dblclick", Easy.delegate(me.cellDblClick, me, [c, r, colIndex, i]));
});
}
},
load: function (params) {
this.store.load(params);
},
refresh: function (p) {
this.store.load(p);
},
sort: function (sort, cel) {
var me = this;
me.initGrid = false;
Easy.DOM.toogleClass(cel.lastChild, "e-sort-desc");
var params = { sort: sort, dir: "desc" };
if (Easy.DOM.hasClass(cel.lastChild, "e-sort-desc")) {
params["dir"] = "desc";
} else {
params["dir"] = "asc";
}
me.header = me.table.firstChild.firstChild.outerHTML;
me.load(params);
},
selectAll: function (ck) {
var me = this;
Easy.each(me.checkboxs, function (c, i) {
c.checked = ck.checked;
Easy.DOM[ck.checked ? "addClass" : "removeClass"](me.rows[i], "e-row-select");
});
},
checkClick: function (c, r) {
Easy.DOM.toogleClass(r, "e-row-select");
Easy.Event.stopPropagation(window.event);
this.fireEvent('check', this, r, c);
},
rowClick: function (r, i, cked) {
if (!window.event.ctrlKey && !this.mutilSelect)
Easy.each(this.rows, function (r) {
Easy.DOM.removeClass(r, "e-row-select");
r.cells(0).firstChild.checked = false;
});
Easy.DOM.addClass(r, "e-row-select");
this.rows[i - 1].cells(0).firstChild.checked = cked !== false ? true : cked;
this.fireEvent('click', this, r, i, cked);
},
rowDblClick: function (row, idex) {
this.fireEvent('rowdblclick', this, row, idex);
},
cellClick: function (cell, row, colIndex, rowIndex) {
this.fireEvent('cellclick', this, cell, row, colIndex, rowIndex);
},
cellDblClick: function (cell, row, colIndex, rowIndex) {
this.fireEvent('celldblclick', this, cell, row, colIndex, rowIndex);
},
toogleClass: function (r, cls) {
Easy.DOM.toogleClass(r, cls);
},
getSelection: function () {
var me = this, sel = [];
Easy.each(me.rows, function (r) {
var ck = r.cells(0).firstChild;
if (ck.checked === true) {
sel.push(me.data[ck.value]);
}
});
return sel;
},
getValues: function (key, canempty) {
var me = this, v = [];
var sls = me.getSelection.call(me);
Easy.each(sls, function (s) {
v.push(s[key]);
});
if (v.length == 0 && !canempty) {
alert(me.noSelectTip);
v = false;
}
return v;
},
getValue: function (key, canempty) {
var me = this, v = [];
var sls = me.getSelection.call(me);
if (sls.length == 1) {
return sls[0][key];
} else if (!canempty) {
alert(me[sls.length == 0 ? "noSelectTip" : "mutilSelectTip"]);
return false;
}
}
});
看了这么长的源码后, 看看这个grid的到底能出现什么效果呢, 现在看看效果,
效果图如下:
看到效果后我们看看穿件这个grid的代码:
var grid = new Easy.UI.Grid({
id: "roleGrid",
renderTo: 'grid',
baseParams: {
className: "RoleServer",
methodName: "PageData"
},
header: ["<tr class='e-header'>",
"<td class='e-checkbox'><input type='checkbox' /></td>",
"<td style='width:150px;' sort='FName'><span>名 称</span></td>",
"<td style='width:200px;' sort='FOrgID'><span>所属组织</span></td>",
"<td style='width:150px;' sort='FSort'><span>排 序</span></td>",
"<td><span>说明</span></td>",
"</tr>"],
tpl: ["<tr>",
"<td><input type='checkbox' value='{FID}' /></td>",
"<td><span>{FName}</span></td>",
"<td><span>{OrgName}</span></td>",
"<td><span style='width:100px;'>{FSort}</span></td>",
"<td><span>{FRemark}</span></td>",
"</tr>"]
});
id: "roleGrid",
renderTo: 'grid',
baseParams: {
className: "RoleServer",
methodName: "PageData"
},
header: ["<tr class='e-header'>",
"<td class='e-checkbox'><input type='checkbox' /></td>",
"<td style='width:150px;' sort='FName'><span>名 称</span></td>",
"<td style='width:200px;' sort='FOrgID'><span>所属组织</span></td>",
"<td style='width:150px;' sort='FSort'><span>排 序</span></td>",
"<td><span>说明</span></td>",
"</tr>"],
tpl: ["<tr>",
"<td><input type='checkbox' value='{FID}' /></td>",
"<td><span>{FName}</span></td>",
"<td><span>{OrgName}</span></td>",
"<td><span style='width:100px;'>{FSort}</span></td>",
"<td><span>{FRemark}</span></td>",
"</tr>"]
});
穿件这个grid的代码仅此而已, 效果还可以的吧 !