.Net MVC&&datatables.js&&bootstrap做一個界面的CRUD有多簡單
我們在項目開發中,個界做得最多的有多可能就是CRUD,那么我們如何在ASP.NET MVC中來做CRUD呢?如果說只是簡單單純實現功能,那自然是個界再簡單不過了,可是有多我們要考慮如何來做得比較好維護比較好擴展,如何做得比較漂亮。簡單做開發要有工匠精神,個界不要只求完成開發任務,有多那樣的簡單話,永遠停留在只是個界簡單的寫業務邏輯代碼水平,我們要做有追求的有多程序員。本來這么簡單的簡單東西,我真是個界懶得寫,但是有多看到即便是一些工作了好些年的人,做東西也是簡單只管實現功能,啥都不管,還有些界面css樣式要么就硬編要么就毫無規則的在頁面中進行穿插,遇到要設置間距甚至直接寫多個 ,我覺得還是要寫出來給那些人看下。硬編的前提是只有你這一個界面使用。
我們先來看下我們要實現的效果,功能需要:新增、修改、刪除、查詢、分頁、排序、導出excel、打印、上傳圖片、支持表單驗證,優雅的實現有多簡單?非常簡單。
需要用到哪些UI組件?我都是基于bootstrap這種扁平化響應式風格的,jquery.dataTables.js、toastr.js、bootstrapValidator.js、bootstrap-confirmation.js、printThis.js
由于是演示用,所以控制器中直接調用了EF上下文操作,重點是看前端部分的渲染和交互,不要重復你的代碼!不要重復你的代碼!不要重復你的代碼!重要的事情說三遍!為什么沒有用mvc自帶的模型驗證?答:太傻逼!1、樣式改起來操蛋;2、每次要點擊提交表單才促發驗證。
這里表數據量少,是直接一次性加載,然后內存中分頁的,如果表數據量多,那么就要用服務器分頁,同樣很簡單。修改下配置項,如下所示:然后控制器中對應的方法稍微修改下即可。
options.bServerSide = true;,
options.fnServerParams = function (aoData) { //查詢條件 aoData.push( { "name": "LogName", "value": $("#LogName").val() } ); };
BaseController控制器基類

[PublicAuthorize] public class BaseController : Controller { HomeService _HomeService = new HomeService(); #region 字段 /// <summary> /// 新增 /// </summary> protected string CText = "新增"; /// <summary> /// 讀取 /// </summary> protected string RText = "讀取"; /// <summary> /// 更新 /// </summary> protected string UText = "更新"; /// <summary> /// 刪除 /// </summary> protected string DText = "刪除"; /// <summary> /// 數據有誤! /// </summary> protected string VoidText = "數據有誤!"; #endregion #region 屬性 /// <summary> /// 獲取點擊的菜單ID /// </summary> public string MenuId { get { return Request.QueryString["MenuId"]; } } /// <summary> /// 自動構建頁面標題導航 /// </summary> public MvcHtmlString HeadString { get { return new MvcHtmlString(_HomeService.GetHead(int.Parse(MenuId))); } } /// <summary> /// 構造非菜單頁的界面導航標題 /// </summary> /// <param name="title">頁面標題</param> public void CreateSubPageHead(string title) { ViewBag.HeadString = HeadString; ViewBag.MenuId = MenuId; ViewBag.SubHeadString = title; } #endregion [HttpGet] public virtual ActionResult Index() { if (!string.IsNullOrEmpty(MenuId)) { ViewBag.MenuId = MenuId; ViewBag.HeadString = HeadString; } return View(); } /// <summary> /// 操作成功 /// </summary> /// <param name="message">提示文本</param> /// <returns></returns> protected virtual AjaxResult SuccessTip(string message) { return new AjaxResult { state = ResultType.success.ToString(), message = message }; } /// <summary> /// 操作失敗 /// </summary> /// <param name="message">提示文本</param> /// <returns></returns> protected virtual AjaxResult ErrorTip(string message) { return new AjaxResult { state = ResultType.error.ToString(), message = message }; } }View Code
控制器DefaultController

public class DefaultController : BaseController { private MyContext db = new MyContext(); /// <summary> /// 客戶列表 /// </summary> /// <param name="filter"></param> /// <returns></returns> [HttpPost] public JsonResult List(Customer filter) { //filter.PageSize = int.MaxValue; IQueryable<Customer> dataSource = db.Customers; if (!string.IsNullOrEmpty(filter.Name)) { dataSource = dataSource.Where(x => x.Name == filter.Name).OrderBy(x => x.CreateTime); } List<Customer> queryData = dataSource.ToList(); var data = queryData.Select(u => new { ID = u.Id, Name = u.Name, CreateTime = u.CreateTime.ToDateStr(), Address = u.Address }); //構造成Json的格式傳遞 var result = new { iTotalRecords = queryData.Count, iTotalDisplayRecords = 10, data = data }; return Json(result, JsonRequestBehavior.AllowGet); } #region CRUD [HttpGet] public ActionResult Create() { return View(); } [HttpPost] public JsonResult Create([Bind(Include = "Name,Address,CreateTime,Msg,HeadsUrl")] Customer _Customer) { AjaxResult _AjaxResult = null; if (ModelState.IsValid) { db.Customers.Add(_Customer); _AjaxResult = db.SaveChanges() > 0 ? SuccessTip(string.Format("{ 0}成功!", CText)) : ErrorTip(string.Format("{ 0}失敗!", CText)); ; } else { _AjaxResult = ErrorTip(VoidText); } return Json(_AjaxResult, JsonRequestBehavior.AllowGet); } [HttpGet] public ActionResult Update(int Id) { var model = db.Customers.Where(x => x.Id == Id).FirstOrDefault(); return View(model); } [HttpPost] public JsonResult Update([Bind(Include = "Id,Name,Address,CreateTime,Msg,HeadsUrl")] Customer _Customer) { AjaxResult _AjaxResult = null; if (ModelState.IsValid) { db.Entry(_Customer).State = EntityState.Modified; _AjaxResult = db.SaveChanges() > 0 ? SuccessTip(string.Format("{ 0}成功!", UText)) : ErrorTip(string.Format("{ 0}失敗!", UText)); } else { _AjaxResult = ErrorTip(VoidText); } return Json(_AjaxResult, JsonRequestBehavior.AllowGet); } [HttpPost] public JsonResult Delete(int Id) { var model = db.Customers.Where(x => x.Id == Id).FirstOrDefault(); db.Customers.Remove(model); AjaxResult _AjaxResult = db.SaveChanges() > 0 ? SuccessTip(string.Format("{ 0}成功!", DText)) : ErrorTip(string.Format("{ 0}失敗!", DText)); return Json(_AjaxResult, JsonRequestBehavior.AllowGet); } [HttpPost] public JsonResult DeleteList(List<int> ids) { var list = db.Customers.Where(x => ids.Contains(x.Id)).ToList(); db.Customers.RemoveRange(list); AjaxResult _AjaxResult = db.SaveChanges() > 0 ? SuccessTip(string.Format("{ 0}成功!", DText)) : ErrorTip(string.Format("{ 0}失敗!", DText)); return Json(_AjaxResult, JsonRequestBehavior.AllowGet); } #endregion #region File handle /// <summary> /// 導出Excel /// </summary> /// <returns></returns> public FileResult ExportExcel() { string excelPath = Server.MapPath("~/Excel/用戶列表.xls"); GenerateExcel genExcel = new GenerateExcel(); genExcel.SheetList.Add(new UserListSheet(db.Customers.ToList(), "用戶列表")); genExcel.ExportExcel(excelPath); return File(excelPath, "application/ms-excel", "用戶列表.xls"); } /// <summary> /// 上傳文件 /// </summary> /// <returns></returns> public JsonResult ExportFile() { HttpPostedFileBase file = Request.Files["txt_file"]; uploadFile _uploadFile = new uploadFile(); if (file != null) { string str = DateTime.Now.ToString("yyyyMMddhhMMss"); var fileFullName =string.Format("{ 0}{ 1}_{ 2}",Request.MapPath("~/Upload/"),str ,file.FileName); try { file.SaveAs(fileFullName); _uploadFile.state = 1; } catch { _uploadFile.state = 0; } finally { _uploadFile.name = str+"_"+file.FileName; _uploadFile.fullName = fileFullName; } } else { _uploadFile.state = 0; } return Json(_uploadFile, JsonRequestBehavior.AllowGet); } /// <summary> /// 刪除文件 /// </summary> /// <returns></returns> [HttpPost] public JsonResult DeleteFile(string key) { var fileFullName = Path.Combine(Request.MapPath("~/Upload"), key); int state = 0; try { state = FileHelper.DeleteFile(fileFullName) ? 1 : 0; //var model = db.Customers.Where(x => x.HeadsUrl == key).FirstOrDefault(); //if(model!=null) //{ // db.Customers.Remove(model); //} } catch { state = 0; } return Json(state, JsonRequestBehavior.AllowGet); } #endregion }View Code
視圖頁面,razor、css、js都分離,不要放到一個文件中。
Index視圖:

@model List<Secom.Smp.Data.Models.Customer>@{ ViewBag.Title = "用戶列表"; ViewBag.ParentTitle = "系統管理"; Layout = "~/Views/Shared/_Page.cshtml";}<style type="text/css"> .divModal { width: 700px; }</style><div class="page-content-body"> <div class="row"> <div class="col-md-12"> <!-- BEGIN EXAMPLE TABLE PORTLET--> <div class="portlet-title"> <div class="caption font-dark"> <i class="icon-settings font-dark"></i> <span class="caption-subject bold uppercase">用戶列表</span> </div> <div class="actions"> </div> </div> <div class="portlet-body"> <div class="table-toolbar"> <div class="row"> <div class="col-md-6"> <div class="btn-group"> <button id="btnAdd" class="btn sbold green" onclick="DataTablesObj.doCreateModal('/Admin/Default/Create')" data-toggle="modal">添加用戶<i class="fa fa-plus"></i></button> <button id="btnDeleteList" title="確定要刪除嗎?" class="btn sbold btn-danger deleteBtn" data-toggle="confirmation" data-placement="right" data-btn-ok-label="繼續" data-btn-ok-icon="icon-like" data-btn-ok-class="btn-success" data-btn-cancel-label="取消" data-btn-cancel-icon="icon-close" data-btn-cancel-class="btn-danger"> 批量刪除 <i class="fa fa-minus"></i> </button> </div> </div> <div class="col-md-6"> <div class="btn-group pull-right"> <button class="btn green btn-outline dropdown-toggle" data-toggle="dropdown"> 操作 <i class="fa fa-angle-down"></i> </button> <ul class="dropdown-menu pull-right"> <li> <a href="/Admin/Default/ExportExcel" target='_blank' class="fa fa-file-excel-o"><span style="margin-left:10px;"> 導出Excel </span></a> </li> <li> <a href="#" class="fa fa-file-excel-o" id="printView"><span style="margin-left:10px;"> 打印預覽</span></a> </li> </ul> </div> </div> </div> </div> <table class="table table-striped table-bordered table-hover table-checkable order-column" id="table_local"></table> </div> <!--模態彈窗--> <div class="modal fade" id="defaultModal" tabindex="-1" role="dialog" aria-labelledby="defaultModalLabel" aria-hidden="true"> <div class="modal-dialog divModal" role="document"> <div class="modal-content"> </div> </div> </div> <!-- END EXAMPLE TABLE PORTLET--> </div> </div></div>@section scripts{ <script src="@Html.ScriptsPath("lib/printThis.js")"></script>}View Code
Create視圖:

@model Secom.Smp.Data.Models.Customer@{ ViewBag.Title = "Create"; Layout = "~/Views/Shared/_Form.cshtml";}<div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="defaultModalLabel">添加用戶</h4></div>@using (Html.BeginForm("Create", "Default", new { area = "Admin" }, FormMethod.Post, new { @id = "defaultForm" })) { <div class="modal-body"> <div class="row"> <div class="col-md-5"> <div class="form-group"> @Html.LabelFor(x => x.HeadsUrl,new { @class = "control-label" }): <input type="file" id="txt_file" name="txt_file" class="file-loading" accept="image/*" /> @Html.HiddenFor(x=>x.HeadsUrl,new { @id = "hidFileUrl" }) </div> </div> <div class="col-md-7"> <div class="form-group"> @Html.LabelFor(x => x.Name, new { @class = "control-label" }): @Html.TextBoxFor(x => x.Name, new { @id = "Name", @placeholder = "請輸入用戶名", @class = "form-control" }) </div> <div class="form-group"> @Html.LabelFor(x => x.Address, new { @class = "control-label" }): @Html.TextBoxFor(x => x.Address, new { @id = "Address", @placeholder = "請輸入地址", @class = "form-control" }) </div> <div class="form-group"> @Html.LabelFor(x => x.CreateTime): <div class="input-group input-medium date date-picker"> @Html.TextBoxFor(x => x.CreateTime, new { @class = "form-control", @readonly = true }) <span class="input-group-btn"> <button class="btn default" type="button"> <i class="fa fa-calendar"></i> </button> </span> </div> </div> </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">關閉</button> <button type="submit" class="btn sbold green">提交</button> </div>}@section scripts{ }View Code
Update視圖:

@model Secom.Smp.Data.Models.Customer@{ ViewBag.Title = "Update"; Layout = "~/Views/Shared/_Form.cshtml";}<div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="defaultModalLabel">修改用戶</h4></div> @using (Html.BeginForm("Update", "Default", new { area = "Admin" }, FormMethod.Post, new { @id = "updateForm" })) { @Html.HiddenFor(x=>x.Id) <div class="modal-body"> <div class="row"> <div class="col-md-5"> <div class="form-group"> @Html.LabelFor(x => x.HeadsUrl, new { @class = "control-label" }): <input type="file" id="txt_file" name="txt_file" class="file-loading" accept="image/*" /> @Html.HiddenFor(x => x.HeadsUrl, new { @id = "hidFileUrl" }) </div> </div> <div class="col-md-7"> <div class="form-group"> @Html.LabelFor(x => x.Name, new { @class = "control-label" }): @Html.TextBoxFor(x => x.Name, new { @id = "Name", @placeholder = "請輸入用戶名", @class = "form-control" }) </div> <div class="form-group"> @Html.LabelFor(x => x.Address, new { @class = "control-label" }): @Html.TextBoxFor(x => x.Address, new { @id = "Address", @placeholder = "請輸入地址", @class = "form-control" }) </div> <div class="form-group"> @Html.LabelFor(x => x.CreateTime): <div class="input-group input-medium date date-picker"> @Html.TextBoxFor(model => model.CreateTime, new { @type = "date", @class = "form-control", @readonly = true, @Value = Model.CreateTime.ToDateStr(),@id= "CreateTime" }) <span class="input-group-btn"> <button class="btn default" type="button"> <i class="fa fa-calendar"></i> </button> </span> </div> </div> </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">關閉</button> <button type="submit" class="btn sbold green">提交</button> </div> } @section scripts{ }View Code
_Form模板頁視圖
<!DOCTYPE html><html><head> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title></head><body> @RenderBody() @RenderSection("scripts", required: false) @Html.AutoLoadPageJs()</body></html>
看下這個自定義的擴展方法AutoLoadPageJs方法,其實就是模擬mvc的路由尋址方式去找指定目錄下面的js
/// <summary> /// 根據mvc路由自動加載js文件(如果不存在則不加載) /// </summary> /// <param name="helper"></param> /// <returns></returns> public static MvcHtmlString AutoLoadPageJs(this HtmlHelper helper) { var areas = helper.ViewContext.RouteData.DataTokens["area"]; var action = helper.ViewContext.RouteData.Values["action"]; var controller = helper.ViewContext.RouteData.Values["controller"]; string url = areas == null ? string.Format("views/{ 0}/{ 1}", controller, action) : string.Format("views/areas/{ 2}/{ 0}/{ 1}", controller, action, areas); return LoadJsString(helper,url); } /// <summary> /// 構造js加載的html字符串 /// </summary> /// <param name="helper"></param> /// <param name="url">js文件路徑</param> /// <returns></returns> public static MvcHtmlString LoadJsString(HtmlHelper helper, string url) { var jsBuilder = new StringBuilder(); string jsLocation = "/content/release-js/";#if DEBUG jsLocation = "/content/js/";#endif string jsFullUrl = Path.Combine(jsLocation, url + ".js"); if (File.Exists(helper.ViewContext.HttpContext.Server.MapPath(jsFullUrl))) { jsBuilder.AppendFormat("<script src=\"{ 0}\"></script>", jsFullUrl); } return new MvcHtmlString(jsBuilder.ToString()); }
我們看下View對應的js文件
index.js
$(function () { //-------------初始化datatable var obj = DataTablesObj; obj.showReadBtn = false;//顯示詳情按鈕 obj.showDeleteBtn = true;//顯示刪除按鈕 obj.showUpdateBtn = true;//顯示更新按鈕 obj.updateUrl = "/Admin/Default/Update"; obj.deleteUrl = "/Admin/Default/Delete"; obj.batchDeleteUrl = "/Admin/Default/DeleteList";//批量刪除路徑 obj.options.columns = [{ title: "", "visible": false, "data": "ID" }, obj.checboxFied, { "data": "Name", title: "用戶名稱" }, { "data": "Address", title: "用戶地址" }, { "data": "CreateTime", title: "創建時間" }, obj.opratorFiled ]; obj.options.searching = true; obj.options.sAjaxSource = "/Admin/Default/List"; //數據源地址 obj.init(obj.options); //表單驗證配置項 FormValidatorObj.options.fields = { Name: { message: '用戶名驗證失敗', validators: { notEmpty: { message: '用戶名不能為空' } } }, Address: { validators: { notEmpty: { message: '地址不能為空' } } } }; //打印預覽 $("#printView").on("click", function () { $("#table_local").printThis({ debug: false,// 調試模式下打印文本的渲染狀態 importCSS: true, importStyle: true, printContainer: true, //loadCSS: "/Content/bootstrap.css", pageTitle: "用戶列表", removeInline: false, printDelay: 333, header: null, formValues: true, header: "<h1>用戶列表</h1>", footer: null }); })})
create.js
$(function () { DatetimepickerObj.init('CreateTime');//(控件ID) //--------------表單驗證 FormValidatorObj.init("defaultForm","defaultModal","table_local"); //(表單id,[modal容器Id],[datable容器ID]) //初始化編輯界面的數據 //--------------添加界面中的上傳控件 FileInputObj.init(undefined,"txt_file", "hidFileUrl", "/Admin/Default/ExportFile",true); //配置項,控件ID,存儲文件路徑的控件ID,上傳路徑,是否新增頁面});
update.js
$(function () { DatetimepickerObj.init('CreateTime');//(控件ID) //--------------表單驗證 FormValidatorObj.init("updateForm","defaultModal","table_local"); //(表單id,[modal容器Id],[datable容器ID]) //初始化編輯界面的數據 //([配置項],控件ID,存儲文件路徑的控件ID,圖片路徑,上傳路徑,刪除路徑) FileInputObj.initUpdateImg(undefined,"txt_file", "hidFileUrl", "/Admin/Default/ExportFile", "/Admin/Default/DeleteFile");})
看上去比較多的界面功能,你看下,代碼就這么點,而且各自職責很清晰。對datatables.js組件進行二次封裝,base-Datatable.js代碼如下:

// ajax加載調試用//# sourceURL=base-Datatable.js//DataTables表格組件擴展對象--created by zouqj 2017-7-03var DataTablesObj = (function () { //------------------------------靜態全局屬性------------------------------------- var infoStr = "總共 <span class='pagesStyle'>(_PAGES_) </span>頁,顯示 _START_ -- _END_ ,共<span class='recordsStyle'> (_TOTAL_)</span> 條"; var lengthMenuStr = '每頁顯示:<select class="form-control input-xsmall">' + '<option value="5">5</option>' + '<option value="10">10</option>' + '<option value="20">20</option>' + '<option value="30">30</option>' + '<option value="50">50</option>' + '<option value="100">100</option>' + '<option value="150">150</option>' + '<option value="200">200</option>' + '<option value="250">250</option>' + '<option value="500">500</option>'; this.table_local = "table_local"; //table ID this.chkAllColl = "chkAllColl"; //全選按鈕ID this.modalId = "defaultModal"; //模態窗體ID this.batchDeleteBtn = "btnDeleteList"; //批量刪除按鈕ID this.deleteBtn = "btnDelete"; //刪除按鈕ID this.autoIncrement={ 'title': '序號', 'data': null, 'bSortable': false,'render': function (data, type, full, meta) { return meta.row + 1 + meta.settings._iDisplayStart;}}; // 序號 //操作列 this.opratorFiled = { "data": "ID", orderable: false, title: "操作", "render": function (data, type, row, meta) { //自定義列 var re = "<div class='operatorDiv'></i>"; if (DataTablesObj.showReadBtn) { var temp = DataTablesObj.detailModal == undefined ? data : data + ",'" + DataTablesObj.detailModal+"'"; re += "<a class='' type='button' data-toggle='dropdown' aria-expanded='false' onclick=\"DataTablesObj.doReadModal(" + temp + ")\">詳情</a>"; } if (DataTablesObj.showUpdateBtn) { var temp = DataTablesObj.updateModal == undefined ? data : data + ",'" + DataTablesObj.updateModal + "'"; re += "<a class='' type='button' onclick='DataTablesObj.doUpdateModal(" + temp + ")'>編輯</a>"; } if (DataTablesObj.showDeleteBtn) { re += "<a class='' title='確定要刪除嗎?' data-toggle='confirmation' data-placement='left' data-btn-ok-label='繼續' data-btn-ok-icon='icon-like' data-btn-ok-class='btn-success toastrBtn' data-btn-cancel-label='取消' data-btn-cancel-icon='icon-close' data-btn-cancel-class='btn-danger' type='button' onclick='DataTablesObj.doDelete(this," + data + ")'>刪除</a>"; } re += "</div>"; return re; } }; //復選框列 this.checboxFied = { "data": "ID", title: "<input type='checkbox' id='chkAllColl' onclick='DataTablesObj.selectAll()'/>", orderable: false, "render": function (data, type, row, meta) { return "<input id='cbx" + data + "' name='chkItem' type='checkbox' onclick='DataTablesObj.controlSelectAll(" + data + ")' class='cbx' value='" + data + "'/> "; } }; //------------------------------變化部分的屬性------------------------------------- this.batchDeleteUrl = "";//批量刪除路徑 this.deleteUrl = ""; //單條記錄刪除路徑 this.showReadBtn = true;//默認不顯示詳情按鈕 this.showDeleteBtn = false;//默認不顯示刪除按鈕 this.showUpdateBtn = false;//默認顯示更新按鈕 this.readUrl = ""; //單條記錄讀取路徑 this.updateUrl = "";//更新界面URL地址 this.detailModal = undefined; //詳情頁面的modalId this.updateModal = undefined;//修改頁面的modalId //------------------------------事件、方法------------------------------------- document.onkeydown = function (event) { var e = event || window.event || arguments.callee.caller.arguments[0]; if (e && e.keyCode == 27) { // 按 Esc //要做的事情 } if (e && e.keyCode == 13) { // enter 鍵 //要做的事情 DataTablesObj.reloadList(DataTablesObj.table_local); } }; ////對行單擊添加監聽事件 //$('#table_local tbody').on('click', 'tr', function () { // var tr = $(this).closest('tr'); // var checkbox = tr.find('td:first-child input:checkbox')[0]; // checkbox.checked = !checkbox.checked; //}); //獲Ggridview中所有的復選框 sName: Gridview 的ID this.getCheckbox = function (sName) { var aryCheckbox = new Array(); var tb = document.getElementById(sName); if (tb == null) return; var objs = tb.getElementsByClassName("cbx"); for (var i = 0; i < objs.length; i++) { if (objs[i].type == 'checkbox') aryCheckbox.push(objs[i]); } return aryCheckbox; }; //監聽每一行的復選框,控制全選、反選按鈕 this.controlSelectAll = function (i) { var tblName, cbkAll; //Gridview ID ,全選框ID var tblName = DataTablesObj.table_local; var cbkAll = DataTablesObj.chkAllColl; var id = "#cbx" + i; //點擊復選框選中行 //if ($(id)[0].checked == true) { // $(id).parent().parent().addClass('selected'); // $(id).parent().parent().siblings().removeClass('selected'); //} else { // $(id).parent().parent().siblings().removeClass('selected'); // $(id).parent().parent().removeClass('selected'); //} var chks = DataTablesObj.getCheckbox(tblName); var count = 0; for (var i = 0; i < chks.length; i++) { if (chks[i].checked == true) { count++; } } if (count < chks.length) { document.getElementById(cbkAll).checked = false; } else { document.getElementById(cbkAll).checked = true; } }; //全選反選 this.selectAll = function () { var isChecked = $("#" + DataTablesObj.chkAllColl)[0].checked; $("input[name='chkItem']").prop("checked", isChecked); }; //查詢刷新([datatable ID]) this.reloadList = function (id) { var tableId = id == undefined ? DataTablesObj.table_local : id; var tables = $('#' + tableId).dataTable().api();//獲取DataTables的Api,詳見 http://www.datatables.net/reference/api/ tables.ajax.reload(); }; //