如上就是很多后台管理系统的母版页布局.
左边一列模板.上面一列系统标识.
空白处充填子页面
以ASP.NET MVC为基础
引入bootstrap.js.bootstrap.css
body: <div> <ul class="nav pull-right"> <li class="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" href="#" style="color:#000000"> "你的用户名" <span class="caret"></span> </a> <ul class="dropdown-menu dropdown-usermenu purple"> <li><a href="@Url.Action("Logout","User")"><i class="glyphicon glyphicon-off" style="margin-right:10px";></i><span>注销</span></a></li> </ul> </li> </ul> <h1 class="head"><strong>X公司X系统</strong></h1> </div>
以上代码就是如上效果.
ul class="nav pull-right"
构成了右上角的用户和下拉框.
这个部分的颜色是渐变的.
使用代码实现.
如下:
<style> .head{ font-family: 宋体; color: #FFFFFF; Margin: 0px; background: linear-gradient(#71B2F0, #104593); line-height: 80px; padding-top: 35px; padding-left:30px; height: 150px; } </style>
重点是background: linear-gradient(#71B2F0, #104593);
<ul class="nav nav-pills nav-stacked pull-left" style="240px" id="jucheapMenu"> @if (myMenus != null && myMenus.Any()) { StringBuilder sb = new StringBuilder(); var models = myMenus.Where(item => item.Type == MenuType.模块); foreach (var m in models) { var menus = myMenus.Where(item => item.ParentId == m.Id && item.Type == MenuType.菜单); sb.Append("<li >"); sb.AppendFormat("<a href="#" data-url="{0}/{1}/{2}/0" ><i class="{3}" style="margin-right:10px";></i><span>{4}</span></a>", m.Url, m.ParentId, m.Id, m.icon, m.Name); sb.Append("</li>"); } @(new MvcHtmlString(sb.ToString())) } </ul>
在系统中.菜单分权限和角色.
所以在此从数据库中取值.
实际生成的Html代码很简单.
<ul class="nav nav-pills nav-stacked pull-left" style="240px" id="jucheapMenu"> <li > <a href="#" data-url="你页面的连接" ><i class="图表" style="margin-right:10px";></i><span>“”展示的汉字“”</span></a> </li> </ul>
以上代码会形成如上图的导航元素.
最后加上以下代码
<div class="body-content"> <div class="wrapper"> @RenderBody() <iframe id="txtContentBody" style="calc(100%); height: calc(100%); border: 0; margin: 0; padding: 0; min-height: 400px;overflow-y:scroll" src="@Url.Action("Welcome","Control",new { moudleId = 0, menuId = 0 , btnId = 0})"></iframe> </div> </div>
iframe 内联框架就完成了常规后台系统的布局了.
上图是子页面布局的一个小例子
@{ Layout = "/Areas/Adm/Views/Shared/_Layout_Body.cshtml"; }
引入母版页.
<div class="row" ng-app="passwordIndexApp" ng-controller="passwordIndexCtrl"> <div class="col-lg-12"> <section class="panel">
开头声明两个div
第一个class:class:row .
第二个class:“col-lg-12”
这是bootstrap官网的写法.
然后section.class:panel.
就形成了一个白色面板.(bootstrap底色默认灰)
section 里可以定义 <header class="panel-heading" style="margin-bottom: 10px;"> 和 panel-body.在此不介绍 class:Header.以class:body为例 <div class="panel-body"> <form class="form-inline" role="form"> <div class="form-group col-sm-4">
bootstrap有很多种布局,
在此介绍我常使用的.class:panel-body代表一行
.class:form-inline代表横向排版
class:form-group 代表一行中的一个
.class:col-sm-4表示占多少格。
格数是开头定义的第2个div col-lg-12(默认一行12)
就像下面这个例子
<div class="panel-body"> <form class="form-inline" role="form"> <div class="form-group col-sm-4"> <select id="CountMonth" class="form-control"> @{ foreach (var item in @ViewData["monthFor12"] as List<string>) { if (Model.CountMonth.ToString() == item) { <option selected>@item</option> } else { <option>@item</option> } } } </select> <span class="text-invers">自动统计X个月内未修改密码的用户到管理员邮箱</span> </div> <div class="form-group col-sm-4 pull-right"> <button type="submit" class="btn btn-round btn-Other pull-right" ng-click="SendAdminEmail()">手动给管理员发报告</button> </div> </form> </div>
如上图.很多后台系统都涉及到多条数据的展示。
业务处理。如果使用表格,传统的写法。
数据库噼里啪啦一大堆。后端分页一大堆,
前端在结合.繁琐重复三遍。
bootstrap封装了数据展示,分页,增删改查的方法,并且样式也比传统html美观.
引入第三方插件.这是中文表单
<script src="~/Scripts/bootstrap-table.js"></script> <link href="~/Scripts/bootstrap-table.css" rel="stylesheet" /> <script src="~/Scripts/bootstrap-table-zh-CN.js"></script> $('#Whitelist').bootstrapTable({ url: '/Password/Whitelist', //请求后台的URL(*) method: 'get', //请求方式(*) toolbar: '#toolbar', //工具按钮用哪个容器 striped: true, //是否显示行间隔色 cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*) pagination: true, //是否显示分页(*) sortable: false, //是否启用排序 sortOrder: "asc", //排序方式 queryParams: oTableInit.queryParams,//传递参数(*) sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*) pageNumber: 1, //初始化加载第一页,默认第一页 pageSize: 10, //每页的记录行数(*) pageList: [10, 25, 50, 100], //可供选择的每页的行数(*) search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大 strictSearch: true, showColumns: true, //是否显示所有的列.选择字段展示 showRefresh: true, //是否显示刷新按钮 minimumCountColumns: 2, //最少允许的列数 clickToSelect: true, //是否启用点击选中行 height: 500, //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度 uniqueId: "Id", //每一行的唯一标识,一般为主键列 showToggle: true, //是否显示详细视图和列表视图的切换按钮 cardView: false, //是否显示详细视图 detailView: false, //是否显示父子表 columns: [{ checkbox: true }, { field: 'Name', title: '名称' }, { field: 'EmailAddress', title: '邮箱名称' } , { field: 'Id', title: '主键列' } ] }); }; //得到查询的参数 oTableInit.queryParams = function (params) { var temp = { //这里的键的名字和控制器的变量名必须一直,这边改动,控制器也需要改成一样的 limit: params.limit, //页面大小 offset: params.offset //页码 }; return temp; };
bootstrapTable里还可以设置更多参数.方法.事件,可以参考bootstrap表格api
http://bootstrap-table.wenzhixin.net.cn/zh-cn/documentation/
以下是C#服务端后台代码
[HttpGet] public JsonResult Whitelist(int limit, int offset) { Expression<Func<WhitelistDto, bool>> exp = item => !item.IsDeleted; var dto = whitelistService.Query(exp, item => item.Id, false); var total = dto.Count; var rows = dto.Skip(offset).Take(limit).ToList(); return Json(new { total = total, rows = rows }, JsonRequestBehavior.AllowGet); }
只要返回的json中包含total就能完成分页,rows充填表格
queryParams 输入查询的条件
oTableInit.queryParams = function (params) { var temp = { //这里的键的名字和控制器的变量名必须一直,这边改动,控制器也需要改成一样的 limit: params.limit, //页面大小 offset: params.offset, //页码 name: $("#Name").val(), department: $("#Department").val(), status: $("#Status").val(), emailAddress: $("#EmailAddress").val() }; return temp; };
紧接着.很多表格都需要增删改查的功能。
如下新增按钮和删除
初始化时 js如下
toolbar: '#toolbar', //工具按钮用哪个容器
html如下
<div class="panel-body"> <div id="toolbar" class="btn-group"> <button id="btn_add" type="button" class="btn btn-default" data-toggle="modal" data-target="#myModal"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增 </button> <button id="btn_delete" type="button" class="btn btn-default" ng-click="DeleteAdminEmail()"> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>删除 </button> </div> <table id="Whitelist"></table> </div>
形成最终页面
下面介绍bootstrap的一些事件和方法
onDblClickCell.是点击表格里某一行的双击事件. onDblClickCell: function (field, value, row, td) { $('#myModal').modal('show');//这是模态框.后面会讲到 } field:点击列的 field 名称, value:点击列的 value 值, row:点击列的整行数据, $element:td 元素。 $("#Whitelist").bootstrapTable('refresh');//这是表格的刷新属性 $("#Whitelist").bootstrapTable('getSelections');//当表格某一行被选中时获取选中行的数据.包括隐藏列 $("#Whitelist").bootstrapTable('remove', { field: 'Id',values: array });//移除表格的某一行数据 $('#Whitelist').bootstrapTable('showColumn', 'Name');//展示被隐藏的列 $('#Whitelist').bootstrapTable('hideColumn', 'Id');//隐藏列
上图就是一个模态框.来自bootstrap.
<!-- 模态框(Modal) --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" ng-click="ClearAdminEmail()" aria-hidden="true"> × </button> <h4 class="modal-title" id="myModalLabel">新增白名单用户
</h4>
</div>
<div class="modal-body">
<form class="form-horizontal">
<div class="form-group has-success">
<label class="col-sm-3 control-label" for="AdminName">名称</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="AdminName" placeholder="名称">
</div>
</div>
</form>
<form class="form-horizontal">
<div class="form-group has-success">
<label class="col-sm-2 control-label" for="AdminEmailData">邮箱</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="AdminEmailData" placeholder="请输入邮箱">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="AddAdminEmail()">
提交更改
</button>
<button type="button" class="btn btn-default" ng-click="ClearAdminEmail()">
关闭
</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
想要实现模态框.只需要定义以下样式.
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header">
----------------------------
<div class="modal-body">
modal-body就像我们子页面里的section.
按照子页面布局设计模态框就行.
-----
<button id="btn_add" type="button" class="btn btn-default" data-toggle="modal" data-target="#myModal"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增 </button>//html方式
$('#myModal').modal('show');//js方式
像上面这杨弹出模态框
$('#myModal').modal('hide'); $("#AdminName").val(""); $("#AdminEmailData").val("");
像上面这杨隐藏模态框.注意清除模态框中html元素的值
以上就是我常用的警告框
<section class="panel"> <div id="jsonResult"> </div>
section下定义空div.用js实现
var result = document.getElementById("jsonResult"); //bootstrap的警告框在弹窗关闭时是删除元素而不是隐藏.只能使用一次.所以在此拼接生成新的警告框. //inter.innerHTML =,array.push() 这两种方式有明显迟钝.innerHTML += 多行会破坏布局 result.innerHTML += " <div class='alert alert-success alert-dismissable'><button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×</button>" + data.Value + "</div>"; //这是绿色警告框 result.innerHTML += " <div class='alert alert-danger alert-dismissable'><button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×</button>" + data.Value + "</div>"; //红色警告框
很多时候.我们需要报表的功能.如导出Excel.如生成图表.
<script> var idTmr; function getExplorer() { var explorer = window.navigator.userAgent; //ie if (explorer.indexOf("MSIE") >= 0) { return 'ie'; } //firefox else if (explorer.indexOf("Firefox") >= 0) { return 'Firefox'; } //Chrome else if (explorer.indexOf("Chrome") >= 0) { return 'Chrome'; } //Opera else if (explorer.indexOf("Opera") >= 0) { return 'Opera'; } //Safari else if (explorer.indexOf("Safari") >= 0) { return 'Safari'; } } $scope.ImportEmployeeExcel = function () { if (getExplorer() == 'ie') { var curTbl = document.getElementById("Whitelist"); var oXL = new ActiveXObject("Excel.Application"); var oWB = oXL.Workbooks.Add(); var xlsheet = oWB.Worksheets(1); var sel = document.body.createTextRange(); sel.moveToElementText(curTbl); sel.select(); sel.execCommand("Copy"); xlsheet.Paste(); oXL.Visible = true; try { var fname = oXL.Application.GetSaveAsFilename("Excel.xls", "Excel Spreadsheets (*.xls), *.xls"); } catch (e) { print("Nested catch caught " + e); } finally { oWB.SaveAs(fname); oWB.Close(savechanges = false); oXL.Quit(); oXL = null; idTmr = window.setInterval("Cleanup();", 1); } } else { tableToExcel("Whitelist") } } var tableToExcel = (function () { var uri = 'data:application/vnd.ms-excel;base64,', template = '<html><head><meta charset="UTF-8"></head><body><table>{table}</table></body></html>', base64 = function (s) { return window.btoa(unescape(encodeURIComponent(s))) }, format = function (s, c) { return s.replace(/{(w+)}/g, function (m, p) { return c[p]; }) } return function (table, name) { if (!table.nodeType) table = document.getElementById(table) var ctx = { worksheet: name || 'Worksheet', table: table.innerHTML } window.location.href = uri + base64(format(template, ctx)) } })() }); </script>
以上代码支持主流浏览器的表单导出Excel.调用方法 ng-click="ImportEmployeeExcel()" document.getElementById改成自己的表格Id就行
在报表的时候.需要一些柱图.饼图.更简单粗暴的完成展示.在此以Chart.js实现.
引入一下插件
<link rel="stylesheet" type="text/css" href="~/Template/Admin/jucheap/js/chart-js/normalize.css" />
<script type="text/javascript" src="~/Template/Admin/jucheap/js/Chart.js"></script>
js如下
var canvasBarData = { labels: ["1", "2", "3", "4", "5", "6", "7"], datasets: [ { fillColor: "rgba(49,111,186,0.9)", strokeColor: "rgba(49,111,186,1)", highlightFill: "rgba(49,111,186,0.70)", highlightStroke: "rgba(49,111,186,0.85)", data: [40, 50, 60, 70, 80, 90, 100] } ] } var pieData = [ { value: "30", color: "#fe7200", highlight: "#ff8a2b", label: "空闲" }, { value: "70", color: "#316fba", highlight: "#6e9acf", label: "占用" } ]; window.onload = function () { var Bar = document.getElementById("canvasBar").getContext("2d"); new Chart(Bar).Bar(canvasBarData);//柱状图 var Pie = document.getElementById("canvasPie").getContext("2d"); new Chart(Pie).Pie(pieData);//饼图 // { responsive: true } 图表的响应式属性.非常难看 }
html如下
<canvas id="canvasBar"></canvas>
<canvas id="canvasPie" />
最终效果如下
有动画效果还是很棒的
很多时候我们需要时间控件.但是bootstrap的时间控件默认是全英文.对于一些年长的领导难免不方便
引入一下插件
<link href="~/Scripts/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<script src="~/Scripts/moment-with-locales.min.js"></script>
<script src="~/Scripts/bootstrap-datetimepicker.min.js"></script>
js 如下
$('#datetimepicker1').datetimepicker({
format: 'YYYY-MM-DD',
locale: moment.locale('zh-cn')
});
HTML 如下
<div class="form-group col-sm-6 has-Standard"> <label class="control-label col-sm-5">开始时间</label> <div class="input-group date col-sm-7" id="datetimepicker1"> <input type="text" class="form-control" id="barStratDate"> <span class="input-group-addon"> <span class="glyphicon glyphicon-calendar"></span> </span> </div> </div>
效果如下