demo访问地址:http://106.14.139.196/SaleManage/Index 

本篇文章将与大家分享bootstrap-table插件,借助于它实现基本的增删改查,导入导出,分页,父子表等。

至于其他技术,如冻结表头,列排列,行拖动,列拖动等,会在后续文章中与大家分享。

一   效果图

(一)页面初始化

下图是页面首次加载结束后的效果,主要完成以下功能:

1.日期部分,开始时间:当前月第一天对应的8位日期,结束时间:当前月最后一天对应的8位日期,时间格式为:yyyy-mm-dd

2.bootstrap-table加载的数据为日期部分所对应的时间,且按照时间递减展示

(二)查询

1.支持日期查询和订单编号查询

2.当日期和订单编号都存在时,忽略日期条件(因为订单编号是唯一的)

如下为查询结果:

(三)添加

1.利用dialog模态框加载AddForm页面;

2.实现可拖拽

(四)编辑

1.利用dialog模态框加载EditForm页面

2.根据订单编号选择编辑

(五)删除

1.选中删除

(六)导入

1.下载导入模板

2.按照模板格式导入数据

(七)导出

1.选中导出

2.导出支持多种格式

(八)父子表

1.订单表作为父表,产品表作为子表

2.父表和字表通过产品编号来关联

二   Bootstrap-table讲解

关于bootstrap-table参数,需要掌握如下几大类:表格参数,列参数,事件,方法和多语言,

详情可以参考bootstrap-table官网:http://bootstrap-table.wenzhixin.net.cn/zh-cn/documentation/

三  本Demo技术讲解

(一)Demo架构图

本Demo采用UI+BLL+DAL+Model三层架构。

(二)核心代码

1.Bootstrap-table JS结构定义

 //初始化
var InitTable = function (url) {
//先销毁表格
$('#tb_SaleOrder').bootstrapTable("destroy");
//加载表格
$('#tb_SaleOrder').bootstrapTable({
rowStyle: function (row, index) {//row 表示行数据,object,index为行索引,从0开始
var style = "";
if (row.SignInTime == '' || row.SignOutTime=='') {
style = { css: { 'color': 'red' } };
}
return style;
},
//searchAlign: 'left',
//search: true, //显示隐藏搜索框
showHeader: true, //是否显示列头
//classes: 'table-no-bordered',
showLoading: true,
undefinedText: '',
showFullscreen: true,
toolbarAlign: 'left',
paginationHAlign: 'right',
silent: true,
url: url,
method: 'get', //请求方式(*)
toolbar: '#toolbar', //工具按钮用哪个容器
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, //是否显示分页(*)
sortable: false, //是否启用排序
sortOrder: "asc", //排序方式
//queryParams: InitTable.queryParams, //传递参数(*)
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
pageNumber: 1, //初始化加载第一页,默认第一页
pageSize: 10, //每页的记录行数(*)
pageList: [2, 5, 10, 15], //可供选择的每页的行数(*)
search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
strictSearch: true,
showColumns: true, //是否显示所有的列
showRefresh: true, //是否显示刷新按钮
minimumCountColumns: 2, //最少允许的列数
clickToSelect: true, //是否启用点击选中行
//height: 680, //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度
uniqueId: "ID", //每一行的唯一标识,一般为主键列
showToggle: true, //是否显示详细视图和列表视图的切换按钮
cardView: false, //是否显示详细视图
detailView: false, //是否显示父子表
showExport: true,
//exportDataType: 'all',
exportDataType: "selected", //导出checkbox选中的行数
paginationLoop: false, //是否无限循环
columns: [{
checkbox: true
}, {
field: 'OrderNO',
title: '订单编号'
}, {
field: 'ProductNo',
title: '产品编号'
}, {
field: 'CustName',
title: '客户姓名'
}, {
field: 'CustAddress',
title: '客户地址',
}, {
field: 'CustPhone',
title: '客户电话',
}, {
field: 'CustCompany',
title: '客户公司',
}, {
field: 'CreateDateTime',
title: '订单创建时间',
}, {
field: 'UpdateDateTime',
title: '订单更新时间',
}]
});
return InitTable;
};

2.订单表增删改查

 $(function () {
//初始时间控件
var frstDayDate = GetLocalMonFrstDayDate();
var lastDayDate = GetLocalMonLastDayDate();
$("#startDate").val(frstDayDate);
$("#endDate").val(lastDayDate); //初始化bootstrap-table参数
var filterParam = "";
var startDate = $("#startDate").val();
var endDate = $("#endDate").val();
url = "/SaleManage/GetOrderList?startDate=" + startDate + "&endDate=" + endDate + "&orderNO=" + filterParam + "";
InitTable(url); //查询数据
$("#btn_query").click(function () {
var filterParam = $("#queryKey").val();
var startDate = $("#startDate").val();
var endDate = $("#endDate").val();
var url = "/SaleManage/GetOrderList?startDate="+ startDate + "&endDate=" +endDate + "&orderNO=" + filterParam + "";
InitTable(url);
}) //添加
$("#btn_add").click(function () {
var url = "/SaleManage/AddForm";
openDialog(url, "AddForm", "添加订单", 645, 470, function (iframe) {
top.frames[iframe].AcceptClick()
});
}) //编辑
$("#btn_edit").click(function () {
//获取当前选择行id
var selectedRows = $("#tb_SaleOrder").bootstrapTable('getSelections');
if (selectedRows.length <= 0) {
alert('请选择要编辑的数据');
} else if (selectedRows.length > 1) {
alert('一次只能选择一行数据进行编辑');
} else {
var KeyValue = selectedRows[0].OrderNO;
var url = "/SaleManage/EditForm?KeyValue=" + KeyValue;
openDialog(url, "EditForm", "编辑邮件", 645, 470, function (iframe) {
top.frames[iframe].AcceptClick()
});
}
})
//删除数据
$("#btn_delete").click(function () {
//获取当前选择行id
var selectedRows = $("#tb_SaleOrder").bootstrapTable('getSelections');
if (selectedRows.length <= 0) {
alert('请选择要删除的数据');
return;
}
if (selectedRows.length > 1) {
alert('一次只能选择一行删除');
return;
}
var orderNo = selectedRows[0].OrderNO;
//aja异步请求
$.ajax({
url: '/SaleManage/DelOrder',
type: 'get',
contentType: 'application/json;charset=utf-8',
data: { orderNo: orderNo },
success: function (data) {
//刷新bootstrap-table
$("#tb_SaleOrder").bootstrapTable('refresh');
},
error: function (data) {
alert('数据删除失败' + data);
}
})
}) //回车键
document.onkeydown = function (e) {
if (!e) e = window.event; //火狐中是 window.event
if ((e.keyCode || e.which) == 13) {
var query = document.getElementById("btn_query");
query.focus();
query.click();
}
}
});

3.日期初始化

 //当月第一天所对应的日期 yyyy-mm-dd
function GetLocalMonFrstDayDate() {
var now = new Date();
var year = now.getFullYear();//年
var mon = now.getMonth() + 1;//月
if (mon < 10) {
mon = '-0' + mon;
}
var frstDay = "-01"; //日
return year + mon + frstDay;
}
//当月最后一天所对应的日期 yyyy-mm-dd
function GetLocalMonLastDayDate() {
var now = new Date();
var year = now.getFullYear();//年
var mon = now.getMonth() + 1;//月
if (mon < 10) {
mon = '-0' + mon;
}
var LastDay = "-" + GetDayCountInMon(year + mon);
return year + mon + LastDay;
}
//计算当月对应的最大天数
function GetDayCountInMon(YearMon) {
var arr = YearMon.split("-");
var localYear = parseInt(arr[0]);
var localMon = parseInt(arr[1]);
var localDate = new Date(localYear, localMon, 0);
return localDate.getDate();
}

4.Index.cshtml

 @{
Layout = "~/Views/Shared/_LayoutBTSTable.cshtml";
} <!--查询条件-->
<div class="panel-body" style="padding-bottom:0px;width:104%;margin-left:-15px">
<div class="panel panel-default">
<div class="panel-heading">
订单管理
</div>
<div style="margin-top:-30px;text-align:right">
<a href="~/Files/ImportTemple.xlsx" style="margin-right:20px">下载导入模板 </a>
</div>
<div class="panel-body">
<div style="margin-top:10px;">
日期:
<input type="text" id="startDate" style="height:35px;width:100px;margin-left:5px;margin-top:-32px;border-radius: 6px;border: 1px #cccccc solid; outline: none" onfocus="WdatePicker({dateFmt:'yyyy-MM-dd'})">

<input type="text" id="endDate" style="height:35px;width:100px;margin-left:8px;margin-top:-34px;border-radius: 6px;border: 1px #cccccc solid; outline: none" onfocus="WdatePicker({dateFmt:'yyyy-MM-dd'})">
&nbsp; &nbsp;订单编号:<input type="text" id="queryKey" placeholder="请输入订单编号进行查询" style="height:35px;width:170px;margin-left:10px;margin-top:-34px;border-radius: 6px;border: 1px #cccccc solid; outline: none">
<button type="button" style="width:70px;height:35px;margin-left:20px;margin-top:-3px" id="btn_query" class="btn btn-success">查询</button>
<button type="button" style="width:70px;height:35px;margin-left:20px;margin-top:-3px" id="btn_add" class="btn btn-info">添加</button>
<button type="button" style="width:70px;height:35px;margin-left:20px;margin-top:-3px" id="btn_edit" class="btn btn-warning">编辑</button>
<button type="button" style="width:70px;height:35px;margin-left:20px;margin-top:-3px" id="btn_delete" class="btn btn-danger">删除</button>
</div>
</div>
</div>
</div>
<!--初始化bootstrap-table-->
<div style="margin-bottom:-40px;color:red">注释:订单数据</div>
<table id="tb_SaleOrder" class="table"></table> <style>
#tb_SaleOrder tbody > tr:hover {
background-color: #449d44;
} #tb_SaleOrder > thead th {
padding: 0;
margin: 0;
background-color: #d9edf7;
}
</style>
<script>
//刷新bootstrap-table
function refleshBootStrapTable() {
$("#tb_SaleOrder").bootstrapTable('refresh');
}
</script> <script src="~/CustomUI/TableJS/SaleOrder.js"></script>

5.AddForm.cshtml

 @{
ViewBag.Title = "AddForm";
Layout = "~/Views/Shared/_LayoutBTSTable.cshtml";
} <script>
//添加数据
function AcceptClick() {
var OrderNO = $("#OrderNO").val();
var ProductNo = $("#ProductNo").val();
var CustName = $("#CustName").val();
var CustAddress = $("#CustAddress").val();
var CustPhone = $("#CustPhone").val();
var CustCompany = $("#CustCompany").val();
var CreateDateTime = $("#CreateDateTime").val();
var UpdateDateTime = $("#UpdateDateTime").val();
$.ajax({
url: '/SaleManage/AddDataToDB',
type: 'get',
contentType: 'application/json;charset=utf-8',
data: {
'OrderNO': OrderNO, 'ProductNo': ProductNo, 'CustName': CustName,
'CustAddress': CustAddress, 'CustPhone': CustPhone, 'CustCompany': CustCompany,
'CreateDateTime': CreateDateTime, 'UpdateDateTime': UpdateDateTime
},
success: function (data) {
reflesh();
//关闭对话框
closeDialog();
},
error: function (data) {
alert('添加数据失败' + data);
}
})
}
//刷新
function reflesh() {
window.parent.refleshBootStrapTable();
}
</script> <div class="table" style="width:100%;margin-top:10px">
<table id="tb_SaleOrder_Add" class="table text-nowrap" style="text-align:right;">
<tr>
<td style="height:35px;line-height:35px">订单编号&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="OrderNO" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">产品名称&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="ProductNo" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户姓名&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustName" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户地址&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustAddress" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户电话&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustPhone" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户公司&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustCompany" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">订单创建时间&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CreateDateTime" style="width:500px;" onfocus="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss'})" class="Wdate"/></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">订单更新时间&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="UpdateDateTime" style="width:500px;" onfocus="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss'})" class="Wdate"/></td>
</tr>
</table>
</div> <style>
#tb_SaleOrder_Add td input[type=text] {
height: 35px;
border-radius: 6px;
border: 1px #cccccc solid;
outline: none
}
</style>

6.EditForm.cshtml

@{
ViewBag.Title = "EditForm";
Layout = "~/Views/Shared/_LayoutBTSTable.cshtml";
} <script>
$(function () {
//初始化页面控件
$.ajax({
url: "/SaleManage/InitModifySheet",
type: 'get',
contentType: 'application/json;charset=utf-8',
data: {
orderNO: GetQuery('KeyValue')
},
success: function (data) {
//将回调数据转化为json对象
var jsonData = eval(data);
//遍历,为表单赋值
$("#OrderNO").val(jsonData[0].OrderNO);
$("#ProductNo").val(jsonData[0].ProductNo);
$("#CustName").val(jsonData[0].CustName);
$("#CustAddress").val(jsonData[0].CustAddress);
$("#CustPhone").val(jsonData[0].CustPhone);
$("#CustCompany").val(jsonData[0].CustCompany);
$("#CreateDateTime").val(jsonData[0].CreateDateTime);
$("#UpdateDateTime").val(jsonData[0].UpdateDateTime);
},
error: function (data) {
alert('编辑数据失败' + data);
}
})
}) //添加数据
function AcceptClick() {
var OrderNO = $("#OrderNO").val();
var ProductNo = $("#ProductNo").val();
var CustName = $("#CustName").val();
var CustAddress = $("#CustAddress").val();
var CustPhone = $("#CustPhone").val();
var CustCompany = $("#CustCompany").val();
var CreateDateTime = $("#CreateDateTime").val();
var UpdateDateTime = $("#UpdateDateTime").val();
$.ajax({
url: '/SaleManage/ModifyDataToDB',
type: 'get',
contentType: 'application/json;charset=utf-8',
data: {
'OrderNO': OrderNO, 'ProductNo': ProductNo, 'CustName': CustName,
'CustAddress': CustAddress, 'CustPhone': CustPhone, 'CustCompany': CustCompany,
'CreateDateTime': CreateDateTime, 'UpdateDateTime': UpdateDateTime
},
success: function (data) {
reflesh();
//关闭对话框
closeDialog();
},
error: function (data) {
alert('添加数据失败' + data);
}
})
}
//刷新
function reflesh() {
window.parent.refleshBootStrapTable();
}
</script> <div class="table" style="width:100%;margin-top:10px">
<table id="tb_SaleOrder_Add" class="table text-nowrap" style="text-align:right;">
<tr>
<td style="height:35px;line-height:35px">订单编号&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="OrderNO" style="width:500px;" disabled/></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">产品名称&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="ProductNo" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户姓名&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustName" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户地址&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustAddress" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户电话&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustPhone" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户公司&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustCompany" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">订单创建时间&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CreateDateTime" style="width:500px;" onfocus="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss'})" class="Wdate" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">订单更新时间&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="UpdateDateTime" style="width:500px;" onfocus="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss'})" class="Wdate" /></td>
</tr>
</table>
</div> <style>
#tb_SaleOrder_Add td input[type=text] {
height: 35px;
border-radius: 6px;
border: 1px #cccccc solid;
outline: none
}
</style>

7.Import.cshtml

 @{
ViewBag.Title = "EditForm";
Layout = "~/Views/Shared/_LayoutBTSTable.cshtml";
} <script>
$(function () {
//初始化页面控件
$.ajax({
url: "/SaleManage/InitModifySheet",
type: 'get',
contentType: 'application/json;charset=utf-8',
data: {
orderNO: GetQuery('KeyValue')
},
success: function (data) {
//将回调数据转化为json对象
var jsonData = eval(data);
//遍历,为表单赋值
$("#OrderNO").val(jsonData[0].OrderNO);
$("#ProductNo").val(jsonData[0].ProductNo);
$("#CustName").val(jsonData[0].CustName);
$("#CustAddress").val(jsonData[0].CustAddress);
$("#CustPhone").val(jsonData[0].CustPhone);
$("#CustCompany").val(jsonData[0].CustCompany);
$("#CreateDateTime").val(jsonData[0].CreateDateTime);
$("#UpdateDateTime").val(jsonData[0].UpdateDateTime);
},
error: function (data) {
alert('编辑数据失败' + data);
}
})
}) //添加数据
function AcceptClick() {
var OrderNO = $("#OrderNO").val();
var ProductNo = $("#ProductNo").val();
var CustName = $("#CustName").val();
var CustAddress = $("#CustAddress").val();
var CustPhone = $("#CustPhone").val();
var CustCompany = $("#CustCompany").val();
var CreateDateTime = $("#CreateDateTime").val();
var UpdateDateTime = $("#UpdateDateTime").val();
$.ajax({
url: '/SaleManage/ModifyDataToDB',
type: 'get',
contentType: 'application/json;charset=utf-8',
data: {
'OrderNO': OrderNO, 'ProductNo': ProductNo, 'CustName': CustName,
'CustAddress': CustAddress, 'CustPhone': CustPhone, 'CustCompany': CustCompany,
'CreateDateTime': CreateDateTime, 'UpdateDateTime': UpdateDateTime
},
success: function (data) {
reflesh();
//关闭对话框
closeDialog();
},
error: function (data) {
alert('添加数据失败' + data);
}
})
}
//刷新
function reflesh() {
window.parent.refleshBootStrapTable();
}
</script> <div class="table" style="width:100%;margin-top:10px">
<table id="tb_SaleOrder_Add" class="table text-nowrap" style="text-align:right;">
<tr>
<td style="height:35px;line-height:35px">订单编号&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="OrderNO" style="width:500px;" disabled/></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">产品名称&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="ProductNo" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户姓名&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustName" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户地址&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustAddress" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户电话&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustPhone" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">客户公司&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CustCompany" style="width:500px;" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">订单创建时间&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="CreateDateTime" style="width:500px;" onfocus="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss'})" class="Wdate" /></td>
</tr>
<tr>
<td style="height:35px;line-height:35px">订单更新时间&nbsp;&nbsp;&nbsp;:</td>
<td><input type="text" id="UpdateDateTime" style="width:500px;" onfocus="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss'})" class="Wdate" /></td>
</tr>
</table>
</div> <style>
#tb_SaleOrder_Add td input[type=text] {
height: 35px;
border-radius: 6px;
border: 1px #cccccc solid;
outline: none
}
</style>

8.ParentAndChild.cshtml

 @{
Layout = "~/Views/Shared/_LayoutBTSTable.cshtml";
} <!--查询条件-->
<div class="panel-body" style="padding-bottom:0px;width:104%;margin-left:-15px">
<div class="panel panel-default">
<div class="panel-heading">
订单管理
</div>
<div style="margin-top:-30px;text-align:right">
<a href="~/Files/ImportTemple.xlsx" style="margin-right:20px">下载导入模板 </a>
</div>
<div class="panel-body">
<div style="margin-top:10px;">
日期:
<input type="text" id="startDate" style="height:35px;width:100px;margin-left:5px;margin-top:-32px;border-radius: 6px;border: 1px #cccccc solid; outline: none" onfocus="WdatePicker({dateFmt:'yyyy-MM-dd'})">

<input type="text" id="endDate" style="height:35px;width:100px;margin-left:8px;margin-top:-34px;border-radius: 6px;border: 1px #cccccc solid; outline: none" onfocus="WdatePicker({dateFmt:'yyyy-MM-dd'})">
&nbsp; &nbsp;订单编号:<input type="text" id="queryKey" placeholder="请输入订单编号进行查询" style="height:35px;width:170px;margin-left:10px;margin-top:-34px;border-radius: 6px;border: 1px #cccccc solid; outline: none">
<button type="button" style="width:70px;height:35px;margin-left:20px;margin-top:-3px" id="btn_query" class="btn btn-success">查询</button>
<button type="button" style="width:70px;height:35px;margin-left:20px;margin-top:-3px" id="btn_add" class="btn btn-info">添加</button>
<button type="button" style="width:70px;height:35px;margin-left:20px;margin-top:-3px" id="btn_edit" class="btn btn-warning">编辑</button>
<button type="button" style="width:70px;height:35px;margin-left:20px;margin-top:-3px" id="btn_delete" class="btn btn-danger">删除</button>
</div>
</div>
</div>
</div>
<!--初始化bootstrap-table-->
<div style="margin-bottom:-40px;color:red">注释:父子表</div>
<table id="tb_SaleOrder" class="table"></table> <style>
#tb_SaleOrder > thead th {
padding: 0;
margin: 0;
background-color: #d9edf7;
}
</style>
<script>
//刷新bootstrap-table
function refleshBootStrapTable() {
$("#tb_SaleOrder").bootstrapTable('refresh');
}
</script> <script src="~/CustomUI/TableJS/ParentChild.js"></script>

9.布局页 _LayoutBTSTable.cshtml

 <!DOCTYPE html>

 <html>
<head>
<meta name="viewport" content="width=device-width" />
<link href="~/CustomUI/bootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="~/CustomUI/bootstrapTable/bootstrap-table.css" rel="stylesheet" />
<link href="~/CustomUI/skin/WdatePicker.css" rel="stylesheet" />
<script src="~/CustomUI/jquery/jquery-3.3.1.js"></script>
<script src="~/CustomUI/lhgdialog/lhgdialog.min.js"></script>
<script src="~/CustomUI/bootstrap/js/bootstrap.js"></script>
<script src="~/CustomUI/bootstrapTable/bootstrap-table.js"></script>
<script src="~/CustomUI/bootstrapTable/tableExport.js"></script>
<script src="~/CustomUI/bootstrapTable/bootstrap-table-export.js"></script>
<script src="~/CustomUI/bootstrapTable/bootstrap-table-zh-CN.js"></script>
<script src="~/CustomUI/datepicker/WdatePicker.js"></script>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html> <script src="~/CustomUI/TableJS/DialogTemple.js"></script>

10.ImportExcelToDB.cs

 using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Web; namespace BTStrapTB.Common
{
public class ImportExcelToDB
{
//全局数据库连接字符串
private readonly string strConnection = ConfigurationManager.ConnectionStrings["conStr"].ConnectionString; //从Excel读取数据
public static DataSet ReadExcelDataToTable(string filepath)
{
try
{
int index1 = filepath.LastIndexOf("\\");
int index2 = filepath.LastIndexOf(".");
string fileName ="["+filepath.Substring(index1+1,index2-index1-1)+"$]";
string strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;'", filepath);
using (OleDbConnection oleConn = new OleDbConnection(strConn))
{
oleConn.Open();
string sql = "select * from "+fileName+ "";
OleDbDataAdapter oleDaExcel = new OleDbDataAdapter(sql, oleConn);
DataSet oleDsExcel = new DataSet();
oleDaExcel.Fill(oleDsExcel, "table1");
return oleDsExcel;
}
}
catch (Exception ex)
{
throw ex;
}
}
public void InsertExcelDataToDB(string fileName)
{
//导入表格格式化SQL
string sqlText = @"INSERT INTO [dbo].[SaleOrder]
([OrderNO]
,[ProductNo]
,[CustName]
,[CustAddress]
,[CustPhone]
,[CustCompany]
,[CreateDateTime]
,[UpDateDateTime])
VALUES
('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}')"; if (!System.IO.File.Exists(fileName))
{
throw new Exception("指定路径的Excel文件不存在!");
}
DataSet ds = ReadExcelDataToTable(fileName);
DataTable dt = ds.Tables[0];
//将excel数据插入到DB之前,先判断DB中是否存在数据
DelDBRepeatData(dt);
List<string> list = (from DataRow row in dt.Rows
select String.Format(sqlText, row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7])).ToList();
OperateDB(list);
} /*
将excel数据插入到DB之前,
先判断DB中是否存在同一天同一员工记录
*/
public int DelDBRepeatData(DataTable dt)
{
//sql脚本
string delSqlText = @"DELETE FROM [dbo].[SaleOrder]
WHERE OrderNO IN ('{0}')
"; //取excel中的员工号和打卡日期
StringBuilder strBld = new StringBuilder(); for (int i = 0; i < dt.Rows.Count; i++)
{
strBld.Append(dt.Rows[i][0]); } List<string> list = (from DataRow row in dt.Rows
select String.Format(delSqlText, row[0])).ToList(); OperateDB(list);
return 0;
} //DB操作
public int OperateDB(List<string> list)
{
int result = 0;
using (SqlConnection conn = new SqlConnection(strConnection))
{
if (conn.State==ConnectionState.Closed)
{
conn.Open();
}
foreach (string item in list)
{
SqlCommand cmd = new SqlCommand(item, conn);
result=cmd.ExecuteNonQuery();
}
}
return result;
}
}
}

12.ConvertHelpers.cs

 using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Web; namespace BTStrapTB.Common
{
/// <summary>
/// 转换Json格式帮助类
/// </summary>
public static class JsonHelper
{
public static object ToJson(this string Json)
{
return JsonConvert.DeserializeObject(Json);
}
public static string ToJson(this object obj)
{
return JsonConvert.SerializeObject(obj);
}
public static List<T> JonsToList<T>(this string Json)
{
return JsonConvert.DeserializeObject<List<T>>(Json);
}
public static T JsonToEntity<T>(this string Json)
{
return JsonConvert.DeserializeObject<T>(Json);
}
}
}

13.SaleManageController

 using BTStrapTB.BLL;
using BTStrapTB.Common;
using BTStrapTB.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace BTStrapTB.Controllers
{
//销售管理
public class SaleManageController : BaseManageController
{
ImportExcelToDB ImportToExcl = new ImportExcelToDB();
SaleOrderBLL SOBLL = new SaleOrderBLL();
SaleProductBLL SPBLL = new SaleProductBLL();
public override ActionResult Index()
{
return View();
}
//导入页面
public ActionResult Import()
{
return View();
} //将Excel订单数据导入
[HttpPost]
public ActionResult ImportExclToDB(HttpPostedFileBase file)
{
var severPath = this.Server.MapPath("/Files"); //获取当前虚拟文件路径
var savePath = Path.Combine(severPath, file.FileName); //拼接保存文件路径
file.SaveAs(savePath);
try
{
ImportToExcl.InsertExcelDataToDB(savePath);
return Content("<script>alert('上传成功!!')</script>");
}
catch (Exception ex)
{
throw new Exception(ex.Message);
} //Response.Redirect("/PunchCardRecord/Index");
} //父子页面
public ActionResult ParentAndChild()
{
return View();
} //获取子表数据
public ActionResult GetChildDataList(int limit, int offset,string productNo)
{
List<SaleProduct> list = SPBLL.GetProductOrderList(productNo);
int total = list.Count;
var rows = list.Skip(offset).Take(limit).ToList();
return Json(new { total, rows }, JsonRequestBehavior.AllowGet);
} //获取订单列表
public ActionResult GetOrderList(int limit, int offset,string startDate,string endDate,string orderNO)
{
List<SaleOrder> list = SOBLL.GetSaleOrderList(startDate,endDate, orderNO);
int total = list.Count;
var rows = list.Skip(offset).Take(limit).ToList();
return Json(new { total, rows }, JsonRequestBehavior.AllowGet);
}
//删除数据
public void DelOrder(string orderNo)
{
SOBLL.DelDataToDB(orderNo);
}
//添加数据
public void AddDataToDB(SaleOrder saleOrder)
{
SOBLL.AddDataToDB(saleOrder);
}
//初始化修改表单
public ActionResult InitModifySheet(string orderNO)
{
List<SaleOrder> list = SOBLL.GetSaleOrderList("", "", orderNO);
return Content(list.ToJson());
}
//修改数据
public void ModifyDataToDB(SaleOrder saleOrder)
{
SOBLL.ModifyDataToDB(saleOrder);
}
}
}

14.父子表JS

 //初始化
var InitTable = function (url) {
//先销毁表格
$('#tb_SaleOrder').bootstrapTable("destroy");
//加载表格
$('#tb_SaleOrder').bootstrapTable({
rowStyle: function (row, index) {//row 表示行数据,object,index为行索引,从0开始
var style = "";
if (row.SignInTime == '' || row.SignOutTime == '') {
style = { css: { 'color': 'red' } };
}
return style;
},
//searchAlign: 'left',
//search: true, //显示隐藏搜索框
showHeader: true, //是否显示列头
//classes: 'table-no-bordered',
showLoading: true,
undefinedText: '',
showFullscreen: true,
toolbarAlign: 'left',
paginationHAlign: 'right',
silent: true,
url: url,
method: 'get', //请求方式(*)
toolbar: '#toolbar', //工具按钮用哪个容器
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, //是否显示分页(*)
sortable: false, //是否启用排序
sortOrder: "asc", //排序方式
//queryParams: InitTable.queryParams, //传递参数(*)
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
pageNumber: 1, //初始化加载第一页,默认第一页
pageSize: 10, //每页的记录行数(*)
pageList: [2, 5, 10, 15], //可供选择的每页的行数(*)
search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
strictSearch: true,
showColumns: true, //是否显示所有的列
showRefresh: true, //是否显示刷新按钮
minimumCountColumns: 2, //最少允许的列数
clickToSelect: true, //是否启用点击选中行
//height: 680, //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度
uniqueId: "ID", //每一行的唯一标识,一般为主键列
showToggle: true, //是否显示详细视图和列表视图的切换按钮
cardView: false, //是否显示详细视图
detailView: true, //是否显示父子表
showExport: true,
//exportDataType: 'all',
exportDataType: "selected", //导出checkbox选中的行数
paginationLoop: false, //是否无限循环
columns: [{
checkbox: true
}, {
field: 'OrderNO',
title: '订单编号'
}, {
field: 'ProductNo',
title: '产品编号'
}, {
field: 'CustName',
title: '客户姓名'
}, {
field: 'CustAddress',
title: '客户地址',
}, {
field: 'CustPhone',
title: '客户电话',
}, {
field: 'CustCompany',
title: '客户公司',
}, {
field: 'CreateDateTime',
title: '订单创建时间',
}, {
field: 'UpdateDateTime',
title: '订单更新时间',
}], //无限循环取子表,直到子表里面没有记录
onExpandRow: function (index, row, $Subdetail) {
InitSubTable(index, row, $Subdetail);
}
});
return InitTable; }; //初始化子表格(无线循环)
InitSubTable = function (index, row, $detail) {
var parentid = row.ProductNo;
var cur_table = $detail.html('<table></table>').find('table');
$(cur_table).bootstrapTable({
url: "/SaleManage/GetChildDataList",
method: 'get',
queryParams: { 'limit':10000,'offset':0,'productNo':parentid},
clickToSelect: true,
detailView: false,//父子表
sidePagination: "server",
uniqueId: "ProductNo",
pageSize: 10,
pageList: [10, 25],
columns: [{
field: 'ProductNo',
title: '产品编号'
},
{
field: 'ProductName',
title: '产品名称'
}, {
field: 'ProductType',
title: '产品类型'
}, {
field: 'ProductCount',
title: '产品数量'
},
{
field: 'ProductPrice',
title: '产品单价'
}],
//无限循环取子表,直到子表里面没有记录
onExpandRow: function (index, row, $Subdetail) {
InitSubTable(index, row, $Subdetail);
}
});
};

(三)其他技术点

1.改变bootstrap-table表头颜色

 #tb_SaleOrder > thead th {
padding: 0;
margin: 0;
background-color: #d9edf7;
}

2.改变bootstrap-table 光标悬停颜色

 #tb_SaleOrder tbody > tr:hover {
background-color: #449d44;
}

3.刷新bootstrap-table

 //刷新bootstrap-table
function refleshBootStrapTable() {
$("#tb_SaleOrder").bootstrapTable('refresh');
}

4.弹窗

 /*
弹出对话框(带:确认按钮、取消按钮)
*/
function openDialog(url, _id, _title, _width, _height, callBack) {
Loading(true);
top.$.dialog({
id: _id,
width: _width,
height: _height,
max: false,
lock: true,
title: _title,
resize: false,
extendDrag: true,
content: 'url:' + RootPath() + url,
ok: function () {
callBack(_id);
return false;
},
cancel: true
});
}

5.Bootstrap-table核心技术点,再次强调

 var InitTable = function (url) {
//先销毁表格
$('#tb_SaleOrder').bootstrapTable("destroy");
//加载表格
$('#tb_SaleOrder').bootstrapTable({
rowStyle: function (row, index) {//row 表示行数据,object,index为行索引,从0开始
var style = "";
if (row.SignInTime == '' || row.SignOutTime=='') {
style = { css: { 'color': 'red' } };
}
return style;
},
//searchAlign: 'left',
//search: true, //显示隐藏搜索框
showHeader: true, //是否显示列头
//classes: 'table-no-bordered',
showLoading: true,
undefinedText: '',
showFullscreen: true,
toolbarAlign: 'left',
paginationHAlign: 'right',
silent: true,
url: url,
method: 'get', //请求方式(*)
toolbar: '#toolbar', //工具按钮用哪个容器
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, //是否显示分页(*)
sortable: false, //是否启用排序
sortOrder: "asc", //排序方式
//queryParams: InitTable.queryParams, //传递参数(*)
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
pageNumber: 1, //初始化加载第一页,默认第一页
pageSize: 10, //每页的记录行数(*)
pageList: [2, 5, 10, 15], //可供选择的每页的行数(*)
search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
strictSearch: true,
showColumns: true, //是否显示所有的列
showRefresh: true, //是否显示刷新按钮
minimumCountColumns: 2, //最少允许的列数
clickToSelect: true, //是否启用点击选中行
//height: 680, //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度
uniqueId: "ID", //每一行的唯一标识,一般为主键列
showToggle: true, //是否显示详细视图和列表视图的切换按钮
cardView: false, //是否显示详细视图
detailView: false, //是否显示父子表
showExport: true,
//exportDataType: 'all',
exportDataType: "selected", //导出checkbox选中的行数
paginationLoop: false, //是否无限循环
columns: [{
checkbox: true
}, {
field: 'OrderNO',
title: '订单编号'
}, {
field: 'ProductNo',
title: '产品编号'
}, {
field: 'CustName',
title: '客户姓名'
}, {
field: 'CustAddress',
title: '客户地址',
}, {
field: 'CustPhone',
title: '客户电话',
}, {
field: 'CustCompany',
title: '客户公司',
}, {
field: 'CreateDateTime',
title: '订单创建时间',
}, {
field: 'UpdateDateTime',
title: '订单更新时间',
}]
});
return InitTable;
};

四  写在最后

本片文章借助于bootstrap-table插件,实现了基本的增删改查,导入导出,分页,父子表等。至于其他技术,如冻结表头,列排列,行拖动,列拖动等,会在后续文章中与大家分享。

五  版权区

感谢您的阅读,若有不足之处,欢迎指教,共同学习、共同进步。

从入门到架构群:820424。

极少部分文章利用读书、参考、引用、抄袭、复制和粘贴等多种方式整合而成的,大部分为原创。

如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出,邮箱:2098469527@qq.com。

demo访问地址:http://106.14.139.196/SaleManage/Index ,本套源码49元,需要购买请咨询:2098469527

可以转载该博客,但必须著名博客来源。

【Bootstrap系列】详解Bootstrap-table的更多相关文章

  1. 详解Bootstrap表单组件

    表单常见的元素主要包括:文本输入框.下拉选择框.单选框.复选框.文本域.按钮等.下面是不同的bootstrap版本: LESS:  forms.less SASS:  _forms.scss boot ...

  2. QAction系列详解

    QAction系列详解 一.QAction类详解 [详细描述] QAction类提供了抽象的用户界面action,这些action可以被放置在窗口部件中.        应用程序可以通过菜单,工具栏按 ...

  3. MySQL系列详解八:MySQL多线程复制演示-技术流ken

    前言 Mysql 采用多线程进行复制是从 Mysql 5.6 开始支持的内容,但是 5.6 版本下有缺陷,虽然支持多线程,但是每个数据库只能一个线程,也就是说如果我们只有一个数据库,则主从复制时也只有 ...

  4. 详解Bootstrap按钮组件

    按钮组也是一个独立的组件,所以可以找到相应的源码文件: Less:buttons.less Sass:_buttons.scss Css:Bootstrap.css    3131行~3291行 按钮 ...

  5. 详解Bootstrap下拉菜单组件

    bootstrap框架中的下拉菜单组件是一个独立的组件,根据不同的版本,他对应的文件: less 对应的源码文件为:dropdowns.less sass对应的源码文件为:_dropdowns.scs ...

  6. 详解Bootstrap实现基本布局的方法

    看到了一篇 20 分钟打造 Bootstrap 站点的文章,内容有点老,重新使用bootstrap教程实现一下,将涉及的内容也尽可能详细说明. 1. 创建基本的页面我们先创建一个基本的 HTML 模板 ...

  7. iOS开发技巧系列---详解KVC(我告诉你KVC的一切)

    KVC(Key-value coding)键值编码,单看这个名字可能不太好理解.其实翻译一下就很简单了,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值.而不需 ...

  8. MySQL系列详解六:MySQL主从复制/半同步演示-技术流ken

    前言 随着技术的发展,在实际的生产环境中,由单台MySQL数据库服务器不能满足实际的需求.此时数据库集群就很好的解决了这个问题了.采用MySQL分布式集群,能够搭建一个高并发.负载均衡的集群服务器.在 ...

  9. MySQL系列详解三:MySQL中各类日志详解-技术流ken

    前言 日志文件记录了MySQL数据库的各种类型的活动,MySQL数据库中常见的日志文件有 查询日志,慢查询日志,错误日志,二进制日志,中继日志 .下面分别对他们进行介绍. 查询日志 1.查看查询日志变 ...

  10. OpenStack计费项目Cloudkitty系列详解(一)

    云计算是一种按需付费的服务模式,虽然OpenStack前期在计量方面走了些“弯路”,但现在的ceilometer.gnocchi.aodh.panko项目的稳步并进算是让其峰回路转.然而,目前来看Op ...

随机推荐

  1. How to setup Visual Studio without pain

    Visual Studio (VS) can be very hard to install. If you are lucky, one whole day may be enough to ins ...

  2. Vue.js环境配置

    一.安装node.js 自行下载安装 https://nodejs.org/en/ 二.查看版本,更新版本 查看node版本 node --version 查看npm版本 npm --version ...

  3. centos jdk 配置及版本切换

    一. 环境变量: /etc/profile JAVA_HOME=/usr/lib/jdk1.8.0_91JRE_HOME=/usr/lib/jdk1.8.0_91/jreCLASS_PATH=.:$J ...

  4. GC调优

    Gc调优的目标:1.降低停顿时间 2.提高吞吐量 3.避免full-gc 调优可以使用的手段:1.各个内存区的大小调整:堆,年轻代,老年代,方法区等等2.减少短暂对象的存活时间,提高长期对象的复用率( ...

  5. JavaScript复习笔记——数据类型

    1.undefined 使用var声明但未对其进行初始化时,这个变量的值就是undefined. 对未被初始化的值使用typeof会返回undefined值,而对未声明的变量执行typeof操作同样也 ...

  6. mac上terminal_问题_1117

    (1)安装Homebrew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install ...

  7. JavaScript自定义鼠标右键菜单

    下面为JavaScript代码 window.onload = function () { //好友列表 var f = 0; //判断指定id的元素在页面中是否存在 if (document.get ...

  8. 《HTTP权威指南》2-URL

    前言 在一个城市中,所有的东西都有一个标准化的名字,以帮助人们寻找城市中的各种资源,如宁波火车站地铁站,在因特网这座大城市中,URL就是其标准化名称,它指向每一条电子信息,告诉你它们位于何处,以及如何 ...

  9. SSAS 后端数据库访问模块中存在错误。 为绑定指定的大小太小,导致一个或多个列值被截断。

    在处理AS的过程中报错如上,经排查发现原因为数据库 “工号” 字段长度过长导致. 因为我的字段内容基本是人名加工号:张三/1001 不曾想有用户录入非正常数据 :张三/100/1001 这样导致我截取 ...

  10. MySQL--Insert Buffer

    在进行数据插入时,需要将数据插入到聚集索引和非聚集索引中,而对于非聚集索引,需要先确定数据要插入的索引页,再将索引页加载到内存中进行修改,而在业务上很难保证插入数据在非聚集索引上也是连续的,因此插入操 ...