2013年4月25日 星期四

如何在 jQuery UI 的日期選擇器上附加時間選擇器 timepicker

jQuery UI 的日期選擇器非常容易使用, 但是在專案中我通常要用到 "2013-04-17 12:10:00" 這樣的完整日期時間格式 (例如要設定佈告發布時間, 修改日誌紀錄時間等等), 這樣 jQuery UI 的datepicker 小工具就沒辦法一次到位了, 在官網也找不到時間選擇器, 本來想, 時間部分就用老方法-下拉式選單吧.
上週去受訓時用電腦找了一下, 發現已經有人 (Trent Richardson) 幫 datepicker 加工裝上時間選擇器了. 這個第三方插件 datetimepicker 可在下列網址下載 :

Adding a Timepicker to jQuery UI Datepicker [下載 (zip)]

其實這個 addon 是繼承 jQuery UI 的 datepicker 小工具, 再加上時間選擇器而成, 因此原來的日期選擇器設定方式不變, 但添加了時間選擇器的選項. 下載此插件 zip 檔後解壓縮, 將下列檔案複製到專案目錄的 jquery 下 :

jquery-ui-timepicker-addon.js (插件主程式)
jquery-ui-sliderAccess.js (支援按鈕+滑動軸功能)
jquery-ui-timepicker-addon.css (時間選擇器樣式設定)

然後在網頁的 head 中, 除了 jQuery 與 jQuery UI 函式庫外, 還要再匯入這三個檔案 :
<link href="jquery/jquery-ui-timepicker-addon.css" rel="stylesheet"></link>
<script src="jquery/jquery-ui-timepicker-addon.js" type="text/javascript"></script>
<script src="jquery/jquery-ui-sliderAccess.js" type="text/javascript"></script>

然後如同日期選取器一樣, 放一個 input 文字欄位元素 :

<input id="datetimepicker1" type="text" />

接著呼叫該 input 元素包裹物件元素的 datetimepicker() 方法即可, 如範例 1 所示 :

$('#datetimepicker1').datetimepicker();

測試範例 1 : http://tony1966.xyz/test/jquerytest/datetimepicker_1.htm [看原始碼]

在範例 1 中, 我們並未傳任何參數進去 datetimepicker() 中, 可見預設語言是英文, 預設日期格式 dateFormat 為 "mm/dd/yy", 預設時間格式 timeFormat 為 HH:mm, 兩者以空格串接. 預設時間選擇器類型為 slider (滑動桿), 其滑動步階預設值時分秒均為 1. 當滑動桿移動時, 日曆上的 Time 顯示以及 input 文字欄位中的時或分也會立即改變. 按下日曆左下角的 "Now" 按鈕會填入現在系統的時間, 按下 "Close" 按鈕則關閉日曆.
一般我最常用的完整日期時間格式為 "2013-04-17 12:10:00",  要達到此目標, 日期選擇器部分當然是用選項 {dateFormat: "yy-mm-dd"}, 時間選擇器部分則是需要兩個選項 showSecond 與 timeFormat, 前者預設為 false, 因此不會顯示秒數滑桿, 而後者預設值為 "HH:mm" 不顯示秒數. 在下列範例 2 中, 我們就傳入這三個選項 :

var opt={dateFormat: 'yy-mm-dd',
              showSecond: true,
               timeFormat: 'HH:mm:ss'
               };
$('#datetimepicker1').datetimepicker(opt);

測試範例 2 : http://tony1966.xyz/test/jquerytest/datetimepicker_2.htm [看原始碼]

從範例 2 可知, {showSecond: true} 會讓時間選取器多出秒數滑桿, 而 {timeFormat: 'HH:mm:ss'} 則顯示完整的時分秒格式. 選項 timeFormat 的可用格式如下 :

timeFormat 格式
 H     24 小時制時數, 個位數時前面不補 0
 HH 24 小時制時數 (兩位數), 個位數時前面補 0
 h 12 小時制時數, 個位數時前面不補 0
 hh 12 小時制時數 (兩位數), 個位數時前面補 0
 m 分數, 個位數時前面不補 0
 mm 分數 (兩位數), 個位數時前面補 0
 s 秒數, 個位數時前面不補 0
 ss 秒數 (兩位數), 個位數時前面補 0
 t 早上顯示 "a" 表示 AM, 下午顯示 "p" 表示 PM
 tt 早上顯示 "am" 表示 AM, 下午顯示 "pm" 表示 PM
 T 早上顯示 "A" 表示 AM, 下午顯示 "P" 表示 PM
 TT 早上顯示 "AM" 表示 AM, 下午顯示 "PM" 表示 PM
 z 顯示時區
 l (小寫 L) 毫秒數, 前面補 0
 '' 顯示字串

接下來我們來測試一下不同類型的時間選擇器, datetimepicker 小工具提供三種選擇器類型 (可以利用 controlType 選項客製化), 預設就是上面看到的 slider 滑桿 :

 時間選取器型態 相關選項
 滑動桿 (預設)var opt={stepHour:1, stepMinute:1, stepSecond:1};
 下拉式選單var opt={controlType:"select"};
 滑動桿+按鈕var opt={addSliderAccess:true,sliderAccessArgs:{touchonly:false}};

下列範例 3 我們放了三個日曆來分別測試這三種類型 :


測試範例 3 : http://tony1966.xyz/test/jquerytest/datetimepicker_3.htm [看原始碼]


var opt1={dateFormat: 'yy-mm-dd',
               showSecond: true,
                timeFormat: 'HH:mm:ss',
               stepHour:2, 
               stepMinute:5, 
               stepSecond:10 
               };
var opt2={dateFormat: 'yy-mm-dd',
                showSecond: true,
                timeFormat: 'HH:mm:ss',
                controlType:"select" 
                };
var opt3={dateFormat: 'yy-mm-dd',
               showSecond: true,
               timeFormat: 'HH:mm:ss',
               addSliderAccess:true, 
               sliderAccessArgs:{touchonly:false}  
               };
$('#datetimepicker1').datetimepicker(opt1);
$('#datetimepicker2').datetimepicker(opt2);
$('#datetimepicker3').datetimepicker(opt3);

其中 datetimepicker1 我們使用 stepHour, stepMinute, stepSecond 三個選項來分別設定時分秒三個滑桿滑動時的步階, 秒數每格為 10 秒, 這樣一來就要間隔 10 秒以上按左下角的 "Now" 時, 才會改變 input 內的秒數了. 而 datetimepicker2 則使用 controlType 選項將時間選擇器改為下拉式選單. controlType 預設值為 "slider". 第三個日曆 datetimepicker3 中使用 addSliderAccess 與 sliderAccessArgs 兩個選項, 前者設為 true 表示要加上 +/- 按鈕來控制滑桿, 而後者將 touchonly 設為 false 表示也要顯示滑桿. 我覺得還是預設的單純滑桿簡單好用.

接下來我們要測試四個跟時間預設值有關的選項, hour, minute, second, 以及 defaultValue. 前面三個選項用來設定時間選取器預設值, 而 defaultValue 則是用來設定 input 元素內的時間預設值, 與選擇時間的滑桿無關, 其格式需配合 timeFormat 選項. 這跟日期選取器的 setDate 動作是類似的. 

測試範例 4 : http://tony1966.xyz/test/jquerytest/datetimepicker_4.htm [看原始碼]

功能在範例 4 中我們放置了兩個日曆, 其中 datetimepicker1 以 hour, minute, second 選項設定滑桿的初始值, 而 datetimepicker2 則以 defaultValue 設定 input 元素之初始時間值, 只要一打開日曆, 其值便被設定於 input 欄位內, 但其實這沒甚麼用處. 如果是要修改資料庫中的一個日期欄位, 只要在 PHP 中讀取出來後, 直接放在 input 元素的 value 屬性中就可以了, 沒必要用到 defaultValue, 倒是 hour, minute, second 三個選項比較有用, 可以讓日曆一打開, 滑桿就放在預設位置上了.


var opt1={dateFormat: 'yy-mm-dd',
                 defaultDate: '2013-03-17',
                 showSecond: true,
                 timeFormat: 'HH:mm:ss',
                 hour:13,   
                 minute:25,   
                 second:10  
                 };
var opt2={dateFormat: 'yy-mm-dd',
                defaultDate: '2013-03-17',
                showSecond: true,
                timeFormat: 'HH:mm:ss',
                defaultValue:"13:25:10"  
                };
$('#datetimepicker1').datetimepicker(opt1);
$('#datetimepicker2').datetimepicker(opt2);

接著來看看三個可能會用到的選項 : separator, showTime, 與 showButtonPanel. 前面範例中, 日期與時間是以一個空格串接, 其實這是 separator 選項的預設值為 " " (一個空格) 之故. 其次, showTime 選項是用來控制是否要在日曆中間顯示所選取之時間, 預設是 true. 而 showButtonPanel 則是用來設定是否顯示日曆下方的 "Now" 與 "Close" 兩個按鈕, 預設是 true (其實選項  showButtonPanel 是 datepicker 定義的, 預設是 false 不顯示, 但 datetimepicker 繼承它時改為預設 true). 如果用不到就可以將其設為 false, 這樣日曆版面會比較簡潔. 雖然我認為下方那兩個按鈕不需要, 但日曆中間的時間顯示仍需要保留, 因為有時候日曆會蓋住 input 元素, 導致調整滑桿時不知道現在的調整值, 所以 showTime 還是維持預設 true 較好.

測試範例 5 : http://tony1966.xyz/test/jquerytest/datetimepicker_5.htm [看原始碼]

在範例 5 中, 我們把日期與時間的分隔字元改為 "#", 同時取消中間的時間顯示, 以及下方的兩個按鈕. 這樣日曆看起來就清爽多了吧!

var opt1={dateFormat: 'yy-mm-dd',
                 defaultDate: '2013-03-17',
                 showSecond: true,
                 timeFormat: 'HH:mm:ss',
                 separator: '#',
                 showTime: false,
                 showButtonPanel: false
                };
$('#datetimepicker1').datetimepicker(opt1);

最後來看看時間選擇器的本地化, 這需要以本地語言覆蓋下列 11 個選項的預設值 (英文) : timeOnlyTitle, timeText", hourText, minuteText, secondText, millisecText, timezoneText, currentText, closeText, amNames,  pmNames. 但這 11 個只是 timepicker 部分, 必須同時搭配上半部 datepicker 部分的本地化才完整. 範例 6 為繁體中文化的第一個測試 :

測試範例 6 : http://tony1966.xyz/test/jquerytest/datetimepicker_6.htm [看原始碼]


繁體中文化

var opt={
   //以下為日期選擇器部分
   dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],
   dayNamesMin:["日","一","二","三","四","五","六"],
   monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
   monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
   prevText:"上月",
   nextText:"次月",
   weekHeader:"週",
   showMonthAfterYear:true,
   dateFormat:"yy-mm-dd",
   //以下為時間選擇器部分
   timeOnlyTitle:"選擇時分秒",
   timeText:"時間",
   hourText:"時",
   minuteText:"分",
   secondText:"秒",
   millisecText:"毫秒",
   timezoneText:"時區",
   currentText:"現在時間",
   closeText:"確定",
   amNames:["上午","AM","A"],
   pmNames:["下午","PM","P"],
   timeFormat:"HH:mm:ss"
   };
$("#datetimepicker1").datetimepicker(opt);


在範例 6 中我們也在 input 元素的 value 屬性中給予初始值, 模擬 PHP 從資料庫提取出來的日期時間欄位 :

<input id="datetimepicker1" type="text" value="2013-04-17 12:10:00"/>

點一下 input 欄位, 日期與時間選擇器都被設定為初始值了.

測試範例 7 : http://tony1966.xyz/test/jquerytest/datetimepicker_7.htm [看原始碼]

上面範例 6 是以直接設定選項方式來本地化, 如果網頁中要用到好幾個 datetimepicker, 每次都要這樣設定就太累了, 因為這個 datetimepicker 也繼承了 setDefault() 方法, 所以可以用 reginal 陣列來儲存本地化選項值, 日期與時間要分別用 datepicker 與 timepicker 設定, 這樣此網頁中的每一個日期時間選擇器都會套用此預設值而本地化 :

繁體中文化 (使用 setDefault)

$.datepicker.regional['zh-TW']={
   dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],
   dayNamesMin:["日","一","二","三","四","五","六"],
   monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
   monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
   prevText:"上月",
   nextText:"次月",
   weekHeader:"週",
   };
$.timepicker.regional['zh-TW']={
   timeOnlyTitle:"選擇時分秒",
   timeText:"時間",
   hourText:"時",
   minuteText:"分",
   secondText:"秒",
   millisecText:"毫秒",
   timezoneText:"時區",
   currentText:"現在時間",
   closeText:"確定",
   amNames:["上午","AM","A"],
   pmNames:["下午","PM","P"]
   };
$.datepicker.setDefaults($.datepicker.regional["zh-TW"]);
$.timepicker.setDefaults($.timepicker.regional["zh-TW"]);
$("#datetimepicker1").datetimepicker({dateFormat:"yy-mm-dd", 
                                                        timeFormat:"HH:mm:ss",
                                                        showSecond:true
                                                        });

其實 datetimepicker 小工具的作者非常佛心, 早已用上面的 setDefaults() 方法為 timepicker 部分做好許多語言的本地化檔案, 這些都放在解壓縮檔的 localization 目錄下, 例如繁體中文為 jquery-ui-timepicker-zh-TW.js, 韓文則為 jquery-ui-timepicker-ko.js 等等.
我們把本地化 js 檔複製到專案的 jquery 目錄下, 同時在 head 中匯入此本地化檔案, 那麼就不需要自行設定本地化選項了, 連同 datepicker 本身的本地化檔案, 完整的繁體中文的日期時間 widget 需要匯入下列檔案 :

<link href='jquery/jquery-ui-timepicker-addon.css' rel='stylesheet'>
<script type="text/javascript" src="jquery/jquery-ui-timepicker-addon.js"></script>
<script type='text/javascript' src='jquery/jquery-ui-sliderAccess.js'></script>
<script type="text/javascript" src="jquery/jquery.ui.datepicker-zh-TW.js"></script>
<script type="text/javascript" src="jquery/jquery-ui-timepicker-zh-TW.js"></script>

這樣呼叫 datetimepicker() 時就只要傳入需要的選項即可, 不必再管那些本地化選項了 :

$('#datetimepicker1').datetimepicker({showMonthAfterYear: true,
                                                          dateFormat: 'yy-mm-dd',
                                                          timeFormat: 'HH:mm:ss',
                                                          showSecond: true,
                                                          showButtonPanel: false,
                                                          showTime: false
                                                          });

繁體中文的實際測試詳見範例 8.

測試範例 8 : http://tony1966.xyz/test/jquerytest/datetimepicker_8.htm [看原始碼]

其他語言的本地化就不再一一測試, 僅舉韓語為例如範例 9.

<script type="text/javascript" src="jquery/jquery.ui.datepicker-ko.js"></script>
<script type="text/javascript" src="jquery/jquery-ui-timepicker-ko.js"></script>

測試範例 9 : http://tony1966.xyz/test/jquerytest/datetimepicker_9.htm [看原始碼

http://trentrichardson.com/examples/timepicker/

9 則留言 :

Unknown 提到...

您好,
看完您的"如何在 jQuery UI 的日期選擇器上附加時間選擇器 timepicker"後,
我有一個實作的疑問,
請問datetimepicker如何像datepicker一樣選擇一個日期時間範圍,

datepicker是通過如下的程式碼,請問datetimepicker是如何設定呢?
onClose: function( selectedDate ) {
$( "#to" ).datepicker( "option", "minDate", selectedDate );

小狐狸事務所 提到...

Sorry, datetimepicker 我沒有進一步測試, 所以也還不知道如何設定.

匿名 提到...

大大可以請問一下網業為何開起會跑到另外一個網頁

小狐狸事務所 提到...

您是說哪一個網頁呢?

terry 提到...


"如何在 jQuery UI 的日期選擇器上附加時間選擇器 timepicker"
這個裡面的範例我點開都跳到另外的頁面

小狐狸事務所 提到...

這是我上周遷移主機時的漏網之魚, 現在已經改好了, 謝謝! 參考 :

http://yhhuang1966.blogspot.tw/2017/06/blog-post_8.html

terry 提到...

想請問大大那個檔案我下載好我全部丟進jquery為何會出現錯誤?

小狐狸事務所 提到...

甚麼錯誤呢? 要注意 javascript 的路徑

terry 提到...

Tony大大:
我之前指的錯誤示指我丟進我的專案下面在我的程式編輯那檔案顯示紅色XX,不過這個我上網爬文解決了
我現在碰到路徑問題
我放在
C:\Users\LJ\Workspaces\MyEclipse Professional\raphael\WebRoot\jquery
< href='../jquery/jquery-ui-timepicker-addon.css' rel='stylesheet'>
< type="text/javascript" src="../jquery/jquery-ui-timepicker-addon.js"><>
< type='text/javascript' src='../jquery/jquery-ui-sliderAccess.js'><>
我路徑怎麼設都無法呼叫到檔案