JSCal2 簡介
這一套
JSCal 已經出道很久了,我第一次在 ASP 程式的 Calendar 就是使用 JSCal 版,還不是 JSCal2,不過後來轉為付費版本且免費資源越來越多的情況下,就換其他選擇了。但今天我們還是選擇介紹它,因為我想透過 JSCal2 介紹一個 ASP.NET MVC 裡的功能,這個功能常讓人家誤解。
先把 Model、Controller \ Action、View 建立起來。
Model:BlogPostJSCal2.vb
01 | Imports System.ComponentModel.DataAnnotations |
06 | Public Class BlogPostJSCal2 |
08 | Public Property Title() As String |
10 | <DataType(DataType. Date )> |
11 | Public Property PostedOn() As DateTime |
13 | Public Property Tags() As String |
15 | Public Property Content() As String |
Controller \ Action:BlogPostJSCal2Controller.vb
01 | Namespace Mvc3HTMLEditorAndDatePicker |
02 | Public Class BlogPostJSCal2Controller |
03 | Inherits System.Web.Mvc.Controller |
08 | Function Create() As ActionResult |
12 | <HttpPost(), ActionName( "Create" )> |
13 | Function Create_Post(model As BlogPostMy97) As ActionResult |
14 | ViewBag.HtmlContent = model.Content |
View:Create.aspx
01 | <%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of Mvc3HTMLEditorAndDatePicker.BlogPostJSCal2)" %> |
03 | < asp:Content ID = "Content1" ContentPlaceHolderID = "TitleContent" runat = "server" > |
04 | KKBruce : DatePicker (使用 JSCal2) 日期選擇器測試 |
07 | < asp:Content ID = "Content2" ContentPlaceHolderID = "MainContent" runat = "server" > |
09 | < h2 >DatePicker (使用 JSCal2) 日期選擇器測試</ h2 > |
11 | <%-- The following line works around an ASP.NET compiler warning --%> |
14 | < script src = "<%: Url.Content(" ~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></ script > |
15 | < script src = "<%: Url.Content(" ~/Scripts/jquery.validate.unobtrusive.min.js") %>" type="text/javascript"></ script > |
17 | <% Using Html.BeginForm() %> |
18 | <%: Html.ValidationSummary(True) %> |
20 | < legend >JSCal2 DatePicker</ legend > |
22 | < div class = "editor-label" > |
23 | <%: Html.LabelFor(Function(model) model.Title) %> |
25 | < div class = "editor-field" > |
26 | <%: Html.EditorFor(Function(model) model.Title) %> |
27 | <%: Html.ValidationMessageFor(Function(model) model.Title) %> |
30 | < div class = "editor-label" > |
31 | <%: Html.LabelFor(Function(model) model.PostedOn) %> |
33 | < div class = "editor-field" > |
34 | <%: Html.EditorFor(Function(model) model.PostedOn) %> |
35 | <%: Html.ValidationMessageFor(Function(model) model.PostedOn) %> |
38 | < div class = "editor-label" > |
39 | <%: Html.LabelFor(Function(model) model.Tags) %> |
41 | < div class = "editor-field" > |
42 | <%: Html.EditorFor(Function(model) model.Tags) %> |
43 | <%: Html.ValidationMessageFor(Function(model) model.Tags) %> |
46 | < div class = "editor-label" > |
47 | <%: Html.LabelFor(Function(model) model.Content) %> |
49 | < div class = "editor-field" > |
50 | <%: Html.EditorFor(Function(model) model.Content) %> |
51 | <%: Html.ValidationMessageFor(Function(model) model.Content) %> |
55 | < input type = "submit" value = "Create" /> |
61 | <%: Html.ActionLink("Back to List", "Index") %> |
讓我們來使用 JSCal2 吧。
下載及複製 JSCal2
我們先下載
JSCal2-1.9 (目前最新) ,以下為授權內文:
The version you can download from here is fully functional, but the source code is minified and mangled (using the YUI compressor). If you want the full source code, please purchase a license.
Feel free to use the version distributed here for non-commercial purposes, i.e. on your personal blog, on a charity or educational website, in your free software, etc.
我們測試使用上沒有授權問題。
解壓縮後,
- 把 「JSCal2-1.9\src\js」下所有檔案複製到專案 「Scripts\JSCal2-1.9」 目錄之下,
- 「JSCal2-1.9\src\css」下有檔案複製到專案「Content\JSCal2-1.9」目錄之下。
設定與使用 JSCal2
在解壓縮的 JSCal2-1.9 目錄下,有完整的說明與範例文章,我們先看「JSCal2-1.9/demo/
simple.html」這個文件 Source Code,以了解如何使用。
需要引用二個 JavaScript 與 三個 CSS 檔案:
2 | < script src = "<%: Url.Content(" ~/Scripts/JSCal2-1.9/jscal2.js") %>" type="text/javascript"></ script > |
3 | < script src = "<%: Url.Content(" ~/Scripts/JSCal2-1.9/lang/cn.js") %>" type="text/javascript"></ script > |
4 | < link href = "<%: Url.Content(" ~/Content/JSCal2-1.9/jscal2.css") %>" rel="stylesheet" type="text/css" /> |
5 | < link href = "<%: Url.Content(" ~/Content/JSCal2-1.9/border-radius.css") %>" rel="stylesheet" type="text/css" /> |
6 | < link href = "<%: Url.Content(" ~/Content/JSCal2-1.9/steel/steel.css") %>" rel="stylesheet" type="text/css" /> |
然後看一下它所撰寫的 JavaScript,還好,很簡單易懂。
01 | < input size = "30" id = "f_date1" />< button id = "f_btn1" >...</ button > |
04 | < script type = "text/javascript" > |
07 | inputField: "f_date1", // 重要:選擇後的值要放到那個 input 欄位 |
08 | trigger: "f_btn1", // 重要:JSCal2 必須由"button"觸發 |
09 | onSelect: function () { this.hide() }, |
11 | dateFormat: "%Y-%m-%d %I:%M %p" // 日期格式:年-月-日 時:分 PM|AM |
12 | // 例如,2011-10-06 04:30 PM |
依上面的注解,我們改寫一下此 JavaScript 與 Create.aspx:
01 | < div class = "editor-field" > |
02 | <%: Html.EditorFor(Function(model) model.PostedOn) %> |
03 | <%: Html.ValidationMessageFor(Function(model) model.PostedOn) %> |
06 | < button id = "jscal_bnt" >選擇日期</ button > |
08 | < script type = "text/javascript" > |
11 | inputField: "PostedOn", |
13 | onSelect: function () { this.hide() }, |
15 | dateFormat: "%Y-%m-%d %I:%M %p" |
 |
圖一:ASP.NET MVC - JSCal2 執行畫面 |
到這裡我們已經完成了 JSCal2 在 Datepicker 的應用。
JSCal 行程曆範例
「你又想往下寫,是呀?」訪客說。
「多學一些,又不會怎樣。」KKBruce說:「寫的人又不你,累的人是我。」
「也對!」訪客說。
在解壓縮的目錄「JSCal2-1.9\demo」之下,有許多用好的範例,其中一個
dateInfo.html 引起我的興趣。它是一個類似程事曆範例,
 |
圖二:JSCal2 dateInfo.html 範例 |
以下是 dateInfo.html 內的 JavaScript 的程式碼:
01 | < script type = "text/javascript" > |
05 | 20090507: { klass: "highlight", tooltip: "%Y/%m/%d (%A) |
07 | 20090508: { klass: "highlight", tooltip: "And this is TODAY" } |
10 | function getDateInfo(date, wantsClassName) { |
11 | var as_number = Calendar.dateToInt(date); |
12 | if (as_number >= 20090518 && as_number <= 20090524) |
15 | tooltip : "<div style='text-align: center'>This is the green week</div>" |
17 | return DATE_INFO[as_number]; |
20 | var cal = Calendar.setup({ |
24 | dateInfo : getDateInfo |
你能發現,以上參數都是寫死的,一般而言,會像我在「
ASP.NET+jqPlot實作線上即時統計圖表(Chart) 」所介紹的,
這種程式碼,應該由後端去組合出來,然後回傳給前端,以保持前端動態且即時的資訊。
ASP.NET MVC - JavaScript ActionResult 使用介紹
這時候,就讓我們 ASP.NET MVC 中的
JavaScript ActionResult 上場吧!常看到有人問,這個 JavaScript ActionResult 是做什麼用?直接呼叫它,還會給我一個下載提示或顯示為純文字!常有人誤解它的用處,在這樣讓我們把 JavaScript ActionResult 的用處展示一下。
我們改寫上面 dateInfo.html 裡的 JavaScript,然後放到 BlogPostJSCal2Controller.vb 之中:
05 | Function Create_DateInfoJS() As JavaScriptResult |
09 | Dim thisMonth As Date = Date .Now |
10 | Dim starDay As Date = Date .Now |
11 | Dim endDay As Date = Date .Now.AddDays(7) |
13 | Dim DateInfoJS As New System.Text.StringBuilder |
15 | DateInfoJS.Append( "var DATE_INFO = {" ) |
17 | DateInfoJS.Append( "" & thisMonth.ToString( "yyyyMM" ) & "01" & ": { klass: " "highlight" ", tooltip: " "%Y/%m/%d (%A) |
18 | KKBruce說:初一要記得拜拜! "" },") |
19 | DateInfoJS.Append( "" & thisMonth.ToString( "yyyyMM" ) & "15" & ": { klass: " "highlight" ", tooltip: " "%Y/%m/%d (%A) |
20 | KKBruce說: 十五要記的觀賞月亮! "" }") |
21 | DateInfoJS.Append( "};" ) |
23 | DateInfoJS.Append( "function getDateInfo(date, wantsClassName) {" ) |
24 | DateInfoJS.Append( "var as_number = Calendar.dateToInt(date);" ) |
26 | DateInfoJS.Append( "if (as_number >= " & starDay.ToString( "yyyyMMdd" ) & " && as_number <= " & endDay.ToString( "yyyyMMdd" ) & ")" ) |
27 | DateInfoJS.Append( "return {" ) |
28 | DateInfoJS.Append( "klass : " "highlight2" "," ) |
29 | DateInfoJS.Append( "tooltip : " "<div style='text-align: center'>KKBruce說:希望接下來的一週每天都是green不要red!</div>" "" ) |
30 | DateInfoJS.Append( "};" ) |
31 | DateInfoJS.Append( "return DATE_INFO[as_number];" ) |
32 | DateInfoJS.Append( "};" ) |
34 | DateInfoJS.Append( "var cal = Calendar.setup({" ) |
36 | DateInfoJS.Append( "cont : " "cont" "," ) |
37 | DateInfoJS.Append( "fdow : 1," ) |
39 | DateInfoJS.Append( "date : " & thisMonth.ToString( "yyyyMM" ) & "01" & "," ) |
40 | DateInfoJS.Append( "dateInfo : getDateInfo" ) |
41 | DateInfoJS.Append( "});" ) |
43 | Return JavaScript(DateInfoJS.ToString()) |
增加一個 Action,以強型別新增一個 View。
Action:Create_DateInfo
3 | Function Create_DateInfo() As ActionResult |
View:Create_DateInfo.aspx 引用相關 JavaScript
02 | < script src = "<%: Url.Content(" ~/Scripts/jquery.unobtrusive-ajax.min.js") %>" type="text/javascript"></ script > |
05 | < script src = "<%: Url.Content(" ~/Scripts/JSCal2-1.9/jscal2.js") %>" type="text/javascript"></ script > |
06 | < script src = "<%: Url.Content(" ~/Scripts/JSCal2-1.9/lang/cn.js") %>" type="text/javascript"></ script > |
07 | < link href = "<%: Url.Content(" ~/Content/JSCal2-1.9/jscal2.css") %>" rel="stylesheet" type="text/css" /> |
08 | < link href = "<%: Url.Content(" ~/Content/JSCal2-1.9/border-radius.css") %>" rel="stylesheet" type="text/css" /> |
09 | < link href = "<%: Url.Content(" ~/Content/JSCal2-1.9/matrix/matrix.css") %>" rel="stylesheet" type="text/css" /> |
10 | < style type = "text/css" > |
11 | .highlight { color: #f00 !important; } |
12 | .highlight2 { color: #0f0 !important; font-weight: bold; } |
然後,透過 Ajax 技術的幫忙,讓我們動態的去載入此日曆。
01 | < div class = "editor-field" > |
03 | <%: Html.EditorFor(Function(model) model.PostedOn) %> |
04 | <%: Html.ValidationMessageFor(Function(model) model.PostedOn) %> |
09 | <%: Ajax.ActionLink("載入日曆", "Create_DateInfoJS", |
10 | new AjaxOptions With {.UpdateTargetId= "datapicker" }) %> |
建置,執行網頁「http://localhost:6944/BlogPostJSCal2/Create_DateInfo」(記得換成你的 port)。
 |
圖三:Ajax 動態載入 JavaScript |
一開始好像不錯,不過你多按幾次會發現,前一次的行事曆不會消失。
 |
圖四:Ajax 動態載入 - 前一次的效果不會消失 |
讓我們寫一小段 jQuery 程式碼來解決這個問題。
01 | < div class = "editor-field" > |
03 | <%: Html.EditorFor(Function(model) model.PostedOn) %> |
04 | <%: Html.ValidationMessageFor(Function(model) model.PostedOn) %> |
09 | <%: Ajax.ActionLink("載入日曆", "Create_DateInfoJS", |
10 | new AjaxOptions With {.UpdateTargetId= "datapicker", |
11 | .OnBegin = "RemovePreDataPicker" }) %> |
13 | < script type = "text/javascript" > |
16 | function RemovePreDataPicker() { |
17 | var datepickerId = $('#cont'); |
18 | datepickerId.find('table').each(function() { |
建置,重新執行網頁。
JSCal2 使用心得
JSCal2 是一個開發很久的純 JavaScript 專案,也是穩定好用。而我想透過 JSCal2 裡的範例,讓大家了解 ASP.NET MVC 裡 JavaScript ActionResult 的用途。當我們的 JavaScript 裡的資料需要由「
伺服器端即時提供」時,此時就是使用 JavaScript ActionResult 的好時機。
參考資料
如何移除JSCal2按下enter觸發下拉選單的動作呢?謝謝
回覆刪除