2014年8月15日 星期五

ASP.NET MVC - 下拉選單的日期選擇器 Part.4 - Editor Templates

上一篇已經說明將下拉選單日期選擇器給做成 Editor Templates 的方式在 ASP.NET MVC 裡使用,但是上一篇所說明的只是基本的應用,所以有很多地方缺乏了彈性,在實際專案的應用將會有很多的困難,於是這一篇我們繼續將這個下拉選單日期選擇器的 Editor Templates 給加以改善。

 


首先把 DemoModel 類別給恢復原貌

image

回到 Sample1.cshtml 的 BirthDate 部分,指定使用「DateDropDownList」的 Editor Templates,

image

我們可以在 Html.EditorFor 的多載方法裡看到其中的一個方法,

image

第三個參數「addtionalViewData」匿名物件,可包含額外的檢視資料,此檢視資料將合併到為範本所建立的 ViewDataDicionary<TModel> 執行個體,

MSDN - EditorExtensions.EditorFor(TModel, TValue) 方法 (HtmlHelper(TModel), Expression(Func(TModel, TValue)), String, Object) (System.Web.Mvc.Html)

使用指定的範本和其他檢視資料,傳回運算式所表示之物件中每一個屬性的 HTML input 項目。

 

簡單地來說,我們可以透過這個 addtionalViewData 將資料傳遞給 Editor Templates,所以我們就可以將需要用來做設定的資料透過 addtionalViewData 傳給 Editor Templates,然後再將這些設定放到 input element 裡,以 data attribute 的方式放置這些資料,最後在 javascript code 裡就可以取得這些 data 的資料內容,這麼一來就可以做為 dataDropDowns 的 options 內容。

 

好的就先來看看在 Sample1.cshtml 檢視頁面裡要在 BirthDate 的 Html helper 裡要在 addtionalViewData 放些什麼資料,

image

這邊都用「_(底線)」作為變數名稱的 Prefix(前綴字),這是等一下我們要在 DateDropDownList.cshtml 裡讓我們可以很明確的取得哪些資料是要放在 input element 的 data attribute 裡,而從上到下的六個變數與內容分別市代表:是否使用民國年顯示、起始年、結束年、年份預設項目名稱、月份預設項目名稱、日份預設項目名稱。

 

再來就是要修改 DateDropDownList.cshtml 的內容,修改為以下的樣子,我想應該就不需做額外的說明,反正就是把 addtionalViewData 的資料抓出來,然後再放到 TextBox Html Helper 內的 Html Attributes,

image

@model DateTime?
@{
    var value = Model.HasValue
                    ? Model.Value.ToString("yyyy-MM-dd")
                    : "";
 
    var options = ViewData.Keys
        .Where(item => item.StartsWith("_"))
        .ToDictionary(
            item => item.Substring(1), 
            item => ViewData[item]);
}
 
 
@Html.TextBox("", value, new
{
    @class = "form-control Date-DropDownList",
    data_TaiwanCalendarYear = options.ContainsKey("TaiwanCalendarYear")
        ? options["TaiwanCalendarYear"].Equals(true).ToString()
        : "False",
    data_YearStart = options.ContainsKey("YearStart")
        ? options["YearStart"]
        : DateTime.Now.AddYears(-100).Year,
    data_YearEnd = options.ContainsKey("YearEnd")
        ? options["YearEnd"]
        : DateTime.Now.Year,
    data_YearOption = options.ContainsKey("YearOption")
        ? options["YearOption"]
        : string.Empty,
    data_MonthOption = options.ContainsKey("MonthOption")
        ? options["MonthOption"]
        : string.Empty,
    data_DayOption = options.ContainsKey("DayOption")
        ? options["DayOption"]
        : string.Empty
})

 

最後就是 site.js 裡面的前端程式內容,

image

;
$(function () {
 
    DateDropDownList();
});
 
function DateDropDownList() {
 
    var digitalMonthNames = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];
 
    var $NormalDateDDL = $('input.Date-DropDownList');
 
    $NormalDateDDL.dateDropDowns({
        dateFormat: 'yy/MM/DD',
        monthNames: digitalMonthNames,
        taiwanCalendarYear: $NormalDateDDL.data("taiwancalendaryear") === 'True',
        yearStart: $NormalDateDDL.data("yearstart"),
        yearEnd: $NormalDateDDL.data("yearend"),
        yearOption: $NormalDateDDL.data("yearoption"),
        monthOption: $NormalDateDDL.data("monthoption"),
        dayOption: $NormalDateDDL.data("dayoption")
    });
}

 

執行結果

image

image

image

 

如果在 Sample1.cshtml 的 BirthDate 只有指定「DateDropDownList」範本名稱而沒有指定 addtionalViewData,這樣也是可以正常執行,因為在 DateDropDownList 這個 Editor Templates 裡已經有判斷當沒有 addtiomViewData 設定時就會給預設值,執行結果如下:

image

image

image

 


這一篇寫得有些長了,主要介紹的就是在使用 Editor Templates 的時候,我們可以使用 addtionalViewData 將資料傳給 Editor Templates 使用,當我們需要在範本裡去對將來要生成的 input element 做一些彈性變化與設定的時候,就可以藉由這樣的方式來做處理。

BUT!

這樣就結束了嗎?

如果每次要使用到這個下拉選單日期選擇器,那些 addtionalViewData 就必須要再寫一次嗎?

如果我的專案裡使用到 DateDropDownList 就只有一種設定,我不想每次使用都要重複去輸入同樣 addtionalViewData,應該要怎麼處理呢?

就…… 且看下回分曉(當小說寫了….

 

系列文章:

ASP.NET MVC - 下拉選單的日期選擇器 Part.1

ASP.NET MVC - 下拉選單的日期選擇器 Part.2

ASP.NET MVC - 下拉選單的日期選擇器 Part.3 - Editor Templates

ASP.NET MVC - 下拉選單的日期選擇器 Part.4 - Editor Templates

ASP.NET MVC - 下拉選單的日期選擇器 Part.5 - Editor Templates

ASP.NET MVC - 下拉選單的日期選擇器 Part.6 - @helper ?

ASP.NET MVC - 下拉選單的日期選擇器 part.7 - Validation

 

以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。