BS3 datetimepicker
簡介
在基本的 BS3 中並沒有提供圖形的日曆介面以供選取日期,必須使用額外的插件 (plug-in)。在網路上可以找到很多 BS3 的日期選取插件, https://eonasdan.github.io/bootstrap-datetimepicker/ 這個插件可說是廣受歡迎。這個插件除了架構於 jQuery 及 Bootstrap 3 之上,還另需一個 Moment.js 的 JavaScript 程式館,可由 http://momentjs.com/ 下載。如果必須客製顯示日期時使用的語言,則下載 moment-with-locales.js 程式館。
datetimepicker 這個插件,並沒有定義容器類別,必須透過 JavaScript 在程式中建立。建立 datatimepicker 時,常用的傳入參數略述如下:
- viewMode
- 允許值為 'decades','years','months','days',預設為 'days'。指定日期選取插件顯示時的內容格式。
- locale
- 指定顯示日期時所要使用的語言,正體中文為 'zh-TW'。
- daysOfWeekDisabled
- 允許值為一陣列,內中包含 0 到 6 的數值,0 代表週日,其它數值則代表一週中對應的日子。日期選取插件顯示時,會將陣列中數值對應的日子,顯示為無法選取。
- format
- 設定日期及時間的格式,只設定日期格式時,會隱藏時間的選取介面; 只設定時間格式時,會隱藏日期的選取介面。也就是說這個參數的值,也同時用來設定輸入時只能選取日期,或只能選取時間。
- toolbarPlacement
- 允許值為 'top', 'bottom',預設為 'bottom'。用來設定工具列出現的位置。
- showTodayButton
- 允許值為 true/false,預設為 false。在工具列中顯示「今日」按鈕,圖像為「準星」;點按時會自行輸入當日日期及時間。
- showClear
- 允許值為 true/false,預設為 false。在工具列中顯示「清除」按鈕,圖像為「拉圾」;點按時會清除日期輸入值。
- showClose
- 允許值為 true/false,預設為 false。在工具列中顯示「關閉」按鈕,圖像為 "X";點按時會隱藏日期選取介面。
以下為 datetimepicker.css 樣式表的內容。
<style> /*! * Datetimepicker for Bootstrap 3 * version : 4.17.42 * https://github.com/Eonasdan/bootstrap-datetimepicker/ */ .bootstrap-datetimepicker-widget { list-style: none; } .bootstrap-datetimepicker-widget.dropdown-menu { margin: 2px 0; padding: 4px; width: 19em; } @media (min-width: 768px) { .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { width: 38em; } } @media (min-width: 992px) { .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { width: 38em; } } @media (min-width: 1200px) { .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { width: 38em; } } .bootstrap-datetimepicker-widget.dropdown-menu:before, .bootstrap-datetimepicker-widget.dropdown-menu:after { content: ''; display: inline-block; position: absolute; } .bootstrap-datetimepicker-widget.dropdown-menu.bottom:before { border-left: 7px solid transparent; border-right: 7px solid transparent; border-bottom: 7px solid #ccc; border-bottom-color: rgba(0, 0, 0, 0.2); top: -7px; left: 7px; } .bootstrap-datetimepicker-widget.dropdown-menu.bottom:after { border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 6px solid white; top: -6px; left: 8px; } .bootstrap-datetimepicker-widget.dropdown-menu.top:before { border-left: 7px solid transparent; border-right: 7px solid transparent; border-top: 7px solid #ccc; border-top-color: rgba(0, 0, 0, 0.2); bottom: -7px; left: 6px; } .bootstrap-datetimepicker-widget.dropdown-menu.top:after { border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 6px solid white; bottom: -6px; left: 7px; } .bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before { left: auto; right: 6px; } .bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after { left: auto; right: 7px; } .bootstrap-datetimepicker-widget .list-unstyled { margin: 0; } .bootstrap-datetimepicker-widget a[data-action] { padding: 6px 0; } .bootstrap-datetimepicker-widget a[data-action]:active { box-shadow: none; } .bootstrap-datetimepicker-widget .timepicker-hour, .bootstrap-datetimepicker-widget .timepicker-minute, .bootstrap-datetimepicker-widget .timepicker-second { width: 54px; font-weight: bold; font-size: 1.2em; margin: 0; } .bootstrap-datetimepicker-widget button[data-action] { padding: 6px; } .bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Increment Hours"; } .bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Increment Minutes"; } .bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Decrement Hours"; } .bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Decrement Minutes"; } .bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Show Hours"; } .bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Show Minutes"; } .bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Toggle AM/PM"; } .bootstrap-datetimepicker-widget .btn[data-action="clear"]::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Clear the picker"; } .bootstrap-datetimepicker-widget .btn[data-action="today"]::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Set the date to today"; } .bootstrap-datetimepicker-widget .picker-switch { text-align: center; } .bootstrap-datetimepicker-widget .picker-switch::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Toggle Date and Time Screens"; } .bootstrap-datetimepicker-widget .picker-switch td { padding: 0; margin: 0; height: auto; width: auto; line-height: inherit; } .bootstrap-datetimepicker-widget .picker-switch td span { line-height: 2.5; height: 2.5em; width: 100%; } .bootstrap-datetimepicker-widget table { width: 100%; margin: 0; } .bootstrap-datetimepicker-widget table td, .bootstrap-datetimepicker-widget table th { text-align: center; border-radius: 4px; } .bootstrap-datetimepicker-widget table th { height: 20px; line-height: 20px; width: 20px; } .bootstrap-datetimepicker-widget table th.picker-switch { width: 145px; } .bootstrap-datetimepicker-widget table th.disabled, .bootstrap-datetimepicker-widget table th.disabled:hover { background: none; color: #777777; cursor: not-allowed; } .bootstrap-datetimepicker-widget table th.prev::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Previous Month"; } .bootstrap-datetimepicker-widget table th.next::after { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; content: "Next Month"; } .bootstrap-datetimepicker-widget table thead tr:first-child th { cursor: pointer; } .bootstrap-datetimepicker-widget table thead tr:first-child th:hover { background: #eeeeee; } .bootstrap-datetimepicker-widget table td { height: 54px; line-height: 54px; width: 54px; } .bootstrap-datetimepicker-widget table td.cw { font-size: .8em; height: 20px; line-height: 20px; color: #777777; } .bootstrap-datetimepicker-widget table td.day { height: 20px; line-height: 20px; width: 20px; } .bootstrap-datetimepicker-widget table td.day:hover, .bootstrap-datetimepicker-widget table td.hour:hover, .bootstrap-datetimepicker-widget table td.minute:hover, .bootstrap-datetimepicker-widget table td.second:hover { background: #eeeeee; cursor: pointer; } .bootstrap-datetimepicker-widget table td.old, .bootstrap-datetimepicker-widget table td.new { color: #777777; } .bootstrap-datetimepicker-widget table td.today { position: relative; } .bootstrap-datetimepicker-widget table td.today:before { content: ''; display: inline-block; border: solid transparent; border-width: 0 0 7px 7px; border-bottom-color: #337ab7; border-top-color: rgba(0, 0, 0, 0.2); position: absolute; bottom: 4px; right: 4px; } .bootstrap-datetimepicker-widget table td.active, .bootstrap-datetimepicker-widget table td.active:hover { background-color: #337ab7; color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .bootstrap-datetimepicker-widget table td.active.today:before { border-bottom-color: #fff; } .bootstrap-datetimepicker-widget table td.disabled, .bootstrap-datetimepicker-widget table td.disabled:hover { background: none; color: #777777; cursor: not-allowed; } .bootstrap-datetimepicker-widget table td span { display: inline-block; width: 54px; height: 54px; line-height: 54px; margin: 2px 1.5px; cursor: pointer; border-radius: 4px; } .bootstrap-datetimepicker-widget table td span:hover { background: #eeeeee; } .bootstrap-datetimepicker-widget table td span.active { background-color: #337ab7; color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .bootstrap-datetimepicker-widget table td span.old { color: #777777; } .bootstrap-datetimepicker-widget table td span.disabled, .bootstrap-datetimepicker-widget table td span.disabled:hover { background: none; color: #777777; cursor: not-allowed; } .bootstrap-datetimepicker-widget.usetwentyfour td.hour { height: 27px; line-height: 27px; } .bootstrap-datetimepicker-widget.wider { width: 21em; } .bootstrap-datetimepicker-widget .datepicker-decades .decade { line-height: 1.8em !important; } .input-group.date .input-group-addon { cursor: pointer; } .sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; } </style>
範例
範例中建立了三個日期/時間的輸入選取介面。由左至右,第一個不具圖像,當輸入欄位獲得焦點時,自動顯示日期選取介面。點選工具列中的時鐘圖像則顯示時間選取介面。第二個具有圖像,當輸人欄位獲得焦點時,並不會顯示日期選取介面,必須點按「日曆」圖像才能顯示日期選取介面,工具列中具有「今日」、「清除」及「關閉」三個圖像。第三個具有「時鐘」圖像,用來點按以顯示時間的選取介面。在實務上運作時,三個介面在一個時間點只會出現一個介面,其它的會被隱藏,圖例中的示意圖有經過剪貼。
CSS
<style> html { width:100%; height:100%; } body { margin: 0 auto; max-width: 1000px; padding: 20px; } </style>
在 CSS 中沒有特別的樣式需要設定。但要在 <head> 標記中加上下列程式碼,以納入 datetimepicker 的樣式表。請自行修改路徑位置。
<link rel="stylesheet" href="libs/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css">
HTML
<body></body>
第 5 行建立一個不具圖像的日期和時間輸入欄位的掛載點,因為不具圖像,所以用不到 .form-group 及 .input-group 樣式類別。搜尋用的 id 設在 <input> 之中。
第 8~15 行及 18~26 行各建立一個具有圖像的日期和時間輸入欄位,因為具有圖像,所以用到 .form-group 及 .input-group 等樣式類別。搜尋用的 id 設在 .input-group 的 <div> 標記中,注意 .input-group 伴隨一個 .date 樣式類別,這是程式碼中唯一定義於 datetimepicker.css 中的樣式類別,.input-group.date{}樣式中設定了游標形狀。
第 22 行用 glyphicon-time 將圖像設成「時鐘」的圖像。
剩下的工作都得靠 JavaScript 程式來完成了。
Script
記得加上下列程式碼,以納入 datetimepicker 的 JavaScript 程式碼。請自行修改路徑位置。
<script src="libs/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js"></script>
<script> $(function(){ $('#datetimepicker1').datetimepicker({ daysOfWeekDisabled: [0, 6] }); $('#datetimepicker2').datetimepicker({ locale: 'zh-TW', format: 'YYYY-MM-DD', // this will only display date selector toolbarPlacement: 'bottom', showTodayButton : true, showClear: true, showClose: true }).on('dp.change', function(){ let picked = $('#datetimepicker2').datetimepicker('date'); alert(picked); }); $('#datetimepicker3').datetimepicker({ format: 'LT' // this will only display time selector }); }); </script>
第 4 行將所有週六及週日的日子,都設定為不可選取。
第 7 行設定顯示時使用正體中文。
第 8 行設定日期格式,因為只設定了日期格式,所以不會出現時間的選取介面。
第 9 行設定工具列在選取介面中的位置。
第 10~12 行則分別顯示「今日」、「清除」及「關閉」三個工具列的圖像鈕。
第 13~15 行於資料改變時,處理 dp.change 事件,讀取輸入值,並顯示在螢幕上。
第 20 行將格式設定為 LT (Local Time),因此只會出現時間選取介面。format 屬性的值,得去參考 Moment.js 的文件。