本节书摘来自异步社区《jQuery、jQuery UI及jQuery Mobile技巧与示例》一书中的第7章,第7.5节,作者:【荷】Adriaan de Jonge , 【美】Phil Dutson著,更多章节内容可以访问云栖社区“异步社区”公众号查看
7.5 技巧:使用日历微件选择日期
在HTML5之前,在Web页面中选择日期是很痛苦的。甚至支持了HTML5的浏览器中仍有一些不能提供一个好用的日历。
代码清单7-5展示了jQuery UI提供的datepicker,它可以用于传统的输入框。
代码清单7-5 帮助网站用户输入日期
00 <!DOCTYPE html>
01
02 <html lang="en">
03 <head>
04 <title>jQuery UI Datepicker</title>
05 <link type="text/css" rel="stylesheet" href=
06 "http://code.jquery.com/ui/1.8.16/themes/base/jquery-ui.css">
07 </head>
08 <body>
09
10 <input type="text" id="my-date">
11
12 <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
13 <script src="http://code.jquery.com/ui/1.8.16/jquery-ui.min.js">
14 </script>
15
16 <script>
17 // 请将下列代码移至一个外部的.js文件中
18 $(document).ready(function() {
19
20 $('#my-date').datepicker();
21
22 });
23 </script>
24 </body>
25 </html>
第10行和第20行就是初始化一个简单的日历所需要做的。但这仅仅是冰山一角。在表面之下,还有许多选项用来调整偏好和适应不同的国家。
7.5.1 为日历元素添加样式
虽然datepicker生成的HTML、CSS和JavaScript不是它的精彩之处。但是,如果想应用自定义的样式,它们就是需要了解的样式类和HTML元素。
<div class="ui-datepicker ui-widget ui-widget-content
ui-helper-clearfix ui-corner-all" id="ui-datepicker-div"
style="position: absolute; top: 0px; left: 8px; z-index: 1;
display: block;">
<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix
ui-corner-all">
<a title="Prev"
onclick="DP_jQuery_1322422893896.datepicker
.adjustDate('#my-date', -1, 'M');"
class="ui-datepicker-prev ui-corner-all">
<span class="ui-icon ui-icon-circle-triangle-w">Prev</span>
</a>
<a title="Next"
onclick="DP_jQuery_1322422893896.datepicker
.adjustDate('#my-date', +1, 'M');"
class="ui-datepicker-next ui-corner-all">
<span class="ui-icon ui-icon-circle-triangle-e">Next</span>
</a>
<div class="ui-datepicker-title">
<span class="ui-datepicker-month">November</span>
<span class="ui-datepicker-year">2011</span>
</div>
</div>
<table class="ui-datepicker-calendar">
<thead>
<tr>
<th class="ui-datepicker-week-end">
<span title="Sunday">Su</span>
</th>
<th>
<span title="Monday">Mo</span>
</th>
<th>
<span title="Tuesday">Tu</span>
</th>
<th>
<span title="Wednesday">We</span>
</th>
<th>
<span title="Thursday">Th</span>
</th>
<th>
<span title="Friday">Fr</span>
</th>
<th class="ui-datepicker-week-end">
<span title="Saturday">Sa</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="ui-datepicker-week-end ui-datepicker-other-month
ui-datepicker-unselectable ui-state-disabled">
</td>
<td class="ui-datepicker-other-month ui-datepicker-unselectable
ui-state-disabled">
</td>
<td onclick="DP_jQuery_1322422893896.datepicker
.selectDay('#my-date',10,2011, this);return false;"
class="">
<a href="#" class="ui-state-default">1</a>
</td>
<td onclick="DP_jQuery_1322422893896.datepicker
.selectDay('#my-date',10,2011, this);return false;"
class="">
<a href="#" class="ui-state-default">2</a>
</td>
<td onclick="DP_jQuery_1322422893896.datepicker
.selectDay('#my-date',10,2011, this);return false;"
class="">
<a href="#" class="ui-state-default">
. . . 等等,直到此月最后一天 . . .
</a>
</td>
<tr>
. . . 等等,直到此月最后一周 . . .
</tr>
</tbody>
</table>
当前日期可以用类ui-state-highlight识别。
7.5.2 设置日历的选项
通过下面的代码片断你可以看到,disabled选项的作用就像它在其他对象和微件中的作用一样。它可以在初始化时禁用组件,之后再启用它。默认情况下,此选项的值是false。
$('#my-date').datepicker({disabled: true});
当选择一个日期后,altField选项会搜索另一个输入框来更新。altFormat选项可以更改返回日期的格式。与你所期望的正好相反,使用yy返回四位数字格式的年。如果你键入yyyy,该函数会返回23-06-20122012而不是23-06-2012。
$('#my-date').datepicker({
altField: '#dutch-notation',
altFormat: 'dd-mm-yy'
});
这段文本会被添加到输入框的后面,用来提示用户应该输入到文本框的日期格式,如下所示:
$('#my-date').datepicker({appendText: '(mm/dd/yyyy)'});
调整输入框的大小以适合当前的日期。默认值是false:
$('#my-date').datepicker({autoSize: true});
根据对其他jQuery UI组件的了解,你可能期望提供一个类名作为按钮图片的值,如ui-icon-calendar。不同的是,你需要提供一个指向图像的硬编码(hard code)路径,如下所示:
$('#my-date').datepicker({buttonImage: '/images/my-image.png'});
删除按钮的文本。默认值是 false:
$('#my-date').datepicker({buttonImageOnly: true});
buttonText选项可以更改按钮上的文字。你可以使用showOn选项改变显示日历的时机。默认值是focus,当输入框获得焦点时显示;使用button值会使日历等待,直到按钮被点击时显示;使用both值则要求两个事件之一被触发时显示。
当日历使用点击按钮触发显示时,将按钮文字设置为choose:
$('#my-date').datepicker({buttonText: 'choose', showOn: 'button'});
更改计算周数的算法实现。默认遵从ISO 8601标准。这意味着,每年的第一周要依赖于该年的第一个星期四的出现1:
$('#my-date').datepicker({calculateWeek: function(date) {
// 从日期计算周数
return calculatedWeekNr;
}});
为选择月份和年份提供下拉列表,而不仅仅依靠月份两边的选择箭头。这些选项的默认值是false:
$('#my-date').datepicker({changeMonth: true, changeYear: true});
这些选项用于更改日历上按钮的文字。closeText选项更改关闭按钮上的文字,默认值是Done。currentText选项更改用于当天的文字,默认值是Today。prevText选项更改上一月链接的文字,默认是Prev。nextText选项更改下一月链接的文字,默认值是Next。showButtonPanel选项用于切换是否显示按钮面板,默认值是false。
更改日历上的关闭按钮文字为Close,当天的文字改为Current,上一月链接的文字改为Earlier,下一月链接的文字改为Later,并启用按钮面板:
$('#my-date').datepicker({closeText: 'Close',
currentText: 'Current', prevText: 'Earlier',
nextText: 'Later', showButtonPanel: true});
将constrainInput设置为false,允许输入的内容与当前的日期格式不匹配。默认值是true:
$('#my-date').datepicker({constrainInput: false});
你可能生活在西北欧的一个小国,而且还不能确定英语是否将成为21世纪的通用语言。当然,也很有可能,汉语将最终变得比英语更重要。但是,汉语是一门不好学的语言,它仍然需要扩大在世界上的影响力。
要在英语与汉语的辩论中处于安全位置,最好保持中立并且使用一种不起眼的和过时的被称为荷兰语的语言来写你的文本和日期。荷兰语所做的一切都有些不同。例如,其日期写为dd-mm-yy而不是mm/dd/yy。不过有个好消息告诉你:使用jQuery UI日历,可以用任何喜欢的格式输入日期。下面的示例实现了一个荷兰语版本的日历:
$('#my-date').datepicker({
dateFormat: 'dd-mm-yy', dayNames: ['Maandag', 'Dinsdag', 'Woensdag',
'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag'],
dayNamesMin: ['Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za', 'Zo'],
dayNamesShort: ['Maa', 'Din', 'Woe', 'Don', 'Vri', 'Zat', 'Zon'],
monthNames: ['Januari', 'Februari', 'Maart', 'April', 'Mei',
'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November',
'December'],
monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', 'Jul',
'Aug', 'Sep', 'Okt', 'Nov', 'Dec']});
duration选项设置日历出现的速度。它也可以被设置为一个以毫秒为单位的数字:
$('#my-date').datepicker({duration: 'slow'});
配置每周开始于星期三,而不是星期日。firstDay的默认值是0,也就是星期日。一周其余的日子继续向后计算,1表示星期一,2表示星期二,依此类推:
$('#my-date').datepicker({firstDay: 3});
如果设置了minDate和/或maxDate,可以隐藏上一月和下一月按钮而不是禁用它们。默认值是false:
$('#my-date').datepicker({hideIfNoPrevNext: true});
如果要为像阿拉伯语一样的语言生成日历,需要设置日历的渲染方式,以此实现从右至左读。(注:RTL表示从右至左。)默认值是false:
$('#my-date').datepicker({isRTL: true});
下面的代码段约束日期处于最小日期和最大日期范围内。在本例中,字符w代表周。你也可以使用d、m和y,分别代表日、月和年,或者可以提供符合当前日期格式的日期字符串:
$('#my-date').datepicker({ maxDate: '+5w', minDate: '-4w'});
在下面示例中,numberOfMonths选项被设置为同时显示3个月。默认值是1。在这个例子中,showCurrentAtPos选项用于设置在第二个位置显示当前月。默认值是0,从上边或左边显示的月开始计数。
$('#my-date').datepicker({numberOfMonths: 3,
showCurrentAtPos: 1});
显示和选择上一月的开始几天和下一月的最后几天。这些选项在一起使用,是因为selectOtherMonths的选项只有当showOtherMonths选项设置为true时才起作用。这两个选项的默认值都是false:
$('#my-date').datepicker({selectOtherMonths: true,
showOtherMonths: true});
决定一个两位数的年份在哪个值被认为是在当前世纪,超过该值则被假定为上个世纪2。默认值是+10:
$('#my-date').datepicker({shortYearCutoff: '+20'});
使用showAnim选项启用日历的动画。动画的方式可以是blind、bounce、clip、drop、explode、fade、fold、highlight、puff、
pulsate、scale、shake、size、slide和transfer。默认值是show:
$('#my-date').datepicker({showAnim: 'blind'});
更改日历标题的年份和月份的顺序。此选项也是一个用于本地化的选项。默认值是false:
$('#my-date').datepicker({showMonthAfterYear: true});
为showAnim选项提供额外的参数。该选项的默认值为showAnim选项指定的动画所用的默认值:
$('#my-date').datepicker({showAnim: 'slide', showOptions: {direction: 'down' }});
显示周数。默认值是false:
$('#my-date').datepicker({showWeek: true});
当同时显示多月时,使用stepMonths能快速滚动月份。默认值是1:
$('#my-date').datepicker({stepMonths: 2});
更改代表周的标题文字(这对国际化是非常有用的):
$('#my-date').datepicker({weekHeader: 'w'});
约束选取年份的范围。下面的例子对于选择成人的出生日期是非常有用的3。该选项需要配合选取年的下拉菜单工作:
$('#my-date').datepicker({yearRange: 'c-120:c-18', changeYear: true});
在年份后添加额外的文字:
$('#my-date').datepicker({yearSuffix: ' A.D.'});
7.5.3 捕获日历的事件
当使用日历时,有很多地方可以发生事件处理。下面的代码段提供了几个实例。
当新的日历被初始化时进行事件处理:
$('#my-date').datepicker({create: function(event, ui) {
// 事件处理
}});
//或
$('#my-date')
.on('datepickercreate', function(event, ui) {
// 事件处理
})
.datepicker();
在日历显示之前提供一个事件。输入框元素和日历的实例作为事件处理函数的参数。这使得可以根据当前用户的输入做出设置:
$('#my-date').datepicker({beforeShow: function(input, inst) {
return {yearSuffix: ' A.D.'};
}});
使用beforeShowDay为日历提供自定义的细节。此功能是非常有用的,例如,如果你提供一种服务,客户的价格取决于具体的日期。以酒店预订或类似的应用为例:
$('#my-date').datepicker({beforeShowDay: function() {
return [
true, // 日期可选
'my-class', // 添加mg-class用于样式
'Probably NOT X-Mas' // 鼠标悬停时的日期描述
];
}});
当年或月改变时执行自定义的操作。你可以更新整个浏览器画面,以反映当前选定的月。你可以随季节改变你的屏幕主题抑或其他你喜欢做的:
$('#my-date').datepicker({
onChangeMonthYear: function(year, month, inst) {
alert(year + '-' + month);
}});
定义自己的函数,用于日历关闭事件,无论是否有日期被选中,都会触发。如果没有日期被选定,dateText是空的。要访问input元素,可以使用this:
$('#my-date').datepicker({
onClose: function(dateText, inst) {
alert(dateText);
}});
与onClose事件相似,只是onSelect事件始终返回一个日期:
$('#my-date').datepicker({
onSelect: function(dateText, inst) {
alert(dateText);
}});
7.5.4 调用日历的方法
日历微件的一些方法与本章开头讲的折叠菜单微件以及第6章讲的可拖曳交互组件的方法相似。这些方法是destroy、disable、enable、option和widget。
在屏幕中央以对话框形式打开日历。你可以添加一个onSelect函数、一个用于设置附加选项的对象和一组用于对话框在屏幕上定位的坐标值[x, y]:
$('#my-date').datepicker('dialog', '02/05/2013');
返回当前的日历是否被禁用:
('#my-date').datepicker('isDisabled');
隐藏日历:
$('#my-date').datepicker('hide');
如果日历是隐藏的,则显示日历:
$('#my-date').datepicker('show');
在屏幕变化之后刷新日历:
$('#my-date').datepicker('refresh');
返回当前选定的日期(或者如果还没有日期被选定则返回null):
$('#my-date').datepicker('getDate');
改变选定的日期。你也可以使用这样的值,如'+1m +2y'会向前推进2年1个月。
$('#my-date').datepicker('setDate', '02/02/2013');