上一篇完成了[縣市]基本作業;另外,在[設定]內的其他基本作業,就可以自行來練習看看囉。
本篇要來進行複雜型單檔作業,就是有加上一些關聯功能的[員工檔]作業!
一樣會從頭開始操作如何建立作業及其中的新增、編輯及刪除等功能。
不過,一些共同性步驟(Ex.產生控制器及檢示頁面的動作)會省略圖示哦~有忘記的話再請看上一篇複習一下。
1. 新增[ViewModel]:
因為會有關聯其他資料表的欄位呈現,所以需在Model內增加欄位,但又不想異動原始Model,所以加上檢視用Model,後續只要有關聯欄位就可以在此加上。
[Models]
--> [加入]
--> [類別]
。
除了加上欄位;也要using關聯參考進來。
還記得上一篇完成後,執行的結果在欄位名稱上會直接呈現資料表欄位名稱,這會讓使用者看的無法理解,所以要讓其呈現使用者看的懂的名稱,如何做呢?很簡單,如下圖中在每個欄位上加上一組[DisplayName(“XXXX”)]標籤屬性,執行後就會依設定的名稱來呈現了,是不是很棒呢!
名稱使用[DisplayName(“XXXX”)]
,這次多了一個日期格式,格式化顯示[年/月/日]方式呈現,所以要加上一組[DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}", ApplyFormatInEditMode = true)]
。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Hair.Models
{
public class EmployeeViewModel
{
[DisplayName("員工編號")]
public string em_no { get; set; }
[DisplayName("姓名")]
public string em_name { get; set; }
[DisplayName("身份證字號")]
public string em_id { get; set; }
[DisplayName("別名")]
public string em_alias { get; set; }
[DisplayName("性別")]
public string em_sex { get; set; }
[DisplayName("生日")]
[DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> em_birthday { get; set; }
[DisplayName("電話")]
public string em_tel { get; set; }
[DisplayName("手機")]
public string em_phone { get; set; }
[DisplayName("縣市編號")]
public string em_city { get; set; }
[DisplayName("縣市名稱")]
public string cityname { get; set; }
[DisplayName("區域編號")]
public string em_area { get; set; }
[DisplayName("區域名稱")]
public string areaname { get; set; }
[DisplayName("地址")]
public string em_address { get; set; }
[DisplayName("薪資編號")]
public string em_salarytype { get; set; }
[DisplayName("薪資名稱")]
public string salaryname { get; set; }
[DisplayName("技術抽率")]
public Nullable<decimal> em_rate1 { get; set; }
[DisplayName("產品抽率")]
public Nullable<decimal> em_rate2 { get; set; }
[DisplayName("備註")]
public string em_remark { get; set; }
}
}
2. 新增[EmployeeController]:
[Controllers]
--> [加入]
--> [控制器]
。空白控制器
,等未來熟悉之後,再讓工具幫您產出有內建程式的控制器吧!Index
:就是功能首頁,來調整一下讓其可以秀出表格資料。[EmployeeController]
新增[Index]
程式碼,一開始加上程式碼時,會出現下圖異常,可點選異常處,再點選黃色小圖示,會看到需要using的部份,加上後異常就會消失了。public ActionResult Index()
{
//宣告回傳員工列表
List<EmployeeViewModel> result = new List<EmployeeViewModel>();
//接收成功與否的訊息
ViewBag.ResultMessage = TempData["ResultMessage"];
//使用Entities類別,名稱為db
using (Models.HairSystemEntities db = new Models.HairSystemEntities())
{
//Linq方式取得Employees資料
result = ((from em in db.employee
join sa in db.salarytype on em.em_salarytype equals sa.no
join ci in db.city on em.em_city equals ci.no
join ar in db.area on new { area = em.em_area, city = em.em_city } equals new { area = ar.no, city = ar.cityno }
into e
from obj in e.DefaultIfEmpty()
orderby em.em_no
select new EmployeeViewModel
{
em_no = em.em_no,
em_name = em.em_name,
em_id = em.em_id,
em_alias = em.em_alias,
em_sex = (em.em_sex == "M" ? "男" : (em.em_sex == "F" ? "女" : (em.em_sex == "T" ? "第三性" : "其他"))),
em_birthday = em.em_birthday,
em_tel = em.em_tel,
em_phone = em.em_phone,
em_city = em.em_city,
cityname = ci.name,
em_area = em.em_area,
areaname = obj.name,
em_address = em.em_address,
em_salarytype = em.em_salarytype,
salaryname = sa.name,
em_rate1 = em.em_rate1,
em_rate2 = em.em_rate2,
em_remark = em.em_remark
})).ToList();
}
//回傳給檢示頁面
return View(result);
}
[View]
上按右鍵 --> [新增檢視]
。[加入]
。List(清單)
,模型及類別選擇建立的Models
。[EmployeeController]
有將查詢出來的資料轉型ToList(),所以@model要調整型態為List<>。@*@model IEnumerable<Hair.Models.EmployeeViewModel>*@
@model List<Hair.Models.EmployeeViewModel>
@{
ViewBag.Title = "員工清單";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>員工首頁</h2>
@if (ViewBag.ResultMessage != null) //判斷有訊息就顯示
{
@Html.Label("info", (string)ViewBag.ResultMessage, new { @class = "text-info" })
}
<p>
@Html.ActionLink("新增員工", "Create")
</p>
<table class="table" border="1">
<tr>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show1 = null; }
@Html.DisplayNameFor(showParam => show1.em_no)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show3 = null; }
@Html.DisplayNameFor(showParam => show3.em_id)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show4 = null; }
@Html.DisplayNameFor(showParam => show4.em_alias)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show5 = null; }
@Html.DisplayNameFor(showParam => show5.em_sex)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show6 = null; }
@Html.DisplayNameFor(showParam => show6.em_birthday)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show7 = null; }
@Html.DisplayNameFor(showParam => show7.em_tel)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show8 = null; }
@Html.DisplayNameFor(showParam => show8.em_phone)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show9 = null; }
@Html.DisplayNameFor(showParam => show9.em_city)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show11 = null; }
@Html.DisplayNameFor(showParam => show11.em_area)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show13 = null; }
@Html.DisplayNameFor(showParam => show13.em_address)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show14 = null; }
@Html.DisplayNameFor(showParam => show14.em_salarytype)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show16 = null; }
@Html.DisplayNameFor(showParam => show16.em_rate1)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show17 = null; }
@Html.DisplayNameFor(showParam => show17.em_rate2)
</th>
<th style="text-align: center">
@{ Hair.Models.EmployeeViewModel show18 = null; }
@Html.DisplayNameFor(showParam => show18.em_remark)
</th>
<th style="text-align: center" colspan="2">操作項目</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.em_no)
@Html.DisplayFor(modelItem => item.em_name)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_id)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_alias)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_sex)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_birthday)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_tel)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_phone)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_city)
@Html.DisplayFor(modelItem => item.cityname)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_area)
@Html.DisplayFor(modelItem => item.areaname)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_address)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_salarytype)
@Html.DisplayFor(modelItem => item.salaryname)
</td>
<td style="text-align: right">
@Html.DisplayFor(modelItem => item.em_rate1)
</td>
<td style="text-align: right">
@Html.DisplayFor(modelItem => item.em_rate2)
</td>
<td>
@Html.DisplayFor(modelItem => item.em_remark)
</td>
<td>
@Html.ActionLink("編輯", "Edit", new { id = item.em_no }, new { @Class = "btn btn-default" })
</td>
<td>
@using (@Html.BeginForm("Delete", "employee", FormMethod.Post, new { @class = "Delete" }))
{
@Html.Hidden("id", item.em_no)
<input type="submit" value="刪除" class="btn btn-default" />
}
</td>
</tr>
}
</table>
Create
:就是新增的頁面,程式碼有兩段;一段是後端帶出資料到前端,一段是前端傳遞資料到後端。ViewModel
內要再加一組[SexViewModel]
。public class SexViewModel
{
public static List<SelectListItem> SexDropDownList => new List<SelectListItem>()
{
new SelectListItem() {Text = "男", Value = "M"},
new SelectListItem() {Text = "女", Value = "F"},
new SelectListItem() {Text = "第三性", Value = "T"},
new SelectListItem() {Text = "其他", Value = "O"},
};
}
[Models]
--> [Hair.edmx]
--> [Hair.tt]
--> [employee.cs]
也要比照[ViewModel]
內加上標簽屬性,才能呈現出想要的名稱哦![EmployeeController]
新增[Create]
程式碼,會預設帶入員工編號,從[00001]
開始編。/// <summary>
/// 新增員工,宣告下拉元件資料來源
/// </summary>
/// <returns></returns>
public ActionResult Create()
{
//宣告回傳縣市列表
List<Models.city> result1 = new List<Models.city>();
//宣告回傳區域列表
List<Models.area> result2 = new List<Models.area>();
//宣告回傳薪資類別列表
List<Models.salarytype> result3 = new List<Models.salarytype>();
//使用Entities類別,名稱為db
using (Models.HairSystemEntities db = new Models.HairSystemEntities())
{
//Linq方式取得Citys資料
result1 = (from s in db.city select s).ToList();
SelectList selectList1 = new SelectList(result1, "no", "name");
ViewBag.CitySelectList = selectList1;
string CityNo = result1.FirstOrDefault().no;
//Linq方式取得Areas資料
result2 = (from s in db.area where s.cityno == CityNo select s).ToList();
SelectList selectList2 = new SelectList(result2, "no", "name");
ViewBag.AreaSelectList = selectList2;
//Linq方式取得SalaryTypes資料
result3 = (from s in db.salarytype select s).ToList();
SelectList selectList3 = new SelectList(result3, "no", "name");
ViewBag.SalaryTypeSelectList = selectList3;
}
//性別選項
ViewBag.SexSelectList = SexViewModel.SexDropDownList;
ViewBag.NewNo = GetNo();
return View();
}
/// <summary>
/// 新增員工,利用Entities回存資料庫
/// </summary>
/// <param name="postback"></param>
/// <returns></returns>
[HttpPost]
public ActionResult Create(Models.employee postback)
{
//資料驗證成功
if (this.ModelState.IsValid)
{
using (Models.HairSystemEntities db = new Models.HairSystemEntities())
{
//將回傳資料postback加入至Products
db.employee.Add(postback);
//儲存異動資料
db.SaveChanges();
//成功顯示訊息
TempData["ResultMessage"] = string.Format("員工[{0}]成功建立!", postback.em_name);
//頁面轉至瀏覽頁
return RedirectToAction("Index");
}
}
//失敗顯示訊息
ViewBag.ResultMessage = "資料有誤,請檢查!";
//停留在Create頁面
return View(postback);
}
[EmployeeController]
新增員工編號函式,讓每次新增都會預設產出一組號碼。/// <summary>
/// 給予單號預設值
/// </summary>
/// <returns></returns>
public String GetNo()
{
string NewNo;
using (Models.HairSystemEntities db = new Models.HairSystemEntities())
{
//Linq方式取得最新單號資料
var TempData = (from s in db.employee orderby s.em_no descending select s).ToList();
if (TempData.Count > 0)
{
string LastNo = TempData.FirstOrDefault().em_no;
if (string.IsNullOrEmpty(LastNo))
{
NewNo = "00001";
}
else
{
NewNo = (Int32.Parse(LastNo) + 1).ToString().PadLeft(5, '0');
}
}
else
{
NewNo = "00001";
}
return (NewNo);
}
}
[EmployeeController]
新增區域取得函式,讓每次選擇縣市後,都會重新帶出該縣市的區域資料。/// <summary>
/// 重新設定區域
/// </summary>
/// <param name="CityNo"></param>
/// <returns></returns>
public JsonResult GetArea(string CityNo)
{
List<Models.area> States = new List<Models.area>();
using (Models.HairSystemEntities db = new Models.HairSystemEntities())
{
//Linq方式取得Areas資料
var TempData = (from s in db.area where s.cityno == CityNo select s).ToList();
foreach (var item in TempData)
{
States.Add(new Models.area()
{
no = item.no.ToString(),
name = item.name.ToString(),
cityno = item.cityno.ToString()
});
}
}
return Json(States, JsonRequestBehavior.AllowGet);
}
稍早有提到,會有日期功能;所以要新增日期套件:在[工具]
--> [NuGet套件管理員]
--> [管理方案的NuGet套件]
。
下載[Bootstrap.v3.Datetimepicker.CSS]
套件使用,並將其加入在[BundleConfig.cs]
內。
// 日期套件所需
bundles.Add(new ScriptBundle("~/bundles/datetimepicker").Include(
"~/Scripts/jquery-3.4.1.min.js",
"~/Scripts/moment-with-locales.min.js",
"~/Scripts/bootstrap-datetimepicker.min.js"));
// 時間套件所需
bundles.Add(new ScriptBundle("~/bundles/timepicker").Include(
"~/Scripts/jquery.mask.js"));
[View]
上按右鍵 --> [新增檢視]
。Script語法
來做一個下拉日期元件
及上下層連動功能
來使用。@model Hair.Models.employee
@{
ViewBag.Title = "員工新增";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<head>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap-datetimepicker.min.css" rel="stylesheet" />
</head>
<h2>新增員工</h2>
@if (ViewBag.ResultMessage != null) //判斷有訊息就顯示
{
@Html.Label("info", (string)ViewBag.ResultMessage, new { @class = "text-info" })
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.em_no, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextBoxFor(model => model.em_no, new { @class = "form-control", @Value = ViewBag.NewNo, @readonly = "readonly" })
@Html.ValidationMessageFor(model => model.em_no, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.em_name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.em_name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.em_id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.em_id, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_alias, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.em_alias, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.em_alias, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_sex, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.em_sex, (IEnumerable<SelectListItem>)ViewBag.SexSelectList, "--請選擇性別--", new { @class = "form-control MakeWide btn btn-secondary dropdown-toggle" })
@Html.ValidationMessageFor(model => model.em_sex, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_birthday, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.em_birthday, new { htmlAttributes = new { @class = "form-control datepicker" } })
@Html.ValidationMessageFor(model => model.em_birthday, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_tel, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.em_tel, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.em_tel, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_phone, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.em_phone, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.em_phone, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_city, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.em_city, (SelectList)ViewBag.CitySelectList, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.em_city, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_area, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.em_area, (SelectList)ViewBag.AreaSelectList, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.em_area, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_address, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.em_address, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.em_address, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_salarytype, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.em_salarytype, (SelectList)ViewBag.SalaryTypeSelectList, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.em_salarytype, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_rate1, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.em_rate1, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.em_rate1, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_rate2, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.em_rate2, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.em_rate2, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.em_remark, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.em_remark, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.em_remark, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="確認" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("回員工首頁", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/datetimepicker")
<script>
//設定日期套件
$('.datepicker').datetimepicker({
date: null, //一開始輸入框的日期為空
format: 'YYYY/MM/DD', //日期的顯示格式
locale: moment.locale('zh-tw'), //國別
daysOfWeekDisabled: [0, 6] //隱藏的天數0為周日6為星期六
});
//設定縣市及區域連動關係
$(document).ready(function () {
$('#em_city').change(function () { ChangeCity(); });
});
function SetAreaEmpty() {
$('#em_area').empty();
}
function ChangeCity() {
var selectedCityNo = $.trim($('#em_city option:selected').val());
if (selectedCityNo.length == 0) {
SetAreaEmpty();
}
else {
$.getJSON("/Employee/GetArea", { CityNo: selectedCityNo }, function (data) {
$('#em_area').empty();
$.each(data, function (i, item) {
$('#em_area').append($('<option></option>').val(item.no).text(item.name));
});
});
}
}
</script>
}
完成一半了,還有編輯及刪除功能,下一篇見囉~