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. XNA、FNA以及在VS2017中编写XNA

    XNA是早期DX SDK支持的C#游戏开发环境,虽然现游戏开发大多是以Unity3D,Unreal 4为主,但是许多独立游戏开发者,特别是2D游戏,依然使用XNA进行开发, 纠其原因,猜测是C#开源且 ...

  2. 索引Log

    最左前缀原则 B+ 主键索引ID =>ID树 非主键索引K 先K树=>ID树 主键自增索引

  3. EFLinq查询

    1.无参数查询var model = db.Database.SqlQuery<UserInfo>("select* from UserInfoes ").ToList ...

  4. 学习Python第四天

    关于剩下的数据类型:字符串 字符串是有序的,不可变的(不可变的意思是指将变量a重新赋值后不会覆盖原来的值,而是在内存中开辟了一块新的内存地址,存储变量的值) 字符串的各种方法: 1,将字符串中的大写变 ...

  5. VS code的疑惑之处

    作为一个新手,我充满疑惑 eg:下载了git但无法使用匹配 然后在各位博主的详细解释下知道 VS code更新后的git.path被格式化了: so需要进行路径覆盖. 在这之后我的终端依旧出现问题   ...

  6. 关于IO的整理

    我们知道io只是输入输出,在java语言中分为同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO,现在的IO,一般是用作两种用途:一种是进行文件或者目录的操作(将不同的输入输出源抽象成流,所以流 ...

  7. The test form is only available for requests from the local machine

    使用浏览器测试Web服务时出现提示“The test form is only available for requests from the local machine.”的解决办法 在Web服务项 ...

  8. Openvswitch手册(2): OpenFlow Controller

         我们这一节主要来看Controller Controller有两种: Primary Controller: 真正控制vswitch的flow table,vswitch会保持和contro ...

  9. TIME_WAIT状态过多的排查

    一.概述 (一)现象 服务器有两个现象,第一是tcp连接数不多,不超过10个,但是time_wait状态的2000.第二个按照以往的性质,在很少用户访问的情况下,服务器的资源几乎没有使用,比如CPU, ...

  10. 编程语言吐槽之Java与C

    包含各种偏见和武断,请谨慎阅读. 为什么在学校学习的C,拿到企业生产中不起作用? 而为什么企业级的程序员,依然对C/C++无法掌控?在算法各方面不够精湛? 根本原因还是应用场景的不同.企业级的开发,主 ...