前言:SlickGrid 是一个Javascript编写的数据控件,其采用数据虚拟显示的特性备受后来的Grid推崇,如ExtJS DataGrid,其架构设计优秀,UI交互功能非常丰富,插件化的可扩展功能开发非常值得Web开发人员学习,本文列出基本方法的使用,供开发人员参考;并在后文继续总结列出已经开发出的插件,以供开发人员参考。
0. SlickGrid 基本样式示例
功能包括:
1)首列复选框;
2)编辑器:文本编辑框,下拉框,复选框,日期控件,长文本编辑器,数字格式编辑器,YesNo编辑器等;
3)列排序,列字段值过滤,列冻结;
4)分页:客户端分页和服务端分页;
5)多字段组合查询;
6)各种列样式指定,行样式设定;
其它扩展功能依然可以通过插件完成。
1. Grid初始化及数据绑定 new、setItems、setSelectionModel
var gridView;
var grid;
var data = [];
var columns = [
{ id: "id", name: "id", field: "id", behavior: "select" },
{ id: "code", name: "入库单编号", field: "code"},
{ id: "ctemp1", name: "明细款号", field: "ctemp1" }
];
var options = {
editable: true,
enableCellNavigation: true,
enableColumnReorder: true,
asyncEditorLoading: true,
forceFitColumns: false,
topPanelHeight: 25
};
ajaxPost('/Stk/StkInm/StkInmSearch/' + id,
JSON.stringify(id),
function (result) {
data = result;
gridView = new Slick.Data.DataView({ inlineFilters: true });
grid = new Slick.Grid("#GridSearch", data, columns, options);
gridView.setItems(data, "id");
grid.setSelectionModel(new Slick.RowSelectionModel());
}
var visibleColumns = [];//定义一个数组存放显示的列
for (var i = 0; i < columns.length; i++) {
if (i!=0)
visibleColumns.push(Columns[i]);//将columns的列push进去
}
grid.setColumns(visibleColumns);
var columnpicker = new Slick.Controls.ColumnPicker(columnsSearch, gridSearch, options);
grid.setColumns(visibleColumns);
//分页事件
var onDataPagedEvent = function (e, args) {
var pageNum = args.pageNum;
var pageSize = args.pageSize;
loadGridPaged(pageNum, pageSize, $('#TB_Search').val());
};
//分页数据获取方法封装
function loadGridPaged(pageNum, pageSize,txt) {
var pagetxt = {
searchtxt: txt,
pageNum: pageNum,
pageSize: pageSize
}
ajaxPost('/Stk/StkInm/StkInmSearch/' + pagetxt,
JSON.stringify(pagetxt),
function (result) {
data = result.t;
var rowCount = result.s;
var pageCount = Math.ceil(rowCount / pageSize);
var pageInfo = {};
pageInfo.pageNum = pageNum;
pageInfo.pageSize = pageSize;
pageInfo.totalRowsCount = rowCount;
pageInfo.totalPagesCount = pageCount;
gridView = new Slick.Data.DataView({ inlineFilters: true });
grid = new Slick.Grid("#GridSearch", Data, Columns, Options);
gridView.setItems(data, "id");
grid.setSelectionModel(new Slick.RowSelectionModel());
//注册分页控件
var pager = new Slick.Controls.PagerSvr(gridView, grid, PageInfo, $("#pagergrid"));
pager.onDataPaged.subscribe(onDataPagedEvent);
});
}
grid.onClick.subscribe(function (e, args) {
//单击事件发生的处理逻辑
});
grid.onDblClick.subscribe(function (e, args) {
//双击事件发生的处理逻辑
});
//未用DataView编辑单元格数据
gridProduct.onCellChange.subscribe(function (e, args) {
gridProduct.invalidateRow(args.row);
dsProduct[args.row]["Notes"] = dsProduct[args.row]["Notes"] + "new string added.";
gridProduct.render();
});
//DataView编辑单元格数据
gridProduct.onCellChange.subscribe(function (e, args) {
var item = args.item;
item.Notes = item.Notes += " new sring added.";
changedItemsProduct.push(item);
dataViewProduct.updateItem(item.ID, item);
grid.render();
}
//默认单元格描色
var attachdColumns = [
{ id: "ID", name: "ID", field: "ID", behavior: "select", cssClass: "readonlycss",formatter: ztcolFormat },
{ id: "attid", name: "attid", field: "attid", cssClass: "readonlycss" },
{ id: "att_name", name: "文件名", field: "att_name" },
{ id: "att_path", name: "路径", field: "att_path" },
{ id: "txt", name: "主题", field: "txt"},
{ id: "att_remarks", name: "内容", field: "att_remarks" }
];
var colarry = [];
function ztcolFormat(row, cell, value, columnDef, dataContext) {
if (dataContext.txt != "") {
colarry.push(row);
}
//须return,否则无数据显示
return value;
}
for (var i = 0; i < colarry.length; i++) {
hash[colarry[i]] = {};
hash[colarry[i]]["attid"] = "changed2";
}
//给第四行描色
for (var i = 0; i < attachdColumns.length; i++) {
hash[3][attachdColumns[i].id] = "changed";
}
gridattachd.setCellCssStyles("hightlight", hash);
function getSelectedDataItem() {
if (!selectionModel) {
throw "Selection model is not set";
}
return getDataItem(selectedRows[0]);
}
function getSelectedDataItems() {
if (!selectionModel) {
throw "Selection model is not set";
}
var items = selectedRows.map(function (x) {
return getDataItem(x);
});
return items;
}
调用示例:
var row = grid.getSelectedDataItem();
及
var rows = grid.getSelectedDataItems();
//单元格值改变事件
gridBom.onCellChange.subscribe(function (e, args) {
var index = args.row;
var item = gridViewBom.getItemByIdx(index);
item.pyardcw = item.pyard * item.wear;
//gridViewBom.updateItem(args.item.ID, item);
gridBom.updateRow(args.row);
if (editData.length > 0) {
var live = false;
for (var i = 0; i < editData.length; i++) {
if (editData[i].ID == args.item.ID) {
editData[i] = item;
live = true;
}
}
if (live == false) {
editData.push(item);
}
}
else { editData.push(item); }
});
//选中行改变事件
gridBom.onSelectedRowsChanged.subscribe(function (e, args) {
var item = gridViewBom.getItemByIdx(selectedRowIndex);
//添加状态码下拉框
var selectDom = "";
args.grid.$selDropdownlistDatasource = $(selectDom);
}
});
args.grid.onTextButtonClick = function (arg) {
//e.stopPropagation();
var strValue = 'hello world';
alert("打开新窗口页面,包含要选取的数据列表!");
arg.textContent = strValue;
};
});
//合并成本项目
var xm = "a";
function groupFormatter(row, cell, value, columnDef, dataContext) {
if (dataContext.fsttxt == xm) {
if (value != "")
columnDef.cssClass = "noneLine";
return "";
}
else {
xm = dataContext.fsttxt;
return value;
}
}
var pstItem = { id: "", stkid: "", stktxt: "", stkp: "", memo: "" };
//添加
function addPst() {
if (stkid <= 0)
return;
pstItem.stkid = stkid;
pstItem.stktxt = stkItm.txt;
Datapst.push(pstItem);
gridpst.updateRowCount();
gridpst.render();
}
//复制行
function copyRow(result, selectedRowIndex) {
var item = gridViewBom.getItemByIdx(selectedRowIndex);
//gridBom.invalidateRow(result.length);
item.ID = "";
result.push(item);
gridBom.updateRowCount();
gridBom.render();
}
//删除
function delPst() {
if (confirm("确定删除明细吗?")) {
if (pstid == undefined || pstid == null || pstid == "" || pstid <= 0) {
}
else {
ajaxPost('/Stk/StkMain/DelPst/' + pstid,
JSON.stringify(pstid),
function (result) {
alert("删除成功!");
});
}
datapst.splice(pstsIndex, 1);
gridpst.invalidateRow(pstsIndex);
gridpst.updateRowCount();
gridpst.render();
}
}
//离开提示保存
function leaveSave() {
if (editData.length!=0) {
if (confirm("尚未保存明细,是否保存?")) {
save();
alert("保存成功!")
}
else {
editData = [];
}
}
}
//保存样式到cookie
function saveGridStyle() {
newColumns = gridBom.getColumns();
for (var i = 0; i < newColumns.length; i++) {
if (newColumns[i].editor != undefined) {
newColumns[i].editor = getDomStyle(newColumns[i].editor.toString());
}
}
//BomColumns = newColumns;
ajaxPost('/WebFramework/Sampric/SaveGridBomStyle/',
JSON.stringify(newColumns),
function (result) {
if (result != null) {
//获取存在cookie的样式
//var gridStyle = JSON.parse(JSON.parse(result).gridBom);
alert("ok");
getBomStyle();
bindBom(searchItem.ID);
}
});
}
//取样式
function getBomStyle() {
ajaxPost('/WebFramework/Sampric/GetBomStyle/',
'',
function (result) {
if (result != false) {
//获取存在cookie的样式
var gridStyle = JSON.parse(JSON.parse(result).gridBom);
newColumns = gridStyle;
}
});
}
//清除cookie样式
function coverGrid() {
ajaxPost('/WebFramework/Sampric/ClearGridStyle/',
'',
function (result) {
if (result != null) {
newColumns = [];
alert("恢复成功!");
getBomStyle();
bindBom(searchItem.ID);
}
});
}
//gridBom右键菜单
$("#gridBom").contextMenu('myMenu', {
bindings: {
'savestyle': saveGridStyle,
'clearstyle': coverGrid
}
});
//默认选中第一行
var attachrows = [];
var attachitem;
if (attachData.length > 0) {
attachrows.push([0]);
gridattach.setSelectedRows(attachrows);
attachitem = gridViewattach.getItemByIdx(0);
//附件从表
bindGridAttachd(attachitem.ID);
}
else
$('#gridattachd').empty();
Ps:多行选择,界面多行合计,列拖动直接删除列(样式)
//是否可编辑行的验证
gridProduct.onBeforeEditCell.subscribe(function (e, args) {
//此处列出行属性,同样也可以获取列属性,从而定位单元格
if (args.row === 4) {
return false;
}
});
var columnsProduct = [
{ id: "ID", name: "产品编号", field: "ID", fieldType: "number", width: 100, cssClass: "cell-title" },
{ id: "ProductName", name: "产品名称", field: "ProductName", fieldType: "string", width: 120, hasFilter: true, editor: Slick.Editors.TextButton },
{ id: "UnitPrice", name: "单价", field: "UnitPrice", fieldType: "number", hasFilter: true, editor: Slick.Editors.Text }
];
gridProduct = new Slick.Grid("#myGridProduct", dataViewProduct, columnsProduct, optionsProduct);
.slick-row.redrowextra {
color:red;
font-size:18px;
font-style: italic;
font-weight: bold;
}
.slick-row.redrowreadonly {
color:peru;
font-size:18px;
font-style: italic;
font-weight: bold;
}
dataViewProduct.getItemMetadata = function (row) {
if (row % 2 === 1) {
return {
'cssClasses': 'redrowextra'
};
} else {
return {
'cssClasses': ' redrowreadonly'
};
}
}
//先根据列数值,定义列样式:
var numberFormatter = function (row, cell, value, columnDef, dataContext) {
try {
if (value < 100)
return '' + value + '';
else if (value >= 5000)
return '' + value + '';
else
return '' + value + '';
} catch (e) {
return '';
}
}
//然后在列定义数组中,指定formatter属性;下面的例子是为”UnitPrice”列指定数字格式的样式,根据数字范围进行数据的颜色标识,对于业务人员处理数字类型的操作时,比较有用。
var columnsProduct = [
{ id: "ID", name: "产品编号", field: "ID", fieldType: "number", width: 100, cssClass: "cell-title" },
{ id: "ProductName", name: "产品名称", field: "ProductName", fieldType: "string", width: 120, hasFilter: true, editor: Slick.Editors.TextButton },
{ id: "UnitPrice", name: "单价", field: "UnitPrice", fieldType: "number", hasFilter: true, editor: Slick.Editors.Text, formatter: numberFormatter }
]
SlickGrid 源代码网站:
https://github.com/mleibman/SlickGrid