Jquery UI的日历控件datepicker限制日期

长孙翔
2023-12-01

JQuery.ui.Datepicker是一个很强大的日期选择控件,定制性很强。朱最近在做一个旅馆预订的小功能,要求用户在填写订单选择入住日期时,要将已经被预订出的日期置为不可用,查些资料,看看JS,原来可以使用beforeshowday来控制每一天的格式。主要代码如下:

 
  1. var orderDays = [[4,30,2010],[5,1,2010],[5,14,2010]];  
  2. function setOrdereDays(date) {  
  3.     var isOrdered = false;  
  4.     var scheduleStatus = "";  
  5.     for (i = 0; i < orderDays.length; i++) {  
  6.       if (date.getMonth() == orderDays[i][0] - 1 && 
          date.getDate() == orderDays[i][1] && date.getFullYear() == orderDays[i][2])  
  7.       {  
  8.         isOrdered = true;break;  
  9.       }  
  10.     }  
  11.     if(isOrdered){  
  12.         return [false'CLOSED'];  
  13.     }else{  
  14.         return [true''];  
  15.     }  
  16. }  

“CLOSED”貌似是Datepicker内置的一个什么值,设置为"CLOSED"则当天的日期是不可选的。

ui.Datepicker.js里关于beforeShowDay的一些注释:

beforeShowDay: null, // Function that takes a date and returns an array with
// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
// [2] = cell title (optional), e.g. $.datepicker.noWeekends


A function that takes a date as a parameter and must return an array with:

  • [0]true/false indicating whether or not this date is selectable
  • [1]: a CSS class name to add to the date's cell or "" for the default presentation
  • [2]: an optional popup tooltip for this date
第三个参数可以在该日期上显示title,提示节假日名称。(比如国庆)

return [false, 'customCss','国庆'];  
[plain]  view plain copy print ?
  1. 现在jquery用的很广泛,一方面是其强大的库,另一方面是它的插件很丰富。最近用了jquery的datepicker插件,感觉很棒,界面很漂亮,功能齐全,且扩展性很好。强烈推荐使用。  
  2.   
  3. 项目中有一个需求,要禁用某些日期,比如周末,节假日。看了datepicker的源码,发现里面有一个noWeekends方法可非常简单地实现禁用周末,请看代码:  
  4.   
  5. $("#datepicker").datepicker({  
  6. beforeShowDay: $.datepicker.noWeekends  
  7. });  
  8.   
  9. 如果要禁用某些特定的日期,可定义一个函数实现,如下:  
  10.   
  11. natDays = [  
  12. [7, 23,2009], [7, 24,2009], [8, 13,2009], [8, 14,2009],  
  13. ];  
  14.   
  15. function nationalDays(date) {  
  16. for (i = 0; i < natDays.length; i++) {  
  17. if (date.getFullYear() == natDays[i][2] && date.getMonth() == natDays[i][0] - 1  
  18. && date.getDate() == natDays[i][1]) {  
  19. return [false, natDays[i][2] + '_day'];  
  20. }  
  21. }  
  22. return [true, ''];  
  23. }  
  24.   
  25. $("#datepicker").datepicker({  
  26. beforeShowDay: nationalDays  
  27. });  
  28.   
  29. 上面函数的返回值是以个数组,第一个布尔值表示是否禁用该日期,true为不禁用,false为禁用。第二个参数是以个样式名,可自定义被禁用时的样式。  
  30.   
  31. 如果只要求某个时间段的日期可以选择,通过设置两个参数可以实现:  
  32.   
  33. $("#datepicker").datepicker({  
  34. minDate: new Date(2009, 6, 6),  
  35. maxDate: new Date(2009, 7, 14),  
  36. });  
  37.   
  38. 以上设置表示在2009年5月6号到2009年6月14号是可选的。  

现在考虑我自己的应用,我现在要做淡旺季的价格表,如果选择旺季,日期就不能选择非旺季的日期,淡季和平季也是如此。

这样乍看起来需要界定一个日期范围,但是研究楼上的源代码后看到,只需要限定月份就行了。因为每个淡旺季的开头和结尾都是以自然月的1号和30号(31,28号)为结束的,所以数组那里只需要一个值,而不需要三个值来判断。对于一般的应用,最多也是需要两个,也就是日期和月份,年份几乎每年都一样。

另外一个变通点,起始日期的选择。如果旺季开始于7月,当前日期是5月,那么日历的起始日期应该是7月1日。如果当前日期正好处于旺季,那么就从当天开始作为日期的起始点。

第三,我必须要从一个隐藏元素中获取当前的季节特征,淡季,平季还是旺季,不同的季节有不同的价格。那么因为各个浏览器对于浏览器加载元素的时机不同,所以决定放在jquery的$(function(){});里面。


于是就有了如下的js

[javascript]  view plain copy print ?
  1. var d=new Date();  
  2. var y=d.getFullYear();  
  3. var m=d.getMonth()+1;  
  4. var day=d.getDate();  
  5.   
  6.   
  7. function nationalDays(date) {  
  8.     for (i = 0; i < natDays.length; i++) {  
  9.         if (date.getMonth() == natDays[i][0] - 1) {  
  10.             return [false, natDays[i][0] + '_day'];  
  11.         }  
  12.     }  
  13.     return [true''];  
  14. }  
  15.   
  16. $(function(){  
  17.     var season=document.getElementById('season').value;  
  18.     if(season=='busy'){  
  19.         document.getElementById('seasonTips').innerHTML='旺季的月份选择只能是4月5月9月10月11月'  
  20.         if(m>1 && m<4){  
  21.             mindate=y+'-4-1';  
  22.         }else if(m>5&&m<9){  
  23.             mindate=y+'-9-1';  
  24.         }else if(m>11){  
  25.             mindate=y+1+'-4-1';  
  26.         }else{  
  27.             mindate=y+'-'+m+'-'+day;  
  28.         }  
  29.         //旺季4,5,9,10,11  
  30.         natDays=[[1],[2],[3],[6], [7], [8],[12],];  
  31.     }else if(season=='common'){  
  32.         document.getElementById('seasonTips').innerHTML='平季的月份选择只能是3月6月7月8月';  
  33.         if(m<3){  
  34.             mindate=y+'-3-1';  
  35.         }else if(m>3 && m<6){  
  36.             mindate=y+'-6-1';  
  37.         }else if(m>8){  
  38.             mindate=y+1+'-3-1'  
  39.         }else{  
  40.             mindate=y+'-'+m+'-'+day;  
  41.         }  
  42.         //平3678  
  43.         natDays=[[1],[2],[4],[5],[9],[10],[11],[12],];  
  44.     }else if(season=='dull'){  
  45.         document.getElementById('seasonTips').innerHTML='淡季的月份选择只能是1月2月和12月';  
  46.         if(m>2 && m<12){  
  47.             mindate=y+'-12-1';  
  48.         }else{  
  49.             mindate=y+'-'+m+'-'+day;  
  50.         }  
  51.         //淡季12.1.2,禁用345678910  
  52.         natDays=[[3],[4],[5],[6],[7],[8],[9],[10],[11],];  
  53.     }  
  54.     // Datepicker  
  55.         $('.Wdate').datepicker({  
  56.             numberOfMonths:2,  
  57.             showButtonPanel:false,  
  58.             dateFormat: 'yy-mm-dd',  
  59.             minDate: mindate,  
  60.             beforeShowDay: nationalDays,  
  61.         });  
  62. });  

Example:

/* create an array of days which need to be disabled */
var disabledDays = ["2-21-2010","2-24-2010","2-27-2010","2-28-2010","3-3-2010","3-17-2010","4-2-2010","4-3-2010","4-4-2010","4-5-2010"];

/* utility functions */
function nationalDays(date) {
	var m = date.getMonth(), d = date.getDate(), y = date.getFullYear();
	//console.log('Checking (raw): ' + m + '-' + d + '-' + y);
	for (i = 0; i < disabledDays.length; i++) {
		if(ArrayContains(disabledDays,(m+1) + '-' + d + '-' + y) || new Date() > date) {
			//console.log('bad:  ' + (m+1) + '-' + d + '-' + y + ' / ' + disabledDays[i]);
			return [false];
		}
	}
	//console.log('good:  ' + (m+1) + '-' + d + '-' + y);
	return [true];
}
function noWeekendsOrHolidays(date) {
	var noWeekend = jQuery.datepicker.noWeekends(date);
	return noWeekend[0] ? nationalDays(date) : noWeekend;
}

/* taken from mootools */
function ArrayIndexOf(array,item,from){
	var len = array.length;
	for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){
		if (array[i] === item) return i;
	}
	return -1;
}
/* taken from mootools */
function ArrayContains(array,item,from){
	return ArrayIndexOf(array,item,from) != -1;
}

/* create datepicker */
jQuery(document).ready(function() {
	jQuery('#date').datepicker({
		minDate: new Date(2010, 0, 1),
		maxDate: new Date(2010, 5, 31),
		dateFormat: 'DD, MM, d, yy',
		constrainInput: true,
		beforeShowDay: noWeekendsOrHolidays
	});
});


 类似资料: