[ASP.NET Core MVC][Vue3][Dapper] 前後台網站公告範例 – 後台編輯頁面教學 #CH2
網站開發常見的一種功能是在後台新增維護資料,然後在前台顯示資料,類似網站公告或最新消息功能,此次教學將會教你如何建立後台公告維護界面,並在前台顯示資料。
此篇文章是接續上一篇文章 [ASP.NET Core MVC + Vue3 + Dapper] 前後台網站公告範例 – 後台查詢頁面教學 #CH1 的教學文章。
在上一篇文章裡我們完成了查詢頁面的製作,接著這篇會完成新增、修改及刪除功能。
此範例使用 ASP.NET Core MVC 版本是 .NET6,前端使用 Vue3 框架,後端資料庫使用 SQL Server 2019,使用 Dapper 套件連線,文末有範例可以下載。
新增公告功能
開啟 \Views\AdmAnno\Index.cshtml,新增公告的畫面設計同樣在這檔案內實作,在 Html 內我將不同的功能用不同的 Div 區隔開來,並給定 id 以方便做隱藏與顯示。
加入新增畫面設計
查詢的區域 id 是 “QueryPanel”,在 <div id="QueryPanel" class="card">
結束的位置繼續加上新增畫面設計。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
<div id="AddPanel" class="card" style="display:none;"> <div class="card-header"> 新增公告 <div style="float:right;"> <button type="button" class="btn btn-secondary btn-sm" v-on:click="BackPage()">回前頁</button> </div> </div> <div class="card-body"> <div class="row"> <div class="col-auto"> <label for="addFormAnnoDate" class="col-form-label">公告日期</label> </div> <div class="col-auto"> <input type="text" id="addFormAnnoDate" class="form-control" v-model="addForm.AnnoDate"> </div> </div> <div class="row"> <div class="col-auto"> <label for="addFormAnnoSubject" class="col-form-label">公告主題</label> </div> <div class="col-auto"> <input type="text" id="addFormAnnoSubject" class="form-control" v-model="addForm.AnnoSubject"> </div> </div> <div class="row"> <div class="col-auto"> <label for="addFormAnnoContent" class="col-form-label">公告內容</label> </div> <div class="col-auto"> <textarea id="addFormAnnoContent" class="form-control" v-model="addForm.AnnoContent"></textarea> </div> </div> <div class="row"> <div class="col-auto"> <label for="addFormAnnoStatus" class="col-form-label">公告狀態</label> </div> <div class="col-auto"> <select class="form-select" id="addFormAnnoStatus" v-model="addForm.AnnoStatus"> <option value="1">顯示</option> <option value="0">隱藏</option> </select> </div> </div> </div> <div class="card-footer"> <button type="button" class="btn btn-primary" v-on:click="AddSave()">儲存</button> </div> </div> |
這裡多了兩個方法 BackPage()
與 AddSave()
,接著在下面的 Vue3 語法加入兩個新方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
// 回前頁 , BackPage() { $('#QueryPanel').show(); $('#AddPanel').hide(); $('#EditPanel').hide(); } // 新增儲存 , AddSave() { var self = this; // 組合表單資料 var postData = {}; postData['AnnoDate'] = self.addForm.AnnoDate; postData['AnnoSubject'] = self.addForm.AnnoSubject; postData['AnnoContent'] = self.addForm.AnnoContent; postData['AnnoStatus'] = self.addForm.AnnoStatus; $.blockUI(); // 使用 jQuery Ajax 傳送至後端 $.ajax({ url:'@Url.Content("~/AdmAnno/AddSave")', method:'POST', dataType:'json', data: { inModel: postData , __RequestVerificationToken: $('@Html.AntiForgeryToken()').val()}, success: function (datas) { $.unblockUI(); if (datas.ErrMsg) { alert(datas.ErrMsg); return; } alert(datas.ResultMsg); self.BackPage(); self.Query(); }, error: function (err) { $.unblockUI(); alert(err.status + " " + err.statusText + '\n' + err.responseText); } }); } |
增加 vue 物件
一個表單的傳送,我會新增對應的 form 物件,在 Vue3 的 data 區增加新增 form 物件。
1 2 3 4 5 6 |
, addForm:{ AnnoDate: '' , AnnoSubject: '' , AnnoContent: '' , AnnoStatus: '1' } |
加入 bootstrap-datepicker 套件
我設計的欄位裡面有一個日期欄位,當使用者要輸入日期時,有日期選取套件會方便輸入,這裡我提供一個我常用的日期選取套件:bootstrap-datepicker
打開 \Views\Shared\_Layout.cshtml 在 css 增加此引用:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css">
在 Javascript增加此引用:
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
設定日期選取套件
回到 index.cshtml,新增公告日期的欄位 id 是 “addFormAnnoDate”,然後在最下方增加 jQuery 的語法綁定日期選取。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$(function () { //Date picker $('#addFormAnnoDate').datepicker({ autoclose: true , format: "yyyy/mm/dd" }); $("#addFormAnnoDate").datepicker().on("blur", function (e) { vm.$data.addForm.AnnoDate = $(this).val(); }); $("#addFormAnnoDate").datepicker().on("change", function (e) { vm.$data.addForm.AnnoDate = $(this).val(); }); }); |
新增公告 Controller 語法
打開 \Controllers\AdmAnnoController.cs,加入新方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
/// <summary> /// 新增公告 /// </summary> /// <param name="inModel"></param> /// <returns></returns> [ValidateAntiForgeryToken] public IActionResult AddSave(AddSaveIn inModel) { AddSaveOut outModel = new AddSaveOut(); // 檢查參數 if (ModelState.IsValid == false) { outModel.ErrMsg = string.Join("\n", ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage)); return Json(outModel); } // 資料庫連線字串 string connStr = _configuration.GetConnectionString("SqlServer"); using (var conn = new SqlConnection(connStr)) { string sql = @"INSERT INTO Announcement(AnnoDate, AnnoSubject, AnnoContent, AnnoStatus) VALUES (@AnnoDate, @AnnoSubject, @AnnoContent, @AnnoStatus)"; var param = new { AnnoDate = inModel.AnnoDate, AnnoSubject = inModel.AnnoSubject, AnnoContent = inModel.AnnoContent, AnnoStatus = inModel.AnnoStatus }; // 使用 Dapper conn.Execute(sql, param); } outModel.ResultMsg = "新增完成"; return Json(outModel); } |
新增公告 ViewModel 語法
打開 \Models\AdmAnnoViewModel.cs,加入新 Model:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class AddSaveIn { [Required] public string AnnoDate { get; set; } [Required] public string AnnoSubject { get; set; } [Required] public string AnnoContent { get; set; } [Required] public string AnnoStatus { get; set; } } public class AddSaveOut { public string ErrMsg { get; set; } public string ResultMsg { get; set; } } |
顯示新增頁面按鈕
完成了新增功能語法,接著在查詢頁面增加一個按鈕,當按下時,可以切換至新增畫面。
我在查詢鈕旁邊加入新增按鈕。
<button type="button" class="btn btn-primary" v-on:click="OpenAddPanel()">新增</button>
然後在 Vue3 增加一方法:
1 2 3 4 5 6 7 8 9 10 11 12 |
// 新增視窗 , OpenAddPanel() { var self = this; $('#QueryPanel').hide(); $('#AddPanel').show(); self.addForm.AnnoDate = ''; self.addForm.AnnoSubject = ''; self.addForm.AnnoContent = ''; self.addForm.AnnoStatus = '1'; } |
測試新增功能
按 F5 執行專案,按下「新增」功能就會切換至新增頁面。
點選日期欄位就會出現日期選取功能。
輸入資料按「儲存」即會新增資料至資料庫內。
新增完成後,查詢頁面就會顯示剛剛新增的資料。
修改公告功能
接著我們就繼續實作修改功能,我會在查詢列表資料前面加上編輯按鈕,點擊後切換至修改頁面,修改完按儲存後寫入資料庫並回至查詢頁面。
加入修改畫面設計
在 <div id="AddPanel" class="card" style="display:none;">
結束的位置繼續加上修改畫面設計。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
<div id="EditPanel" class="card" style="display:none;"> <div class="card-header"> 修改公告 <div style="float:right;"> <button type="button" class="btn btn-secondary btn-sm" v-on:click="BackPage()">回前頁</button> </div> </div> <div class="card-body"> <div class="row"> <div class="col-auto"> <label for="editFormAnnoDate" class="col-form-label">公告日期</label> </div> <div class="col-auto"> <input type="text" id="editFormAnnoDate" class="form-control" v-model="editForm.AnnoDate"> </div> </div> <div class="row"> <div class="col-auto"> <label for="editFormAnnoSubject" class="col-form-label">公告主題</label> </div> <div class="col-auto"> <input type="text" id="editFormAnnoSubject" class="form-control" v-model="editForm.AnnoSubject"> </div> </div> <div class="row"> <div class="col-auto"> <label for="editFormAnnoContent" class="col-form-label">公告內容</label> </div> <div class="col-auto"> <textarea id="editFormAnnoContent" class="form-control" v-model="editForm.AnnoContent"></textarea> </div> </div> <div class="row"> <div class="col-auto"> <label for="editFormAnnoStatus" class="col-form-label">公告狀態</label> </div> <div class="col-auto"> <select class="form-select" id="editFormAnnoStatus" v-model="editForm.AnnoStatus"> <option value="1">顯示</option> <option value="0">隱藏</option> </select> </div> </div> </div> <div class="card-footer"> <button type="button" class="btn btn-primary" v-on:click="EditSave()">儲存</button> </div> </div> |
這裡多了新方法 EditSave(),接著在下面的 Vue3 語法加入新方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// 修改儲存 , EditSave() { var self = this; // 組合表單資料 var postData = {}; postData['Pkey'] = self.editForm.Pkey; postData['AnnoDate'] = self.editForm.AnnoDate; postData['AnnoSubject'] = self.editForm.AnnoSubject; postData['AnnoContent'] = self.editForm.AnnoContent; postData['AnnoStatus'] = self.editForm.AnnoStatus; $.blockUI(); // 使用 jQuery Ajax 傳送至後端 $.ajax({ url:'@Url.Content("~/AdmAnno/EditSave")', method:'POST', dataType:'json', data: { inModel: postData , __RequestVerificationToken: $('@Html.AntiForgeryToken()').val()}, success: function (datas) { $.unblockUI(); if (datas.ErrMsg) { alert(datas.ErrMsg); return; } alert(datas.ResultMsg); self.BackPage(); self.Query(); }, error: function (err) { $.unblockUI(); alert(err.status + " " + err.statusText + '\n' + err.responseText); } }); } |
加入編輯按鈕
編輯按鈕會放在 Grid 資料的前面,在查詢 Grid 加入一個欄位:
<th style="width: 30px;text-align:center;"></th>
<td><a v-on:click="EditMode(index)" style="cursor: pointer;">編</a></td>
這裡多了 EditMode(index)
方法,接著在 Vue3 也新增此方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// 修改模式 , EditMode(index) { var self = this; // 顯示資料 self.editForm.Pkey = self.grid.datas[index].Pkey; self.editForm.AnnoDate = self.grid.datas[index].AnnoDate; $('#editFormAnnoDate').datepicker("update", self.grid.datas[index].AnnoDate); self.editForm.AnnoSubject = self.grid.datas[index].AnnoSubject; self.editForm.AnnoContent = self.grid.datas[index].AnnoContent; self.editForm.AnnoStatus = self.grid.datas[index].AnnoStatus; $('#QueryPanel').hide(); $('#EditPanel').show(); } |
增加 vue 物件
在 Vue3 的 data 區增加新增 form 物件。
1 2 3 4 5 6 7 |
, editForm:{ Pkey:'' , AnnoDate: '' , AnnoSubject: '' , AnnoContent: '' , AnnoStatus: '1' } |
設定日期選取套件
修改區也有一個公告日期欄位, id 是 “editFormAnnoDate”,然後在最下方增加 jQuery 的語法綁定日期選取。
1 2 3 4 5 6 7 8 9 10 |
$('#editFormAnnoDate').datepicker({ autoclose: true , format: "yyyy/mm/dd" }); $("#editFormAnnoDate").datepicker().on("blur", function (e) { vm.$data.editForm.AnnoDate = $(this).val(); }); $("#editFormAnnoDate").datepicker().on("change", function (e) { vm.$data.editForm.AnnoDate = $(this).val(); }); |
修改公告 Controller 語法
打開 \Controllers\AdmAnnoController.cs,加入新方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
/// <summary> /// 修改公告 /// </summary> /// <param name="inModel"></param> /// <returns></returns> [ValidateAntiForgeryToken] public IActionResult EditSave(EditSaveIn inModel) { EditSaveOut outModel = new EditSaveOut(); // 檢查參數 if (ModelState.IsValid == false) { outModel.ErrMsg = string.Join("\n", ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage)); return Json(outModel); } // 資料庫連線字串 string connStr = _configuration.GetConnectionString("SqlServer"); using (var conn = new SqlConnection(connStr)) { string sql = @"UPDATE Announcement SET AnnoDate = @AnnoDate, AnnoSubject = @AnnoSubject, AnnoContent = @AnnoContent, AnnoStatus = @AnnoStatus WHERE Pkey = @Pkey"; var param = new { AnnoDate = inModel.AnnoDate, AnnoSubject = inModel.AnnoSubject, AnnoContent = inModel.AnnoContent, AnnoStatus = inModel.AnnoStatus, Pkey = inModel.Pkey }; // 使用 Dapper int ret = conn.Execute(sql, param); if (ret > 0) { outModel.ResultMsg = "修改完成"; } } return Json(outModel); } |
修改公告 ViewModel 語法
打開 \Models\AdmAnnoViewModel.cs,加入新 Model:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class EditSaveIn { [Required] public string Pkey { get; set; } [Required] public string AnnoDate { get; set; } [Required] public string AnnoSubject { get; set; } [Required] public string AnnoContent { get; set; } [Required] public string AnnoStatus { get; set; } } public class EditSaveOut { public string ErrMsg { get; set; } public string ResultMsg { get; set; } } |
測試修改功能
按 F5 執行專案,在查詢後,前面會出現 ”編” 按鈕。
點擊 “編” 後切換至修改頁面。
修改後儲存完成即會回到查詢頁面,並自動重新查詢。
刪除公告功能
這裡實作最後一個刪除功能。
我會在 Grid 前面增加一個勾選,在 Grid Header 區增加一個「全選/全不選」的勾選,然後在下方增加「勾選刪除」的按鈕。
增加刪除勾選及按鈕
在 index.cshtml 的 Grid 增加 Header 的勾選:
<th style="width: 30px;text-align:center;"><input type="checkbox" v-model="grid.headerCheck" v-on:change="HeaderCheck()" /></th>
在資料前面增加勾選:
<td align="center"><input type="checkbox" v-model="item.selCheck" /></td>
在 <table> 結束的位置加上刪除按鈕:
<div style="float:left">
<input type="button" class="btn btn btn-danger btn-sm" value="勾選刪除" v-on:click="DelCheck()" />
</div>
這裡多了兩個新方法 HeaderCheck()
與 DelCheck()
,接著在 Vue3 新增這兩個方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
// 全選/全不選 , HeaderCheck() { var self = this; for (var i in self.grid.datas) { // 狀態必須是可勾選 if (!self.grid.datas[i].selCheck.disabled && !self.grid.datas[i].selCheck.display) { self.grid.datas[i].selCheck = self.grid.headerCheck; } } } // 勾選刪除 , DelCheck() { var self = this; var cnt = 0; for (var i in self.grid.datas) { if (self.grid.datas[i].selCheck == true) { cnt += 1; } } if (cnt == 0) { alert('請勾選資料'); } else { if (confirm("是否確定刪除所勾選的 " + cnt + " 筆資料?")) { let checks = []; for (var i in self.grid.datas) { if (self.grid.datas[i].selCheck) { checks.push(self.grid.datas[i]); } } var postData = {}; postData['checks'] = checks; $.blockUI(); // 使用 jQuery Ajax 傳送至後端 $.ajax({ url:'@Url.Content("~/AdmAnno/DelCheck")', method:'POST', dataType:'json', data: { inModel: postData , __RequestVerificationToken: $('@Html.AntiForgeryToken()').val()}, success: function (datas) { $.unblockUI(); if (datas.ErrMsg) { alert(datas.ErrMsg); return; } alert(datas.ResultMsg); self.Query(); }, error: function (err) { $.unblockUI(); alert(err.status + " " + err.statusText + '\n' + err.responseText); } }); } } } |
調整 grid 物件
在 data 的 grid 物件,增加屬性:
, headerCheck: false
查詢方法增加屬性
勾選欄位是一個新屬性,需要在每個 grid.datas 都擁有,我們在查詢回傳之後,手動附加這個新屬性放到 datas 裡面。
1 2 3 4 |
// 附加勾選給刪除使用 for(var i in self.grid.datas){ self.grid.datas[i]['selCheck'] = false; } |
刪除公告 Controller 語法
打開 \Controllers\AdmAnnoController.cs,加入新方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
/// <summary> /// 刪除公告 /// </summary> /// <param name="inModel"></param> /// <returns></returns> [ValidateAntiForgeryToken] public IActionResult DelCheck(DelCheckIn inModel) { DelCheckOut outModel = new DelCheckOut(); // 檢查參數 if (inModel.checks.Count == 0) { outModel.ErrMsg = "缺少輸入資料"; return Json(outModel); } // 資料庫連線字串 string connStr = _configuration.GetConnectionString("SqlServer"); using (var conn = new SqlConnection(connStr)) { int ret = 0; foreach (AnnoModel model in inModel.checks) { string sql = @"DELETE Announcement WHERE Pkey = @Pkey"; var param = new { Pkey = model.Pkey }; // 使用 Dapper ret += conn.Execute(sql, param); } if (ret > 0) { outModel.ResultMsg = "成功刪除 " + ret + " 筆資料"; } } return Json(outModel); } |
刪除公告 ViewModel 語法
打開 \Models\AdmAnnoViewModel.cs,加入新 Model:
1 2 3 4 5 6 7 8 9 10 |
public class DelCheckIn { public List<AnnoModel> checks { get; set; } } public class DelCheckOut { public string ErrMsg { get; set; } public string ResultMsg { get; set; } } |
測試刪除功能
按 F5 執行專案,在查詢後前面會增加勾選,在上面的勾選可以執行全選或全不選的功能,在需要刪除的資料前面勾選,再按下方的「勾選刪除」即會刪除資料。
做到這裡恭喜你完成了全部的功能,這個後台維護界面對我來說是很標準的功能,有很多資料表的維護 (新增、修改、刪除、查詢) 都會用這樣功能來修改資料。
你也可以將此功能套用在其他的資料表維護上。
範例下載
下一篇教學文章
相關學習文章
如果你在學習上有不懂的地方,需要諮詢服務,可以參考站長服務,我想辨法解決你的問題
如果文章內容有過時、不適用或錯誤的地方,幫我在下方留言通知我一下,謝謝