一,引言
工作的需要,做了3年的wpf(mvvm)……,又因为项目的需求,回归到web的开发。
- 3 years ago,vue是我三年前没用过的玩意儿。
- 3 years ago,bootstrap组件没现在成熟。
- 3 years ago,font awesome的普及度没有现在高。
- 3 years ago,ui组件的选择也没有现在多。
二,项目的前端(easyui模板订制)
整个项目采用了oracle + dapper + castle + mvc + easyui的技术结合,本篇博客重点介绍easyui。
easyui的默认风格看久了很容易产生视觉疲劳,在这个项目中,我个性化订制风格。
订制easyui模板的工作量是挺大的,我用了一个偷懒的方法,花了几百块钱在网上买了几个easyui的皮肤,然后对这些皮肤,进行优化和重构。
money比较紧的同学,可以去下载easyui的免费皮肤。
三,easyui-datagrid的基本使用:
1,加载数据
a,通过post,url的方法向后端请求数据,如图所示:
$('#List').datagrid({ title: "交易公司", loadMsg: '@CommonResource.Processing', toolbar: '#tb', width: "100%", height: "100%", //idField:"ID", //data: getData(), url: "@Url.Action("GetList")", methord: 'post', rownumbers: true, autoRowHeight: false, fit: true, //fitColumns: true, striped: true, //奇偶行 singleSelect: true,//单选模式 checkOnSelect: false, selectOnCheck: false, collapsible: true, pagination: true, pageNumber: 1, pageSize: 10, pageList: [10, 20], queryParams: { }, columns: [[ { field: 'Company_Name', title: '公司名称', width: 100, sortable: false }, { field: 'Abbreviation', title: '简称', width: 100, sortable: false }, { field: 'Business_Address', title: '经营地址', width: 100, sortable: false }, { field: 'Registered_Address', title: '注册地址', width: 100, sortable: false }, { field: 'Tel', title: '电话', width: 100, sortable: false }, { field: 'Fax', title: '传真', width: 100, sortable: false }, { field: 'Contactor', title: '联系人', width: 100, sortable: false }, { field: 'Payment', title: '结算方式', width: 100, sortable: false }, { field: 'Beneficiary_Name', title: '开户名称', width: 100, sortable: false }, { field: 'Beneficiary_Address', title: '开户地址', width: 100, sortable: false }, { field: 'Advising_Bank', title: '通知行', width: 100, sortable: false }, { field: 'Bank_Address', title: '银行地址', width: 100, sortable: false }, { field: 'Swift_Code', title: '银行代码', width: 100, sortable: false }, { field: 'Beneficiary_Account', title: '银行账户', width: 100, sortable: false }, { field: 'Company_Chop', title: '电子章', width: 100, sortable: false }, { field: 'Send_Url', title: '发件邮箱链接', width: 100, sortable: false }, { field: 'Send_Email', title: '发件人邮箱', width: 100, sortable: false }, { field: 'Remark', title: '备注', width: 100, sortable: false }, { field: 'Created_By', title: '创建人', width: 100, sortable: false }, { field: 'Creation_Date', title: '创建日期', width: 100, sortable: false }, { field: 'Modify_By', title: '修改人', width: 100, sortable: false }, { field: 'Modify_Date', title: '修改日期', width: 100, sortable: false }, ]], }); });
b,先定义好了datagrid的属性以及列,再通过loadData的方法设置datagrid的数据
$('#Detail').datagrid({ loadMsg: '@CommonResource.Processing', toolbar: '#tb', width: "100%", height: "100%", //data: [], rownumbers: true, autoRowHeight: false, fit: true, fitColumns: true, striped: true, singleSelect: true, collapsible: false, pagination: false, queryParams: { }, columns: [[ { field: 'Country_Name', title: '国家名称', width: 100, sortable: false }, { field: 'Item_Number', title: '物料编码', width: 100, sortable: false }, ]], });
var returnData = JSON.parse(response.data); $('#Detail').datagrid("loadData", returnData);
2,合并单元格
有时候用户需要如下图的效果
可以在datagrid的onLoadSuccess事件里增加如下代码:
onLoadSuccess: function (data) { //var opts = $('#List').datagrid('getColumnFields'); var opts = new Array("Item_Number", "Country_Name", "Item_Desc", "Item_Desc_En", "Item_Type", "Unit", "Hs_Code", "Destination_Code", "Status", "Remark", "Create_User", "Create_Date"); var rowsCount = data.rows.length; var mark = 1; for (var j = 1; j < rowsCount; j++) { var preCellVal = data.rows[j - 1]["Material_Id"]; var currentCellVal = data.rows[j]["Material_Id"]; if (preCellVal == currentCellVal) { mark += 1; for (var c = 0; c < opts.length; c++) { var columnName = opts[c]; $(this).datagrid('mergeCells', { field: columnName, index: j + 1 - mark, rowspan: mark }); } } else { mark = 1; } } },
3,行,列变色
针对这样的行,列变色效果:
a,行变色
$('#Detail').datagrid({ loadMsg: '@CommonResource.Processing', toolbar: '#tb', width: "100%", height: "100%", url: "@Url.Action("GetLines")", methord: 'post', rownumbers: true, autoRowHeight: false, fit: true, fitColumns: true, striped: true, singleSelect: true, collapsible: false, pagination: false, queryParams: { hid: $("#Hid").val() }, columns: [[ { field: 'Material_No', title: '物料号', width: 100, sortable: false }, { field: 'Description', title: '中文描述', width: 100, sortable: false }, { field: 'En_Description', title: '英文描述', width: 100, sortable: false }, { field: 'Unit', title: '单位', width: 100, sortable: false }, { field: 'Quantity', title: '工单数量', width: 100, sortable: false }, { field: 'Total_Actual_Send_Quantity', title: '已出货数量', width: 100, sortable: false }, { field: 'Remark', title: '备注', width: 100, sortable: false }, ]], rowStyler: function (index, row) { if (row.Quantity == 0) { return 'background-color:pink;color:blue;font-weight:bold;'; } }, });
b,列变色
$('#Detail').datagrid({ loadMsg: '@CommonResource.Processing', width: "100%", height: "100%", data: [], rownumbers: true, autoRowHeight: false, fit: true, fitColumns: true, striped: true, singleSelect: true, checkOnSelect: false, selectOnCheck: false, collapsible: false, pagination: false, queryParams: {}, columns: [[ { field: 'sel', checkbox: true }, { field: 'Material_No', title: '物料号', width: 80, sortable: false }, { field: 'Description', title: '中文描述', width: 80, sortable: false }, { field: 'Unit', title: '单位', width: 80, sortable: false }, { field: 'Quantity', title: '工单数量', width: 80, sortable: false }, { field: 'Total_Actual_Send_Quantity', title: '已出货数量', width: 80, sortable: false }, { field: 'Remain_Quantity', title: '剩余数量', width: 80, sortable: false }, { field: 'Actual_Send_Quantity', title: '本次出货', width: 80, sortable: false, editor: { type: 'numberbox', options: { required: true, min: 0 }, }, styler: function (value, row, index) { return 'background-color:#ecffff;'; }, }, { field: 'Remark', title: '备注', width: 80, sortable: false, editor: { type: 'textbox', options: { validType: 'length[1,20]' }, }, styler: function (value, row, index) { return 'background-color:#ecffff;'; }, }, ]],
4,为datagrid添加工具条
如下效果的工具条,是通过datagrid的 toolbar 属性来指定,要留意的是toolbar的控件名称需要加上#符号。
html代码:
<div id="tb"> <a id='condition' href='#' class='btn btn-default more'><i class='fa fa-ellipsis-v'></i> 查询条件</a> @Html.ToolButton(string.Format(@"<a id='btnCreate' href='#' class='btn btn-default'><i class='fa fa-plus'></i> {0}</a>", @CommonResource.Add), ActionCode.Create) @Html.ToolButton(string.Format(@"<a id='btnEdit' href='#' class='btn btn-default'><i class='fa fa-pencil'></i> {0}</a>", @CommonResource.Edit), ActionCode.Edit) @Html.ToolButton(string.Format(@"<a id='btnDelete' data-content='Delete 1' href='#' class='btn btn-primary'><i class='fa fa-trash'></i> {0}</a>", @CommonResource.Delete), ActionCode.Delete) </div>
js代码:
5,做增,删,改操作
a,为datagrid增加一行
function addCallBack(data) { $('#List').datagrid('insertRow', { index: 0, row: data, }); layer.msg('@CommonResource.AddSuccess', { icon: 1, time: 1000 }); }
b,为datagrid编辑一行
function editCallBack(data) { var selectData = $('#List').datagrid('getSelected'); var selectIndex = $('#List').datagrid('getRowIndex', selectData); $('#List').datagrid('updateRow', { index: selectIndex, row: data, }); layer.msg('@CommonResource.ModifySuccess', { icon: 1, time: 1000 }); }
c,为datagrid删除一行
$("#btnLineDelete").click(function () { var row = $('#Detail').treegrid('getSelected'); if (row != null) { var rowIndex = $('#Detail').datagrid('getRowIndex', row); $('#Detail').datagrid('deleteRow', rowIndex); layer.msg('@CommonResource.DeleteSuccess', { icon: 1, time: 1000 }); } else { layer.msg('@CommonResource.Noselectedrecord', { icon: 2, time: 1000 }); } });
d,treegrid的操作方法略有区别,附上源码:
function addCallBack(data) { var row = $('#List').treegrid('getSelected'); $('#List').treegrid('append', { parent: data.Parent_Id, data: [{ Id: data.Id, Name: data.Name, En_Name:data.En_Name, Code: data.Code, Enable: data.Enable, Sort: data.Sort, }] }); layer.msg('@CommonResource.AddSuccess', { icon: 1, time: 1000 }); } function editCallBack(data) { var row = $('#List').treegrid('getSelected'); $('#List').treegrid('update', { id: row.Id, row: { Name: data.Name, En_Name: data.En_Name, Code: data.Code, Enable: data.Enable, Sort: data.Sort, } }); layer.msg('@CommonResource.ModifySuccess', { icon: 1, time: 1000 }); } $("#btnDelete").click(function () { var row = $('#List').treegrid('getSelected'); if (row != null) { layer.confirm('@CommonResource.ConfirmDelete', { btn: ['@CommonResource.Sure', '@CommonResource.Cancel'], shadeClose: true, }, function () { if (row.ChildCount == 0 || typeof (row.ChildCount) == 'undefined') { $.post("@Url.Action("Delete")/" + row.Id, function (data) { if (data == "1") { $("#List").treegrid('remove', row.Id); layer.msg('@CommonResource.DeleteSuccess', { icon: 1, time: 1000 }); } else { layer.msg('@CommonResource.DeleteFailed', { icon: 2, time: 1000 }); } }, "json"); } else { layer.msg('@CommonResource.Noselectedrecord', { icon: 2, time: 1000 }); } }, function () { }); } else { layer.msg('@CommonResource.Noselectedrecord', { icon: 2, time: 1000 }); } });
6,编辑单元格
具体代码实现
var taxTypeList = JSON.parse($("#taxTypeList").val()); var manufactureList = JSON.parse($("#manufactureList").val()); $.extend($.fn.datagrid.methods, { editCell: function (jq, param) { return jq.each(function () { var opts = $(this).datagrid('options'); var fields = $(this).datagrid('getColumnFields', true).concat($(this).datagrid('getColumnFields')); for (var i = 0; i < fields.length; i++) { var col = $(this).datagrid('getColumnOption', fields[i]); col.editor1 = col.editor; if (fields[i] != param.field) { col.editor = null; } } $(this).datagrid('beginEdit', param.index); for (var i = 0; i < fields.length; i++) { var col = $(this).datagrid('getColumnOption', fields[i]); col.editor = col.editor1; } }); } }); var editIndex = -1; function endEditCal() { if (editIndex == -1) { return true; } if ($('#Detail').datagrid('validateRow', editIndex)) { $('#Detail').datagrid('endEdit', editIndex); editIndex = -1; return true; } else { return false; } } $('#Detail').datagrid({ loadMsg: '@CommonResource.Processing', toolbar: '#tb', width: "100%", height: "100%", data: JSON.parse($("#MaterialDetailListStr").val()), rownumbers: true, autoRowHeight: false, fit: true, fitColumns: true, striped: true, singleSelect: true, collapsible: false, pagination: false, queryParams: { }, columns: [[ { field: 'Material_Use', title: '用途', width: 100, sortable: false, formatter: function (value) { for (var i = 0; i < manufactureList.length; i++) { if (manufactureList[i].Key == value) return manufactureList[i].Value; } return value; }, editor: { type: 'combobox', options: { valueField: 'Key', textField: 'Value', data: manufactureList, required: true, panelHeight: "auto", editable:false, } }, }, { field: 'Tax_Type', title: '税别', width: 100, sortable: false, formatter: function (value) { for (var i = 0; i < taxTypeList.length; i++) { if (taxTypeList[i].Key == value) return taxTypeList[i].Value; } return value; }, editor: { type: 'combobox', options: { valueField: 'Key', textField: 'Value', data: taxTypeList, required: true, panelHeight: "auto", editable: false, } }, }, { field: 'Tax_Bcd', title: 'BCD', width: 100, sortable: false, editor: { type: 'numberbox', options: { required: true, suffix: '%', precision: 2, min: 0, max: 100, } } }, { field: 'Tax_Cess', title: 'CESS', width: 100, sortable: false, editor: { type: 'numberbox', options: { required: true, suffix: '%', precision: 2, min: 0, max: 100, } } }, { field: 'Tax_Igst', title: 'IGST', width: 100, sortable: false, editor: { type: 'numberbox', options: { required: true, suffix: '%', precision: 2, min: 0, max: 100, } } }, ]], @if (Request.Params["Operate"] != "View") { <text> onClickCell: function (index, field, value) { if (endEditCal()) { $(this).datagrid('selectRow', index).datagrid('editCell', { index: index, field: field }); //编辑一个单元格 //$(this).datagrid('beginEdit', index); //编辑一行 editIndex = index; } else { layer.msg('当前行的数据编辑有误', { icon: 2, time: 1000 }); } }, onAfterEdit: function (index, row, changes) { var rowData = $(this).datagrid('getData').rows[index]; $('#Detail').datagrid('updateRow', { index: index, row: {}, }); }, onLoadSuccess: function (data) { for (var index = 0; index < data.rows.length; index++) { $(this).datagrid('beginEdit', index); } }, </text> } }); $("#btnLineCreate").click(function () { if (endEditCal()) { editIndex = 0; $('#Detail').datagrid('insertRow', { index: editIndex, row: {}, }); $('#Detail').datagrid('selectRow', editIndex); $('#Detail').datagrid('beginEdit', editIndex); } else { layer.msg('当前行的数据编辑有误', { icon: 2, time: 1000 }); } }); $("#btnLineDelete").click(function () { var row = $('#Detail').treegrid('getSelected'); if (row != null) { var rowIndex = $('#Detail').datagrid('getRowIndex', row); $('#Detail').datagrid('deleteRow', rowIndex); layer.msg('@CommonResource.DeleteSuccess', { icon: 1, time: 1000 }); } else { layer.msg('@CommonResource.Noselectedrecord', { icon: 2, time: 1000 }); } }); $("#btnSave").click(function () { var summaryValidate = true; var rows = $("#Detail").datagrid("getRows"); $(rows).each(function (index, itemData) { if ($('#Detail').datagrid('validateRow', index)) { $('#Detail').datagrid('endEdit', index); } else { summaryValidate = false; return false; } }); if (summaryValidate) { if (rows.length == 2) { $("#MaterialDetailListStr").val(JSON.stringify(rows)); } else { layer.msg('税别,用途应该设置为2行数据', { icon: 2, time: 1000 }); return false; } } else { layer.msg('当前表单数据编辑有误', { icon: 2, time: 1000 }); return false; } var check = $('form').form('validate'); if (check) { $.ajax({ url: "@Url.Action("CreateMaterial")", type: "Post", data: $("form").serialize(), dataType: "json", success: function (data) { if (data.Key == "1") { parent.$("#List").datagrid('reload'); var index = parent.layer.getFrameIndex(window.name); parent.layer.close(index); parent.layer.msg('@CommonResource.AddSuccess', { icon: 1, time: 1000 }); } else { layer.msg("物料编号'" + data.Value.Item_Number + "'在数据库中已添加", { icon: 2, time: 1000 }); } }, error: function (jqXHR, textStatus, errorThrown) { layer.msg('@CommonResource.AddFailed', { icon: 2, time: 1000 }); } }); } });
7,重置datagrid布局 $('#List').datagrid("resize");
$(function () { $(".more").click(function () { $(this).closest(".conditions").siblings().toggleClass("hide"); $('#List').datagrid("resize"); }); })
四,总结
这些技巧,在帮助文档里也说的很详细,我只是把这些技术用于实践。希望对大家的学习有所帮助,也希望大家多多支持。
easyui,datagrid
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。