今天找資料時在網頁上看到一張照片, 但是文章中沒說明人物是誰, 於是就想有什麼辦法查出人名. 我發現原來 Google 圖片早就有 "圖片找人" 功能了, 就是先把網頁中的那張不知人名圖片下載到電腦 (按右鍵, 另存影像), 於 Google 首頁按 "圖片", 再點輸入框右邊的照相機, 於彈出視窗中點 "上傳圖片", 然後點選下載的圖片上傳後, Google 就會比對與影中人相似度高的相關網站, 這樣就能從這些網站找到影中人的蛛絲馬跡了. 呵呵, 難道這就是所謂人肉搜索嗎? 所以, 千萬不要亂上傳自己的照片到網路上啊, 除非你想擁有知名度.
2013年4月20日 星期六
2013年4月19日 星期五
產生 jQuery UI 按鈕與訊息盒的 PHP 函式
因為按鈕與訊息盒在 jQuery UI 中使用頻率高, 而且功能較簡單, 乾脆寫成 PHP 函式庫, 每次要用到時就直接呼叫, 產生所需的程式與網頁碼, 省得還要一一佈置. 而確認盒與輸入盒因為牽涉彈性較大的回呼函式, 以後功力深些再想辦法了. 其實訊息盒最重要一點就是要把 autoOpen 選項關掉 (設為 false), 需要顯示訊息時才靠按鈕的 click 事件或其他事件去打開它.
使用上很簡單, 只要 echo 函式的傳回值, 再給按鈕加上 click 事件處理器就可以了 :
<?php
echo get_button("button1","刪除");
echo get_msgbox("dialog1","錯誤訊息","無權刪除","確定");
?>
<script>
$('#button1').click(function(){
$('#dialog1').dialog('open'); //開啟訊息框
});
</script>
使用上很簡單, 只要 echo 函式的傳回值, 再給按鈕加上 click 事件處理器就可以了 :
<?php
echo get_button("button1","刪除");
echo get_msgbox("dialog1","錯誤訊息","無權刪除","確定");
?>
<script>
$('#button1').click(function(){
$('#dialog1').dialog('open'); //開啟訊息框
});
</script>
方便好用的程式碼顯示網站 pastie.org
為了在 blogger 上顯示程式碼著實傷腦筋, 我試過改 blogger 設定, 但不知哪裡沒弄好, 一直不成功, 直到找到 http://pastie.org 才暫時有解. 只要把程式碼貼到該網站, 就會取得一個 javascript 的 id, 例如 :
<script src="http://pastie.org/7643389.js">
</script><br />
<script src="http://pastie.org/7643389.js">
</script><br />
然後把 blogger 切到 HTML 模式, 然後貼到想要顯示程式碼的位置就可以了. 很方便, 但是有一個缺點, 如果程式碼太寬, 它會穿越 blogger 版面, 不美觀. 以我的 blogger 版面為例, 就必須控制每行寬度小於 60 個字元, 這樣就剛剛好.
圖檔網站 icondrawer.com
今天找到一個不錯的網站 http://www.icondrawer.com, 它提供了許多精美的圖檔, 而且可以免費使用, 只要在網頁上加上該公司網址即可, 如不願意 也可以花錢購買. 可以免費的東西, 我當然願意啦!
2013年4月18日 星期四
產生 jQuery UI 日期選取器的 PHP 函式
今天終於寫完 jQuery UI 的日期選取器測試報告, 哇, 還真是龐大啊, 幾乎把所有選項都介紹完了. 其實平常根本用不到這麼多選項, 通常只要中文化就可以了. 所以我用 PHP 寫了一個函式來產生 datepicker 的程式碼, 只要在 PHP 程式中呼叫 get_datepicker(), 再 echo 其傳回值就可以了 :
<?php
echo get_datepicker("datepicker1"); //顯示年月下拉式選單, 中文
echo get_datepicker("datepicker1",false); //不顯示年月下拉式選單, 中文
echo get_datepicker("datepicker1",false,""); //不顯示年月下拉式選單, 英文
?>
get_datepicker() 參數如下 :
$id : 日期選擇器 input/div/span 元素之 id
$change_YM : 是否顯示年月更改選單, true=顯示 (預設), false=不顯示
$locale : 預設 "zh-TW" (繁體中文), 其他字串為英文
<?php
echo get_datepicker("datepicker1"); //顯示年月下拉式選單, 中文
echo get_datepicker("datepicker1",false); //不顯示年月下拉式選單, 中文
echo get_datepicker("datepicker1",false,""); //不顯示年月下拉式選單, 英文
?>
get_datepicker() 參數如下 :
$id : 日期選擇器 input/div/span 元素之 id
$change_YM : 是否顯示年月更改選單, true=顯示 (預設), false=不顯示
$locale : 預設 "zh-TW" (繁體中文), 其他字串為英文
2013年4月17日 星期三
黑部立山
早上 07:30 從鄉下出發, 到小舅家才 8:10, 等婷婷阿姨來後又聊了一下, 09:30 才出發前往機場. 12:10 的飛機, 其實只要 10:10 報到就可以了. 這次小舅媽邀媽媽遊日本, 也是半推半就, 上回他們去宜蘭與阿里山玩也是如此. 菁菁本來也想跟, 但後補機位不足, 而且也剛好月考.
我周日時研究了一下行程如下 :
我周日時研究了一下行程如下 :
- 第二天 :
飛驒高山古三町 走在秋天的飛驒古三町
世界文化遺產:白川鄉合掌村
兼六園 戀戀北陸行DAY2-日本三大名園之一『兼六園』 發現魅力金澤 - 第三天 :
立山黑部 女王的黑部之旅 - 第四天 :
輕井澤 單車漫遊輕井澤 - 第五天 :
淺草觀音寺
2013年4月16日 星期二
備份最重要
晚上正準備把 jQuery UI 的日曆小工具的本地化補充寫完, 結果弄巧成拙, 存檔時出現錯誤, 又再存一次, 結果測試範例 3 以下全部不見了, 哇咧, 我今日一整天已經寫到範例 8 了耶! 卡好, 又沒備份, 只好重寫了.
明日要載小舅跟媽去機場, 所以吃完晚飯後就回鄉下了.
2013-04-17 注 : 今晚想重寫時, 在 html 意外發現原始資料還在, 只是被一些錯誤格式的碼破壞結構, 以致後面都無法顯示, 太好了, 終於救回來了, 要不然, 重寫的話也無法保證寫得一模一樣.
明日要載小舅跟媽去機場, 所以吃完晚飯後就回鄉下了.
2013-04-17 注 : 今晚想重寫時, 在 html 意外發現原始資料還在, 只是被一些錯誤格式的碼破壞結構, 以致後面都無法顯示, 太好了, 終於救回來了, 要不然, 重寫的話也無法保證寫得一模一樣.
2013年4月15日 星期一
jQuery UI 的日期選擇器 datepicker 測試
近兩周都在玩 jQuery UI 的日曆小工具 (或日期選擇器 datepicker), 就是讓使用者可以直接在日曆上選取日期的小工具, 而且日期格式可以指定. 這個 widget 小工具根據書上講是 jQuery UI 最古老, 功能選項也最龐大的一個, 照官網範例三兩下就看到效果了, 很簡單啊, 原本以為兩天就可以搞定, 沒想到弄了快兩個禮拜. 最初看到這麼多選項, 我想又不是每一個都會用到, 只要測試一下最常用的就好了, 後來才發現, 如果要 localization (本地化, 就是繁體中文化啦), 還真的要用到許多看來用不到的選項, 據說 2.0 版時此 widget 會重新改寫.
通常在網頁上用來輸入日期的通常是文字欄位的 input 元素 (我常用的是三個下拉式選單組合) :
<input id="datepicker1" type="text" />
這個陽春的日期輸入介面最大的缺點是, 使用者可能會亂輸入, 資料庫要的是 2013-04-15, 但輸入的可能是 4/16/2013, 而且要一一鍵入不方便. 有了 jQuery UI 後, 就可以呼叫 input 元素的 jQuery 物件的 datepicker() 方法來將 input 元素改裝成美美的日曆選取器 :
$("#datepicker1").datepicker();
這樣一來, 只要滑鼠在 input 文字欄位上點一下取得焦點後, 就會在 input 元素正下方出現一個日曆供選取日期, 例如 :
測試範例 1 : http://tony1966.xyz/test/jquerytest/datepicker_1.htm [看原始碼]
範例 1 中放置了三個日期選取器 :
$("#datepicker1").datepicker();
$("#datepicker2").datepicker({firstDay: 1});
$("#datepicker3").datepicker({appendText: "點一下顯示日曆"});
由 datepicker1 可知, 沒有傳入任何參數時, 日暦預設是英文版的, 而且預設一周是從星期天開始算的. 如果要更改一周之始, 必須傳入參數去設定日曆物件的 firstDay 選項. 如同其他 widget, 傳入參數最常用的是物件實體, 以 key:value 方式指定日曆的各個選項. 選項 firstDay 預設值為 0 (代表星期天), 星期一是 1, ... 星期六是 6. 在 datepicker2 我們將 firstDay 設為 1, 因此日曆的第一欄就是星期一. 另外, 選取日期後 input 元素預設顯示 mm/dd/yy 格式, 這不是我喜歡的 yy-mm-dd 格式, 這要用 dateFormat 選項設定, 稍後再介紹. 在 datepicker3 我們設定了選項 appendText 之值, 此字串會顯示在 input 元素後面, 通常用來作為提示之用.
先來處理本地化, 如果要顯示繁體中文, 就必須傳入特定的七個參數, 把預設的英文版覆蓋掉, 這叫做本地化 (localization). 本地化牽涉之選項有如下七個 :
星期 : dayNames (提示), dayNamesMin (星期欄位名稱)
月份 : monthNames (標題月份全名), monthNamesShort (標題月份下拉式選單簡名)
按鈕 : prevText (上月按鈕提示文字), nextText (次月按鈕提示文字)
週數 : weekHeader (週欄位名稱)
其中, 前七個便是繁體中文化所必須的七個選項, 第八個選項 showMonthAfterYear 是設定月份顯示在年份後面; 最後一個選項 dateFormat 則是設定 input 元素內之日期格式為例如 2013-04-15. 關於 dateFormate 選項的格式字串整理如下 :
最後一個格式為單引號, 用來跳脫其他的格式字串, 例如要在 input 中顯示 "Selected yy-mm-dd", 因 Selected 中含模式字串 d, 必須跳脫, 故要寫成 "Selecte'd' yy-mm-dd", 把 d 字元用單引號括起來即可. 其實我都一律使用 yy-mm-dd, 這最簡單明瞭. 其實這個 "yy-mm-dd" 字串在 datepicker 的管理物件 (manager object) 中也有定義三個常數是 "yy-mm-dd" 的 :
$.datepicker.ATOM
$.datepicker.ISO_8601
$.datepicker.W3C
也就是說, {dateFormat: "yy-mm-dd"} 可以寫成 {dateFormat: $.datepicker.W3C}, 效果是一樣的. 我覺得還是 "yy-mm-dd" 比較好記.
測試範例 2 : http://tony1966.xyz/test/jquerytest/datepicker_2.htm [看原始碼]
如果網頁中不只用到一個日期選取器, 則每一個都要如上設定那七個選項似乎有點煩, 如果要一勞永逸, 可以使用 jQuery UI datepicker 管理物件 (manager object) 的 setDefaults() 方法來設定預設值, 這樣此網頁中任何一個日期選取器都會套用此繁體中文化設定 :
$.datepicker.setDefaults($.datepicker.regional["zh-TW"]);
其實, jQuery UI 早已做好國際化了, 它已經為各種語言寫好本地化 js 設定檔, 這些設定檔放在 jQuery UI 下載檔解壓縮後的 \ui\i18n 目錄下. 只要在匯入 jQuery UI 函式庫後, 接著匯入所需要語言的設定檔即可, 例如繁體中文設定檔為 jquery.ui.datepicker-zh-TW.js, 把它放在專案的 jquery 目錄下, 然後於網頁的 head 中匯入即可 :
<script type="text/javascript" src="http://tony1966.xyz/test/jquery/jquery.ui.datepicker-zh-TW.js"></script>
這樣只要直接呼叫 datepicker() 方法就可以本地化了, 不需再自行設定 (當然客製化除外).
$("#datepicker1").datepicker();
世界主要語言的本地化檔案如下表, 我已將這些檔案放在 http://tony1966.xyz/test/jquery/ 下, 其餘見下載檔解壓縮的 \ui\i18n 目錄 :
以下是這九種語言的本地化日曆, 可以發現 datepicker 中文簡體與繁體其實沒什麼差別.
測試範例 2-1 (繁體) : http://tony1966.xyz/test/jquerytest/datepicker_2_1.htm [看原始碼]
測試範例 2-2 (簡體) : http://tony1966.xyz/test/jquerytest/datepicker_2_2.htm [看原始碼]
測試範例 2-3 (日文) : http://tony1966.xyz/test/jquerytest/datepicker_2_3.htm [看原始碼]
測試範例 2-4 (韓文) : http://tony1966.xyz/test/jquerytest/datepicker_2_4.htm [看原始碼]
測試範例 2-5 (俄文) : http://tony1966.xyz/test/jquerytest/datepicker_2_5.htm [看原始碼]
測試範例 2-6 (阿文) : http://tony1966.xyz/test/jquerytest/datepicker_2_6.htm [看原始碼]
測試範例 2-7 (西文) : http://tony1966.xyz/test/jquerytest/datepicker_2_7.htm [看原始碼]
測試範例 2-8 (德文) : http://tony1966.xyz/test/jquerytest/datepicker_2_8.htm [看原始碼]
測試範例 2-9 (法文) : http://tony1966.xyz/test/jquerytest/datepicker_2_9.htm [看原始碼]
測試範例 2-10 (全部) : http://tony1966.xyz/test/jquerytest/datepicker_2_10.htm [看原始碼]
在測試範例 2-10, 我們把這九種語言整合在一起, 可以點擊國旗圖案 (來自 www.icondrawer.com), 利用 beforeShow 選項呼叫回呼函式來選擇本地化語系 :
var locale=$.datepicker.regional[""];
$("#en").click(function() {locale=$.datepicker.regional[""];});
$("#ar").click(function() {locale=$.datepicker.regional["ar"];});
....
$("#datepicker1").datepicker({beforeShow: set_locale});
function set_locale() {return locale;}
選項 beforeShow 用來設定日曆顯示前要呼叫的函式, 此回呼函式可以傳回選項物件實體, 以便在開啟日曆前先進行設定. 此處回呼函式傳回 $.datepicker.regional[] 來設定語系, 請注意, 本地化陣列 regional[] 之索引, 英文要設為空字串 [""].
接著我們來測試 showMonthAfterYear 與 showWeek 這兩個選項.
測試範例 3 : http://tony1966.xyz/test/jquerytest/datepicker_3.htm [看原始碼]
在範例 3 中, 放置了兩個日期選取器 :
$("#datepicker1").datepicker({dateFormat:"yy-mm-dd",showMonthAfterYear:true});
$("#datepicker2").datepicker({dateFormat:"yy-mm-dd",showWeek:true});
其中 datepicker1 將 showMonthAfterYear 設為 true, 所以日曆標題顯示的是 "2013年 四月"; 而 datepicker2 則為預設 false, 顯示的是 "四月 2013年", 但其 showWeek 選項設為 true, 所以日曆第一欄會顯示週數.
接下來要介紹三個選項 : changeYear, changeMonth 與 yearRange. 在前面範例中, 日曆的標題只是顯示年月字串, 如果要跳到去年或明年某月, 必須不斷按標題左右兩個按鈕 (次月, 上月) 有點麻煩 (循序式). 而 changeYear 與 changeMonth 此兩個選項若設為 true, 就會把標題中的年月字串分別改成下拉式選單, 可以直接選擇要顯示的哪一年哪一月日曆.
測試範例 4 : http://tony1966.xyz/test/jquerytest/datepicker_4.htm [看原始碼]
在範例 4 中, 放置了三個日期選取器 :
$("#datepicker1").datepicker({changeYear: true, changeMonth: true});
$("#datepicker2").datepicker({changeYear: true, changeMonth: true,
yearRange:"2010:2015"});
$("#datepicker3").datepicker({changeYear: true, changeMonth: true,
yearRange:"-5:+5"});
可見三個日曆標題中的年月都變成下拉式選單. 其中從 datepicker1 可知 yearRange 未設定的話是系統年份的前後十年 (不含系統之年份). 在 datepicker2 與 datepicker3 中, 我們測試了 yearRange 的兩種設值方法, 第一種是以 "from:to" 字串方式, 第二種是系統年份為準, 用 - 表示往前幾年, 用 + 表示往後幾年來指定下拉式選單的範圍.
接著我們來測試 showOtherMonths 與 selectOtherMonths 這兩個選項, 前者設為 true 表示要顯示日曆中銜接上月底與下月初的日期, 以便把整個日曆填滿, 預設 false 不顯示; 但這些銜接日期預設都無法選取, 要靠後者設為 true 才行.
測試範例 5 : http://tony1966.xyz/test/jquerytest/datepicker_5.htm [看原始碼]
在範例 5 中放置了兩個日期選取器 :
$("#datepicker1").datepicker({showOtherMonths: true});
$("#datepicker2").datepicker({showOtherMonths: true, selectOtherMonths: true});
可見銜接日期會以較淡顏色顯示, datepicker1 中的銜接日期雖顯示但無法選取, 而 datepicker2 的則可以選取.
範例六我們來測試一下 dafaultDate, minDate 與 maxDate 這三個跟日期有關的選項, 其設定值格式都一樣. 選項 dafaultDate 用來設定日曆的預設日期, 也就是黃色高亮度的日期. 日曆打開時預設是讀取系統今日日期, 而我們設定 dafaultDate 選項就是要把這個系統日期覆蓋掉, 改為我們指定之日期. 而 minDate 與 maxDate 則是用來限制可選取日期範圍的選項. 選項 minDate 用來設定最小可選取日期, 小於此設定值之日期將不可選取; maxDate 用來設定最大可選取日期, 大於此設定值之日期將不可選取. 設定值可以是日期物件, 距離系統日期之日數, 或者是日期字串. 使用日期物件時要注意, Javascript 的日期物件函式 new Date(年,月, 日) 的參數中, 月是從 0 開始的, 因此四月要用 3 代入. 若 dafaultDate, minDate 與 maxDate 使用日期字串, 則必須先用 dateFormat 選項設定其日期格式, 否則會解讀成錯誤的日曆.
測試範例 6 : http://tony1966.xyz/test/jquerytest/datepicker_6.htm [看原始碼]
在範例 6 中放置了三個日期選取器 :
$("#datepicker1").datepicker({dateFormat:"yy-mm-dd",
dafaultDate: "2013-04-16", minDate: "2013-04-03"});
$("#datepicker2").datepicker({dafaultDate: new Date(2013, 3, 16),
minDate: "-5", maxDate: "10"});
$("#datepicker3").datepicker({dafaultDate: new Date(2013, 3, 16),
minDate: "-1y -1m -1w", maxDate: "+1y +1m +1w"});
第一個日曆中, 我們用 defaultDate 將預設日期設為 2013-04-16, 這樣不管哪一天顯示此網頁, 這日曆都會顯示 2013 年四月, 且 4 月 16 日高亮度. 其次, minDate 設為 "2013-04-03", 表示四月份中最小可選取日期為 4 月 3 日 (含), 4/1 與 4/2 都不可選取. 因為只設定 minDate, 沒有設定 maxDate, 因此 4/3 以後都是可選的, 而且次月按鈕都可以按, 而前月按鈕已經失能, 無法再按了. 特別注意這裡我們使用了日期字串來設定 minDate, 因此必須事先以 dateFormat 選項設定其格式, 要不然會剖析錯誤, 顯示 2018 年 10 月的日曆.
第二個日曆我們使用日期物件來設定 defaultDate, 用距離 (offset) 預設日期之日數來設定 minDate 與 maxDate. 因為 Javascript 的 Date 物件中, 月份為 0 起始的, 因此預設日期 2013 年 4 月 16 日要寫成 new Date(2013,3,16). 而 minDate: "-5" 表示最小可選取日為預設日期前 5 日, 也就是 16-5=11, 四月十一日; 而 maxDate: "10", 表示最大可選取日為預設日期後 10 日, 也就是 16+10=26, 四月二十六日. 注意, 因為我們限制可選日期為 4/3~4/26, 因此前月與次月按鈕都失能無法再按了, 如果將 changeYear 與 changeMonth 都設為 true, 則下拉式選單也會被限制選項只剩下 2013 年四月而已.
其實日期字串除了絕對值外, 也可以用相對值, 這是相對於預設日期而言. 在第三個日曆 datepicker3 中, minDate 與 maxDate 就使用了相對值. 其中 "-" 表示在預設日期之前, "+" 表示在預設日期之後, "y" 表示年, "m" 表示月, "d" 表示日, 所以 minDate: "-1y -1m -1w" 表示最小可選取日期為預設日期前一年一個月又一天, 預設日期是 2013-04-16 的話, 則 minDate 就是 2012-03-09; 同理 maxDate 則是 2014-05-23, 請按上月與次月按鈕印證.
關於限制可選取日期, 其實還有一個更常用的情況, 那就是將週六週日都設為不可選取. 請看測試範例 7 :
測試範例 7 : http://tony1966.xyz/test/jquerytest/datepicker_7.htm [看原始碼]
這裡用到 datepicker 管理物件的內建函式 $.datepicker.noWeekends(), 只要將日曆的 beforeShowDay 選項設定為呼叫此函式即可 :
$("#datepicker1").datepicker({beforeshowDay: $.datepicker.noWeekends});
選項 beforeShowDay 用來在顯示日期選取器中的每一天前, 呼叫指定的回呼函式, 如果回呼函式傳回的陣列中, 索引 0 為 true, 便將該日設為可選取, 反之 false 就設為不可選取. 它主要用來覆寫與星期有關的預設行為. 唯一傳入回呼函式的參數是星期, 例如 Friday. 而公用函式 $.datepicker.noWeekends 的作用就是判斷傳入的星期, 若是 Saturday 或 Sunday, 就把傳回陣列的索引 0 設為 false, 其他星期設為 true.
以上就是 datepicker 小工具常用的選項測試. 接下來要測試如何直接用程式設定 datepicker 的日期 (不是靠選取), 以及如何取得日曆小工具的日期. 這不是傳入選項物件, 而是在第一參數傳入 "動作字串" (actions) 與相關參數 params, 其格式為 :
$("#datepicker1").datepicker("action", params)
接著要介紹比較少用的四個選項, showOn, buttonImage, buttonImageOnly, buttonText. 通常我們都是擺個 input 元素當作日期選取器的承載元素, 當使用者點一下文字欄位, 就會自動打開日曆 , 這其實是 showOn 這個選項預設值為 "focus" 的緣故. 此選項有三個值 : "focus", "button", 以及 "both". 預設 "focus" 表示只要 input 元素一取得焦點, 日曆就會打開. 如果設為 "button", 則 input 元素後面會自動多出一個標題文字為 "..." 的按鈕, 這時點選 input 文字欄位就不會打開日曆了, 而是要按後面的那個按鈕, 如測試範例 8_1.
如果嫌 "..." 按鈕不知所云, 可以利用 buttonText 設定其標題文字, {buttonText: "日曆"}, 如測試範例 8_2. 也可以在按鈕上放置圖片來取代文字, {buttonImage: "calendar.gif"}, 當然這要上傳一個日曆圖檔到伺服器才行 (這個圖檔可以在 jQuery UI 下載檔解壓縮目錄 development-bundle\demos\datepicker\images 下找到). 這時即使同時有設定 buttonText, 按鈕上也只顯示圖片, 如測試範例 8_3.
因為按鈕使用 HTML 原生按鈕, 無法套用主題布景, 如果嫌按鈕難看, 也可以將 buttonImageOnly 選項設定為 true, {buttonImageOnly: true}, 這樣就會只顯示圖片, 不顯示按鈕, 如測試範例 8_4. 最後, 前述 showOn 選項設為 "button" 後, 點文字欄位不會再打開日曆, 而是必須按按鈕或圖片, 如果想魚與熊掌兼得的話, 那麼 showOn 選項要設為 "both", 如測試範例 8_5.
測試範例 8_1 : http://tony1966.xyz/test/jquerytest/datepicker_8_1.htm [看原始碼]
測試範例 8_2 : http://tony1966.xyz/test/jquerytest/datepicker_8_2.htm [看原始碼]
測試範例 8_3 : http://tony1966.xyz/test/jquerytest/datepicker_8_3.htm [看原始碼]
測試範例 8_4 : http://tony1966.xyz/test/jquerytest/datepicker_8_4.htm [看原始碼]
測試範例 8_5 : http://tony1966.xyz/test/jquerytest/datepicker_8_5.htm [看原始碼]
下面要介紹與選取事件有關的選項 onSelect, 以及 setDate, getDate, option 這三個動作.
測試範例 9 : http://tony1966.xyz/test/jquerytest/datepicker_9.htm [看原始碼]
此範例稍為複雜, 網頁元素有四個, 一個 input 做日曆輸入, 三個 button 按鈕, 第一個用來設定 input 的日期, 第二個用來取得選取的日期, 並用訊息盒顯示此日期, 第三個用來切換 showWeek 選項, 藉以說明 option 動作的 getter 與 setter 功能. 訊息盒需要一個 div 元素. 訊息盒用法參見 "jQuery UI widget 之確認盒應用範例" 這篇說明.
<input id="datepicker1" type="text" />
<button id="button1">設定日期為 2013-04-01</button>
<button id="button2">取得日期</button>
<div id="msgbox1" title="訊息"></div>
當使用者點一下 input 文字欄位, 在日曆中選取一個日期後, 就會顯示訊息盒告知被選取之日期. 這是加入 onSelect 選項的效果, 其值為一自訂之回呼函式 show_select(), 由這函式來打開訊息盒.
$("#datepicker1").datepicker({dateFormat:"yy-mm-dd",
onSelect: show_select
});
function show_select() {
var date=$("#datepicker1").datepicker("getDate");
$("#msgbox1").html("選取的日期 : " + date);
$("#msgbox1").dialog("open");
}
當使用者按 button1 時, 呼叫 datepicker() 方法執行 setDate 動作, 把 input 之日曆設為選取 2013 年 4 月 1 日.
$('#button1').click(function(){
$("#datepicker1").datepicker("setDate",new Date(2013,3,1));
});
當使用者按下 button2 時, 呼叫 datepicker() 方法執行 getDate 動作, 它會傳回被選取日期之日期物件. 我們可以呼叫日曆的公用函式 formatDate 來把日期物件格式化為字串, 最後把字串用訊息盒顯示出來 :
$('#button2').click(function(){
var date=$("#datepicker1").datepicker("getDate");
date=$.datepicker.formatDate("yy 年 M d 日", date);
$("#msgbox1").html("選取的日期 : " + date);
$("#msgbox1").dialog("open");
});
公用函式 formatDate 的語法為 : $.datepicker.formatDate(format, date[, options]), 第一參數為格式字串, 第二參數為日期物件, 有需要還可以傳入選項物件實體.
繼續來看看 dialog 動作, 此動作是要在對話盒中打開日曆, 而非在 input 元素的下方, 這通常要用一個按鈕來啟動, dialog 動作的參數如下 :
$("#datepicker1").datepicker("dialog", defaultDate, onselect[, options]);
其中第二參數用來設定日曆的預設日期, 可以是日期物件, 例如 new Date(2013,3,16), 或者是日期字串 "2013-04-16", 注意, 使用日期字串時必須帶入第四參數, 設定日期格式選項, 例如 {dateFormat: "yy-mm-dd"}. 如果傳入空字串 "" 表示預設為系統日期. 第三參數是選取日期後要呼叫的回呼函式, 通常用來設定 input 文字欄位元素之值.
範例 9 的第三個按鈕是用來測試 option 動作, 按下可以切換 showWeek 選項之值, 亦即 true 變 false, 或反之. option 動作可以傳入兩個參數 (getter) 或三個參數 (setter), 第二個參數要傳入選項名稱 (字串) :
取得選項之值 : datepicker("option", optionName)
設定選項之值 : datepicker("option", optionName, value)
當按下第三個按鈕時, 先用 getter 取得目前 showWeek 之值, 再進行切換 :
var showWeek=$("#datepicker1").datepicker("option", "showWeek");
if (showWeek) {$("#datepicker1").datepicker("option", "showWeek", false);showWeek=false;}
else {$("#datepicker1").datepicker("option", "showWeek", true);showWeek=true;}
總之, 設定選項有兩種方法, 一是使用選項物件實體, 二是使用 option 動作; 但取得選項之值就只能用 option 動作.
測試範例 10 : http://tony1966.xyz/test/jquerytest/datepicker_10.htm [看原始碼]
此範例中有兩個元素, 一個是放置被選取日期的 input 元素, 一個是用來打開日曆的圖形 (也可以用按鈕或 a 元素) :
<input id="datepicker1" type="text">
<img id="open_calendar" src="calendar.gif">
當按下圖形時, 就呼叫 datepicker() 執行 dialog 動作, 選取日期後呼叫回呼函式去設定 input 元素之值 :
$("#datepicker1").datepicker("dialog", "2013-02-16", setDate, {dateFormat: "yy-mm-dd"});
function setDate(date) {$("#datepicker1").val(date);}
最後要介紹 datepicker 的公用函式, 有如下 5 個 :
formatDate 與 parseDate 是作用相反的函式, formatDate 是將日期物件按指定格式轉成日期字串傳回; 而 parseDate 則是將指定格式之日期字串轉成日期物件傳回. 而 iso8601Week 則是計算日期物件在一年中之周數傳回.
測試範例 11 : http://tony1966.xyz/test/jquerytest/datepicker_11.htm [看原始碼]
此範例中, 特地將 showWeek 選項打開以資與 iso8601Week 計算之結果比較印證, 兩者是一樣的. 首先以 getDate 取得被選取之日期物件, 先用 formatDate 轉成日期字串, 再用 parseDate 又轉回日期物件.
var date=$("#datepicker1").datepicker("getDate");
var date_str=$.datepicker.formatDate("yy-mm-dd", date);
var date_parsed=$.datepicker.parseDate("yy-mm-dd", date_str);
var week=$.datepicker.iso8601Week(date);
var msg=date_str + " 是第 " + week + " 週<br>" +
date_str + " 之日期物件內容 : " + date_parsed;
$("#msgbox1").html(msg);
$("#msgbox1").dialog("open");
以上就是 datepicker 的測試結果, 很長啊, 真是累死我了.
2013-11-27 補充 :
感謝網友戴兄的回應, 如果要對特定欄位, 例如指定星期一與星期四底色, 我查了 jQuery UI 文件, 其 API 中似乎僅 beforeShowDay 這個選項可以用, 但我測試的結果, 卻僅在各日期邊框套色, 並無法整個抽換掉底色 (那是用圖片做的). 原因是 beforeShowDay 乃是 jQuery UI 在描繪日立之前執行的設定, 即使指定了 background-image, 但描繪後全都被蓋掉.
如下範例 12 所示, 我將 themes\hot-sneaks\images 下的這張紅色的底圖取出改名為 hightlight.png :
ui-bg_diagonals-small_50_ff3853_40x40.png
然後用 beforeShowDay 這個選項來設定 :
$(document).ready(function(){
$("#datepicker1").datepicker({beforeShowDay: function(d) {
var day=d.getDay();
if (day==1 || day==4) {return [true,"myclass","Wow!"];}
else {return [true,"","Oops!"];}
}});
});
這裡 beforeShowDay 必須指定為一個三個元素之陣列, [0] 為 true/false, 標示該日期是否可選, [1] 為一樣式名稱字串, 表示該日期要套用之樣式, [2] 則為設定該日期提示字串. 我們以傳入日期物件 d 的匿名函式來傳回此陣列, 取得該日期的星期後, 若為星期一或星期四, 就傳回套用指定樣式之陣列, 否則傳回沒有套用任何樣式之陣列.
樣式 myclass內容如下 :
.myclass {color:white;background-image:url("hightlight.png");}
測試範例 12 : http://tony1966.xyz/test/jquerytest/datepicker_12.htm [看原始碼]
如果不套用底圖, 改套用底色, 效果可能較明顯, 如範例 13 所示 :
.myclass {color:white;background-color:red;}
測試範例 13 : http://tony1966.xyz/test/jquerytest/datepicker_13.htm [看原始碼]
這是目前找到的方法, 或許還有更好的方法也說不定.
至於戴兄的第二個問題, 希望設定今日的截止時間, 超過就不能選, 這主要是 Javascript 日期物件操控問題, datepicker 部分仍然跟上面問題一樣, 需要用 beforeShowDay 選項, 方法如範例 14 :
測試範例 14 : http://tony1966.xyz/test/jquerytest/datepicker_14.htm [看原始碼]
在範例 14 中, 我用 Date 物件的 getTime() 方法來取得自 1970/1/1 以來的毫秒數, 據此來控制傳回給 beforeShowDay 的陣列第一元素是 true/false 來控制可選與否. 我在日曆前面放了另外一個 text 輸入來設定截止時間, 預設為 12:00:00, 每次點日期選擇器時, jQuery UI 會去描繪日曆物件, 這時我們就可以在 beforeShowDate 選項裡, 利用回呼函式去判斷每一個傳入的日期, 搭配現在時間去判斷該日日期是否要設定為可選 :
<input id="deadline" type="text" value="12:00:00">
<input id="datepicker1" type="text">
以下回應戴兄另一詢問, 即是否可以讓輸入日期的 text 欄位僅容許 datepicker 挑選日期, 不讓使用者自行輸入, 這確實是一個實用的問題, 既然用了 jQuery UI, 當然不能還讓使用者可以亂填日期格式, 這問題只要在 input 元素中加入 readonly 來限制即可, 如下範例 15 所示 :
<input id="datepicker1" type="text" readonly="true" > 或者
<input id="datepicker1" type="text" readonly>
測試範例 15 : http://tony1966.xyz/test/jquerytest/datepicker_15.htm [看原始碼]
通常在網頁上用來輸入日期的通常是文字欄位的 input 元素 (我常用的是三個下拉式選單組合) :
<input id="datepicker1" type="text" />
這個陽春的日期輸入介面最大的缺點是, 使用者可能會亂輸入, 資料庫要的是 2013-04-15, 但輸入的可能是 4/16/2013, 而且要一一鍵入不方便. 有了 jQuery UI 後, 就可以呼叫 input 元素的 jQuery 物件的 datepicker() 方法來將 input 元素改裝成美美的日曆選取器 :
$("#datepicker1").datepicker();
這樣一來, 只要滑鼠在 input 文字欄位上點一下取得焦點後, 就會在 input 元素正下方出現一個日曆供選取日期, 例如 :
測試範例 1 : http://tony1966.xyz/test/jquerytest/datepicker_1.htm [看原始碼]
範例 1 中放置了三個日期選取器 :
$("#datepicker1").datepicker();
$("#datepicker2").datepicker({firstDay: 1});
$("#datepicker3").datepicker({appendText: "點一下顯示日曆"});
由 datepicker1 可知, 沒有傳入任何參數時, 日暦預設是英文版的, 而且預設一周是從星期天開始算的. 如果要更改一周之始, 必須傳入參數去設定日曆物件的 firstDay 選項. 如同其他 widget, 傳入參數最常用的是物件實體, 以 key:value 方式指定日曆的各個選項. 選項 firstDay 預設值為 0 (代表星期天), 星期一是 1, ... 星期六是 6. 在 datepicker2 我們將 firstDay 設為 1, 因此日曆的第一欄就是星期一. 另外, 選取日期後 input 元素預設顯示 mm/dd/yy 格式, 這不是我喜歡的 yy-mm-dd 格式, 這要用 dateFormat 選項設定, 稍後再介紹. 在 datepicker3 我們設定了選項 appendText 之值, 此字串會顯示在 input 元素後面, 通常用來作為提示之用.
先來處理本地化, 如果要顯示繁體中文, 就必須傳入特定的七個參數, 把預設的英文版覆蓋掉, 這叫做本地化 (localization). 本地化牽涉之選項有如下七個 :
星期 : dayNames (提示), dayNamesMin (星期欄位名稱)
月份 : monthNames (標題月份全名), monthNamesShort (標題月份下拉式選單簡名)
按鈕 : prevText (上月按鈕提示文字), nextText (次月按鈕提示文字)
週數 : weekHeader (週欄位名稱)
繁體中文化
var opt={
dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],
dayNamesMin:["日","一","二","三","四","五","六"],
monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
prevText:"上月",
nextText:"次月",
weekHeader:"週",
showMonthAfterYear:true,
dateFormat:"yy-mm-dd"
};
$("#datepicker1").datepicker(opt);
其中, 前七個便是繁體中文化所必須的七個選項, 第八個選項 showMonthAfterYear 是設定月份顯示在年份後面; 最後一個選項 dateFormat 則是設定 input 元素內之日期格式為例如 2013-04-15. 關於 dateFormate 選項的格式字串整理如下 :
| d | 每月的第幾日, 個位數時前面不補 0 |
| dd | 每月的第幾日, 兩位數, 個位數時前面補 0 |
| o | 每年的第幾日, 小於 100 時前面不補 0 |
| oo | 每年的第幾日, 三位數, 小於 100 時前面補 0 為 3 位數 |
| D | 星期的簡稱, 如 Fri |
| DD | 星期的全名, 如 Friday |
| m | 每年的第幾月, 個位數時前面不補 0 |
| mm | 每年的第幾月, 兩位數, 個位數時前面補 0 |
| M | 月份簡稱, 例如 Jan |
| MM | 月份全明, 例如 January |
| y | 兩位數的年, 個位數時前面補 0, 例如 05 |
| yy | 四位數的年, 例如 2005 |
| @ | 自 1970/1/1 至今之毫秒數 |
| ! | 自 0001/1/1 至今之奈秒數 (tick) |
| '' | 跳脫上述之模式字串 |
最後一個格式為單引號, 用來跳脫其他的格式字串, 例如要在 input 中顯示 "Selected yy-mm-dd", 因 Selected 中含模式字串 d, 必須跳脫, 故要寫成 "Selecte'd' yy-mm-dd", 把 d 字元用單引號括起來即可. 其實我都一律使用 yy-mm-dd, 這最簡單明瞭. 其實這個 "yy-mm-dd" 字串在 datepicker 的管理物件 (manager object) 中也有定義三個常數是 "yy-mm-dd" 的 :
$.datepicker.ATOM
$.datepicker.ISO_8601
$.datepicker.W3C
也就是說, {dateFormat: "yy-mm-dd"} 可以寫成 {dateFormat: $.datepicker.W3C}, 效果是一樣的. 我覺得還是 "yy-mm-dd" 比較好記.
測試範例 2 : http://tony1966.xyz/test/jquerytest/datepicker_2.htm [看原始碼]
如果網頁中不只用到一個日期選取器, 則每一個都要如上設定那七個選項似乎有點煩, 如果要一勞永逸, 可以使用 jQuery UI datepicker 管理物件 (manager object) 的 setDefaults() 方法來設定預設值, 這樣此網頁中任何一個日期選取器都會套用此繁體中文化設定 :
繁體中文化 (使用 setDefaults)
$.datepicker.regional['zh-TW']={
dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],
dayNamesMin:["日","一","二","三","四","五","六"],
monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
prevText:"上月",
nextText:"次月",
weekHeader:"週"
};
$("#datepicker1").datepicker({dateFormat:"yy-mm-dd",showMonthAfterYear:true});
其實, jQuery UI 早已做好國際化了, 它已經為各種語言寫好本地化 js 設定檔, 這些設定檔放在 jQuery UI 下載檔解壓縮後的 \ui\i18n 目錄下. 只要在匯入 jQuery UI 函式庫後, 接著匯入所需要語言的設定檔即可, 例如繁體中文設定檔為 jquery.ui.datepicker-zh-TW.js, 把它放在專案的 jquery 目錄下, 然後於網頁的 head 中匯入即可 :
<script type="text/javascript" src="http://tony1966.xyz/test/jquery/jquery.ui.datepicker-zh-TW.js"></script>
這樣只要直接呼叫 datepicker() 方法就可以本地化了, 不需再自行設定 (當然客製化除外).
$("#datepicker1").datepicker();
世界主要語言的本地化檔案如下表, 我已將這些檔案放在 http://tony1966.xyz/test/jquery/ 下, 其餘見下載檔解壓縮的 \ui\i18n 目錄 :
| 語言 | 本地化檔名 |
| 繁體中文 | jquery.ui.datepicker-zh-TW.js |
| 簡体中文 | jquery.ui.datepicker-zh-CN.js |
| 德語 | jquery.ui.datepicker-de.js |
| 法語 | jquery.ui.datepicker-fr.js |
| 西班牙語 | jquery.ui.datepicker-es.js |
| 阿拉伯語 | jquery.ui.datepicker-ar.js |
| 俄語 | jquery.ui.datepicker-ru.js |
| 日語 | jquery.ui.datepicker-ja.js |
| 韓語 | jquery.ui.datepicker-ko.js |
以下是這九種語言的本地化日曆, 可以發現 datepicker 中文簡體與繁體其實沒什麼差別.
測試範例 2-1 (繁體) : http://tony1966.xyz/test/jquerytest/datepicker_2_1.htm [看原始碼]
測試範例 2-2 (簡體) : http://tony1966.xyz/test/jquerytest/datepicker_2_2.htm [看原始碼]
測試範例 2-3 (日文) : http://tony1966.xyz/test/jquerytest/datepicker_2_3.htm [看原始碼]
測試範例 2-4 (韓文) : http://tony1966.xyz/test/jquerytest/datepicker_2_4.htm [看原始碼]
測試範例 2-5 (俄文) : http://tony1966.xyz/test/jquerytest/datepicker_2_5.htm [看原始碼]
測試範例 2-6 (阿文) : http://tony1966.xyz/test/jquerytest/datepicker_2_6.htm [看原始碼]
測試範例 2-7 (西文) : http://tony1966.xyz/test/jquerytest/datepicker_2_7.htm [看原始碼]
測試範例 2-8 (德文) : http://tony1966.xyz/test/jquerytest/datepicker_2_8.htm [看原始碼]
測試範例 2-9 (法文) : http://tony1966.xyz/test/jquerytest/datepicker_2_9.htm [看原始碼]
測試範例 2-10 (全部) : http://tony1966.xyz/test/jquerytest/datepicker_2_10.htm [看原始碼]
在測試範例 2-10, 我們把這九種語言整合在一起, 可以點擊國旗圖案 (來自 www.icondrawer.com), 利用 beforeShow 選項呼叫回呼函式來選擇本地化語系 :
var locale=$.datepicker.regional[""];
$("#en").click(function() {locale=$.datepicker.regional[""];});
$("#ar").click(function() {locale=$.datepicker.regional["ar"];});
....
$("#datepicker1").datepicker({beforeShow: set_locale});
function set_locale() {return locale;}
選項 beforeShow 用來設定日曆顯示前要呼叫的函式, 此回呼函式可以傳回選項物件實體, 以便在開啟日曆前先進行設定. 此處回呼函式傳回 $.datepicker.regional[] 來設定語系, 請注意, 本地化陣列 regional[] 之索引, 英文要設為空字串 [""].
接著我們來測試 showMonthAfterYear 與 showWeek 這兩個選項.
測試範例 3 : http://tony1966.xyz/test/jquerytest/datepicker_3.htm [看原始碼]
在範例 3 中, 放置了兩個日期選取器 :
$("#datepicker1").datepicker({dateFormat:"yy-mm-dd",showMonthAfterYear:true});
$("#datepicker2").datepicker({dateFormat:"yy-mm-dd",showWeek:true});
其中 datepicker1 將 showMonthAfterYear 設為 true, 所以日曆標題顯示的是 "2013年 四月"; 而 datepicker2 則為預設 false, 顯示的是 "四月 2013年", 但其 showWeek 選項設為 true, 所以日曆第一欄會顯示週數.
接下來要介紹三個選項 : changeYear, changeMonth 與 yearRange. 在前面範例中, 日曆的標題只是顯示年月字串, 如果要跳到去年或明年某月, 必須不斷按標題左右兩個按鈕 (次月, 上月) 有點麻煩 (循序式). 而 changeYear 與 changeMonth 此兩個選項若設為 true, 就會把標題中的年月字串分別改成下拉式選單, 可以直接選擇要顯示的哪一年哪一月日曆.
測試範例 4 : http://tony1966.xyz/test/jquerytest/datepicker_4.htm [看原始碼]
在範例 4 中, 放置了三個日期選取器 :
$("#datepicker1").datepicker({changeYear: true, changeMonth: true});
$("#datepicker2").datepicker({changeYear: true, changeMonth: true,
yearRange:"2010:2015"});
$("#datepicker3").datepicker({changeYear: true, changeMonth: true,
yearRange:"-5:+5"});
接著我們來測試 showOtherMonths 與 selectOtherMonths 這兩個選項, 前者設為 true 表示要顯示日曆中銜接上月底與下月初的日期, 以便把整個日曆填滿, 預設 false 不顯示; 但這些銜接日期預設都無法選取, 要靠後者設為 true 才行.
測試範例 5 : http://tony1966.xyz/test/jquerytest/datepicker_5.htm [看原始碼]
在範例 5 中放置了兩個日期選取器 :
$("#datepicker1").datepicker({showOtherMonths: true});
$("#datepicker2").datepicker({showOtherMonths: true, selectOtherMonths: true});
可見銜接日期會以較淡顏色顯示, datepicker1 中的銜接日期雖顯示但無法選取, 而 datepicker2 的則可以選取.
範例六我們來測試一下 dafaultDate, minDate 與 maxDate 這三個跟日期有關的選項, 其設定值格式都一樣. 選項 dafaultDate 用來設定日曆的預設日期, 也就是黃色高亮度的日期. 日曆打開時預設是讀取系統今日日期, 而我們設定 dafaultDate 選項就是要把這個系統日期覆蓋掉, 改為我們指定之日期. 而 minDate 與 maxDate 則是用來限制可選取日期範圍的選項. 選項 minDate 用來設定最小可選取日期, 小於此設定值之日期將不可選取; maxDate 用來設定最大可選取日期, 大於此設定值之日期將不可選取. 設定值可以是日期物件, 距離系統日期之日數, 或者是日期字串. 使用日期物件時要注意, Javascript 的日期物件函式 new Date(年,月, 日) 的參數中, 月是從 0 開始的, 因此四月要用 3 代入. 若 dafaultDate, minDate 與 maxDate 使用日期字串, 則必須先用 dateFormat 選項設定其日期格式, 否則會解讀成錯誤的日曆.
測試範例 6 : http://tony1966.xyz/test/jquerytest/datepicker_6.htm [看原始碼]
在範例 6 中放置了三個日期選取器 :
$("#datepicker1").datepicker({dateFormat:"yy-mm-dd",
dafaultDate: "2013-04-16", minDate: "2013-04-03"});
$("#datepicker2").datepicker({dafaultDate: new Date(2013, 3, 16),
minDate: "-5", maxDate: "10"});
$("#datepicker3").datepicker({dafaultDate: new Date(2013, 3, 16),
minDate: "-1y -1m -1w", maxDate: "+1y +1m +1w"});
第一個日曆中, 我們用 defaultDate 將預設日期設為 2013-04-16, 這樣不管哪一天顯示此網頁, 這日曆都會顯示 2013 年四月, 且 4 月 16 日高亮度. 其次, minDate 設為 "2013-04-03", 表示四月份中最小可選取日期為 4 月 3 日 (含), 4/1 與 4/2 都不可選取. 因為只設定 minDate, 沒有設定 maxDate, 因此 4/3 以後都是可選的, 而且次月按鈕都可以按, 而前月按鈕已經失能, 無法再按了. 特別注意這裡我們使用了日期字串來設定 minDate, 因此必須事先以 dateFormat 選項設定其格式, 要不然會剖析錯誤, 顯示 2018 年 10 月的日曆.
第二個日曆我們使用日期物件來設定 defaultDate, 用距離 (offset) 預設日期之日數來設定 minDate 與 maxDate. 因為 Javascript 的 Date 物件中, 月份為 0 起始的, 因此預設日期 2013 年 4 月 16 日要寫成 new Date(2013,3,16). 而 minDate: "-5" 表示最小可選取日為預設日期前 5 日, 也就是 16-5=11, 四月十一日; 而 maxDate: "10", 表示最大可選取日為預設日期後 10 日, 也就是 16+10=26, 四月二十六日. 注意, 因為我們限制可選日期為 4/3~4/26, 因此前月與次月按鈕都失能無法再按了, 如果將 changeYear 與 changeMonth 都設為 true, 則下拉式選單也會被限制選項只剩下 2013 年四月而已.
其實日期字串除了絕對值外, 也可以用相對值, 這是相對於預設日期而言. 在第三個日曆 datepicker3 中, minDate 與 maxDate 就使用了相對值. 其中 "-" 表示在預設日期之前, "+" 表示在預設日期之後, "y" 表示年, "m" 表示月, "d" 表示日, 所以 minDate: "-1y -1m -1w" 表示最小可選取日期為預設日期前一年一個月又一天, 預設日期是 2013-04-16 的話, 則 minDate 就是 2012-03-09; 同理 maxDate 則是 2014-05-23, 請按上月與次月按鈕印證.
關於限制可選取日期, 其實還有一個更常用的情況, 那就是將週六週日都設為不可選取. 請看測試範例 7 :
測試範例 7 : http://tony1966.xyz/test/jquerytest/datepicker_7.htm [看原始碼]
這裡用到 datepicker 管理物件的內建函式 $.datepicker.noWeekends(), 只要將日曆的 beforeShowDay 選項設定為呼叫此函式即可 :
$("#datepicker1").datepicker({beforeshowDay: $.datepicker.noWeekends});
選項 beforeShowDay 用來在顯示日期選取器中的每一天前, 呼叫指定的回呼函式, 如果回呼函式傳回的陣列中, 索引 0 為 true, 便將該日設為可選取, 反之 false 就設為不可選取. 它主要用來覆寫與星期有關的預設行為. 唯一傳入回呼函式的參數是星期, 例如 Friday. 而公用函式 $.datepicker.noWeekends 的作用就是判斷傳入的星期, 若是 Saturday 或 Sunday, 就把傳回陣列的索引 0 設為 false, 其他星期設為 true.
以上就是 datepicker 小工具常用的選項測試. 接下來要測試如何直接用程式設定 datepicker 的日期 (不是靠選取), 以及如何取得日曆小工具的日期. 這不是傳入選項物件, 而是在第一參數傳入 "動作字串" (actions) 與相關參數 params, 其格式為 :
$("#datepicker1").datepicker("action", params)
接著要介紹比較少用的四個選項, showOn, buttonImage, buttonImageOnly, buttonText. 通常我們都是擺個 input 元素當作日期選取器的承載元素, 當使用者點一下文字欄位, 就會自動打開日曆 , 這其實是 showOn 這個選項預設值為 "focus" 的緣故. 此選項有三個值 : "focus", "button", 以及 "both". 預設 "focus" 表示只要 input 元素一取得焦點, 日曆就會打開. 如果設為 "button", 則 input 元素後面會自動多出一個標題文字為 "..." 的按鈕, 這時點選 input 文字欄位就不會打開日曆了, 而是要按後面的那個按鈕, 如測試範例 8_1.
如果嫌 "..." 按鈕不知所云, 可以利用 buttonText 設定其標題文字, {buttonText: "日曆"}, 如測試範例 8_2. 也可以在按鈕上放置圖片來取代文字, {buttonImage: "calendar.gif"}, 當然這要上傳一個日曆圖檔到伺服器才行 (這個圖檔可以在 jQuery UI 下載檔解壓縮目錄 development-bundle\demos\datepicker\images 下找到). 這時即使同時有設定 buttonText, 按鈕上也只顯示圖片, 如測試範例 8_3.
因為按鈕使用 HTML 原生按鈕, 無法套用主題布景, 如果嫌按鈕難看, 也可以將 buttonImageOnly 選項設定為 true, {buttonImageOnly: true}, 這樣就會只顯示圖片, 不顯示按鈕, 如測試範例 8_4. 最後, 前述 showOn 選項設為 "button" 後, 點文字欄位不會再打開日曆, 而是必須按按鈕或圖片, 如果想魚與熊掌兼得的話, 那麼 showOn 選項要設為 "both", 如測試範例 8_5.
測試範例 8_1 : http://tony1966.xyz/test/jquerytest/datepicker_8_1.htm [看原始碼]
測試範例 8_2 : http://tony1966.xyz/test/jquerytest/datepicker_8_2.htm [看原始碼]
測試範例 8_3 : http://tony1966.xyz/test/jquerytest/datepicker_8_3.htm [看原始碼]
測試範例 8_4 : http://tony1966.xyz/test/jquerytest/datepicker_8_4.htm [看原始碼]
測試範例 8_5 : http://tony1966.xyz/test/jquerytest/datepicker_8_5.htm [看原始碼]
下面要介紹與選取事件有關的選項 onSelect, 以及 setDate, getDate, option 這三個動作.
測試範例 9 : http://tony1966.xyz/test/jquerytest/datepicker_9.htm [看原始碼]
此範例稍為複雜, 網頁元素有四個, 一個 input 做日曆輸入, 三個 button 按鈕, 第一個用來設定 input 的日期, 第二個用來取得選取的日期, 並用訊息盒顯示此日期, 第三個用來切換 showWeek 選項, 藉以說明 option 動作的 getter 與 setter 功能. 訊息盒需要一個 div 元素. 訊息盒用法參見 "jQuery UI widget 之確認盒應用範例" 這篇說明.
<input id="datepicker1" type="text" />
<button id="button1">設定日期為 2013-04-01</button>
<button id="button2">取得日期</button>
<div id="msgbox1" title="訊息"></div>
當使用者點一下 input 文字欄位, 在日曆中選取一個日期後, 就會顯示訊息盒告知被選取之日期. 這是加入 onSelect 選項的效果, 其值為一自訂之回呼函式 show_select(), 由這函式來打開訊息盒.
$("#datepicker1").datepicker({dateFormat:"yy-mm-dd",
onSelect: show_select
});
function show_select() {
var date=$("#datepicker1").datepicker("getDate");
$("#msgbox1").html("選取的日期 : " + date);
$("#msgbox1").dialog("open");
}
當使用者按 button1 時, 呼叫 datepicker() 方法執行 setDate 動作, 把 input 之日曆設為選取 2013 年 4 月 1 日.
$('#button1').click(function(){
$("#datepicker1").datepicker("setDate",new Date(2013,3,1));
});
當使用者按下 button2 時, 呼叫 datepicker() 方法執行 getDate 動作, 它會傳回被選取日期之日期物件. 我們可以呼叫日曆的公用函式 formatDate 來把日期物件格式化為字串, 最後把字串用訊息盒顯示出來 :
$('#button2').click(function(){
var date=$("#datepicker1").datepicker("getDate");
date=$.datepicker.formatDate("yy 年 M d 日", date);
$("#msgbox1").html("選取的日期 : " + date);
$("#msgbox1").dialog("open");
});
公用函式 formatDate 的語法為 : $.datepicker.formatDate(format, date[, options]), 第一參數為格式字串, 第二參數為日期物件, 有需要還可以傳入選項物件實體.
繼續來看看 dialog 動作, 此動作是要在對話盒中打開日曆, 而非在 input 元素的下方, 這通常要用一個按鈕來啟動, dialog 動作的參數如下 :
$("#datepicker1").datepicker("dialog", defaultDate, onselect[, options]);
其中第二參數用來設定日曆的預設日期, 可以是日期物件, 例如 new Date(2013,3,16), 或者是日期字串 "2013-04-16", 注意, 使用日期字串時必須帶入第四參數, 設定日期格式選項, 例如 {dateFormat: "yy-mm-dd"}. 如果傳入空字串 "" 表示預設為系統日期. 第三參數是選取日期後要呼叫的回呼函式, 通常用來設定 input 文字欄位元素之值.
範例 9 的第三個按鈕是用來測試 option 動作, 按下可以切換 showWeek 選項之值, 亦即 true 變 false, 或反之. option 動作可以傳入兩個參數 (getter) 或三個參數 (setter), 第二個參數要傳入選項名稱 (字串) :
取得選項之值 : datepicker("option", optionName)
設定選項之值 : datepicker("option", optionName, value)
當按下第三個按鈕時, 先用 getter 取得目前 showWeek 之值, 再進行切換 :
var showWeek=$("#datepicker1").datepicker("option", "showWeek");
if (showWeek) {$("#datepicker1").datepicker("option", "showWeek", false);showWeek=false;}
else {$("#datepicker1").datepicker("option", "showWeek", true);showWeek=true;}
總之, 設定選項有兩種方法, 一是使用選項物件實體, 二是使用 option 動作; 但取得選項之值就只能用 option 動作.
測試範例 10 : http://tony1966.xyz/test/jquerytest/datepicker_10.htm [看原始碼]
此範例中有兩個元素, 一個是放置被選取日期的 input 元素, 一個是用來打開日曆的圖形 (也可以用按鈕或 a 元素) :
<input id="datepicker1" type="text">
<img id="open_calendar" src="calendar.gif">
當按下圖形時, 就呼叫 datepicker() 執行 dialog 動作, 選取日期後呼叫回呼函式去設定 input 元素之值 :
$("#datepicker1").datepicker("dialog", "2013-02-16", setDate, {dateFormat: "yy-mm-dd"});
function setDate(date) {$("#datepicker1").val(date);}
最後要介紹 datepicker 的公用函式, 有如下 5 個 :
- $.datepicker.setDefaults([options])
- $.datepicker.formatDate(format, date [,options])
- $.datepicker.parseDate(format, date_str [,options])
- $.datepicker.iso8601Week(date)
- $.datepicker.noWeekends()
formatDate 與 parseDate 是作用相反的函式, formatDate 是將日期物件按指定格式轉成日期字串傳回; 而 parseDate 則是將指定格式之日期字串轉成日期物件傳回. 而 iso8601Week 則是計算日期物件在一年中之周數傳回.
測試範例 11 : http://tony1966.xyz/test/jquerytest/datepicker_11.htm [看原始碼]
此範例中, 特地將 showWeek 選項打開以資與 iso8601Week 計算之結果比較印證, 兩者是一樣的. 首先以 getDate 取得被選取之日期物件, 先用 formatDate 轉成日期字串, 再用 parseDate 又轉回日期物件.
var date=$("#datepicker1").datepicker("getDate");
var date_str=$.datepicker.formatDate("yy-mm-dd", date);
var date_parsed=$.datepicker.parseDate("yy-mm-dd", date_str);
var week=$.datepicker.iso8601Week(date);
var msg=date_str + " 是第 " + week + " 週<br>" +
date_str + " 之日期物件內容 : " + date_parsed;
$("#msgbox1").html(msg);
$("#msgbox1").dialog("open");
以上就是 datepicker 的測試結果, 很長啊, 真是累死我了.
2013-11-27 補充 :
感謝網友戴兄的回應, 如果要對特定欄位, 例如指定星期一與星期四底色, 我查了 jQuery UI 文件, 其 API 中似乎僅 beforeShowDay 這個選項可以用, 但我測試的結果, 卻僅在各日期邊框套色, 並無法整個抽換掉底色 (那是用圖片做的). 原因是 beforeShowDay 乃是 jQuery UI 在描繪日立之前執行的設定, 即使指定了 background-image, 但描繪後全都被蓋掉.
如下範例 12 所示, 我將 themes\hot-sneaks\images 下的這張紅色的底圖取出改名為 hightlight.png :
ui-bg_diagonals-small_50_ff3853_40x40.png
然後用 beforeShowDay 這個選項來設定 :
$(document).ready(function(){
$("#datepicker1").datepicker({beforeShowDay: function(d) {
var day=d.getDay();
if (day==1 || day==4) {return [true,"myclass","Wow!"];}
else {return [true,"","Oops!"];}
}});
});
這裡 beforeShowDay 必須指定為一個三個元素之陣列, [0] 為 true/false, 標示該日期是否可選, [1] 為一樣式名稱字串, 表示該日期要套用之樣式, [2] 則為設定該日期提示字串. 我們以傳入日期物件 d 的匿名函式來傳回此陣列, 取得該日期的星期後, 若為星期一或星期四, 就傳回套用指定樣式之陣列, 否則傳回沒有套用任何樣式之陣列.
樣式 myclass內容如下 :
.myclass {color:white;background-image:url("hightlight.png");}
測試範例 12 : http://tony1966.xyz/test/jquerytest/datepicker_12.htm [看原始碼]
如果不套用底圖, 改套用底色, 效果可能較明顯, 如範例 13 所示 :
.myclass {color:white;background-color:red;}
測試範例 13 : http://tony1966.xyz/test/jquerytest/datepicker_13.htm [看原始碼]
這是目前找到的方法, 或許還有更好的方法也說不定.
至於戴兄的第二個問題, 希望設定今日的截止時間, 超過就不能選, 這主要是 Javascript 日期物件操控問題, datepicker 部分仍然跟上面問題一樣, 需要用 beforeShowDay 選項, 方法如範例 14 :
測試範例 14 : http://tony1966.xyz/test/jquerytest/datepicker_14.htm [看原始碼]
在範例 14 中, 我用 Date 物件的 getTime() 方法來取得自 1970/1/1 以來的毫秒數, 據此來控制傳回給 beforeShowDay 的陣列第一元素是 true/false 來控制可選與否. 我在日曆前面放了另外一個 text 輸入來設定截止時間, 預設為 12:00:00, 每次點日期選擇器時, jQuery UI 會去描繪日曆物件, 這時我們就可以在 beforeShowDate 選項裡, 利用回呼函式去判斷每一個傳入的日期, 搭配現在時間去判斷該日日期是否要設定為可選 :
<input id="deadline" type="text" value="12:00:00">
<input id="datepicker1" type="text">
以下回應戴兄另一詢問, 即是否可以讓輸入日期的 text 欄位僅容許 datepicker 挑選日期, 不讓使用者自行輸入, 這確實是一個實用的問題, 既然用了 jQuery UI, 當然不能還讓使用者可以亂填日期格式, 這問題只要在 input 元素中加入 readonly 來限制即可, 如下範例 15 所示 :
<input id="datepicker1" type="text" readonly="true" > 或者
<input id="datepicker1" type="text" readonly>
測試範例 15 : http://tony1966.xyz/test/jquerytest/datepicker_15.htm [看原始碼]
2013年4月10日 星期三
Newsweek 紙本最後一期
整理書櫃時找到去年12月下旬收到的紙本 Newsweek 最後一期, 我忙得根本沒拆封, 其實說來慚愧, 以學生價訂了一年 $1960, 收到兩次贈品 (小行李箱), 最後沒滿期還退費. 當初本想像以前那樣, 以避免浪費一定會看的心理, 答應雜誌社小姐訂下去, 結果來了半年卻看不到一半. 唉, 英文真的會退步啦. 其實現在都在忙 IT, 根本沒時間忙別的, 要認清事實啊.
2013年4月8日 星期一
支援各瀏覽器圓角 (round corner) 的辦法
我測試 jQuery 的 Tab 功能發現, 在 Chrome 與 Firefox 上都能完美展現圓角, 不論是 Tab 或按鈕, 任何 UI widget 都有圓角效果, 唯獨 IE 例外, 即使 IE 8 也是如此, 方方的不好看, 改天到燦坤試試 IE9 有沒有長進些.
我搜尋 IE 圓角解決方案, 發現這裡有一個不錯的辦法 :
CSS Rounded Corners In All Browsers (With No Images)
先到這裡下載 border-radius.htc 檔 :
https://code.google.com/p/curved-corner/downloads/list
然後在網頁中替需要圓角的元素加上樣式 (高亮度部份就是專治 IE 的) :
<style type="text/css"></p>
.box {background-color: #ddd;
width: 210px;
height: 30px;
padding: 20px;
position: absolute;
top: 5px; left: 5px;
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
border-radius: 15px;
behavior: url(border-radius.htc);
}
<style>
<div class="box"> Round Corner</div>
只是不知這有沒有辦法整合到 jQuery UI 中, 有空再測試看看. 下圖上面的是 Chrome/Firefox, 下面是 IE8.
我搜尋 IE 圓角解決方案, 發現這裡有一個不錯的辦法 :
CSS Rounded Corners In All Browsers (With No Images)
先到這裡下載 border-radius.htc 檔 :
https://code.google.com/p/curved-corner/downloads/list
然後在網頁中替需要圓角的元素加上樣式 (高亮度部份就是專治 IE 的) :
<style type="text/css"></p>
.box {background-color: #ddd;
width: 210px;
height: 30px;
padding: 20px;
position: absolute;
top: 5px; left: 5px;
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
border-radius: 15px;
behavior: url(border-radius.htc);
}
<style>
<div class="box"> Round Corner</div>
只是不知這有沒有辦法整合到 jQuery UI 中, 有空再測試看看. 下圖上面的是 Chrome/Firefox, 下面是 IE8.
訂閱:
文章
(
Atom
)



