我可以在标准 Jquery UI 日期选择器中突出显示一整周吗?
12 回答
我知道这篇文章已经很老了,但我只是在另一个网站上找到了这段代码,并认为它可能会有所帮助。
源代码 - 来自这篇文章:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/base/jquery-ui.css">
<script type="text/javascript">
$(function() {
var startDate;
var endDate;
var selectCurrentWeek = function() {
window.setTimeout(function () {
$('.week-picker').find('.ui-datepicker-current-day a').addClass('ui-state-active')
}, 1);
}
$('.week-picker').datepicker( {
showOtherMonths: true,
selectOtherMonths: true,
onSelect: function(dateText, inst) {
var date = $(this).datepicker('getDate');
startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());
endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() + 6);
var dateFormat = inst.settings.dateFormat || $.datepicker._defaults.dateFormat;
$('#startDate').text($.datepicker.formatDate( dateFormat, startDate, inst.settings ));
$('#endDate').text($.datepicker.formatDate( dateFormat, endDate, inst.settings ));
selectCurrentWeek();
},
beforeShowDay: function(date) {
var cssClass = '';
if(date >= startDate && date <= endDate)
cssClass = 'ui-datepicker-current-day';
return [true, cssClass];
},
onChangeMonthYear: function(year, month, inst) {
selectCurrentWeek();
}
});
$('.week-picker .ui-datepicker-calendar tr').live('mousemove', function() { $(this).find('td a').addClass('ui-state-hover'); });
$('.week-picker .ui-datepicker-calendar tr').live('mouseleave', function() { $(this).find('td a').removeClass('ui-state-hover'); });
});
</script>
</head>
<body>
<div class="week-picker"></div>
<br /><br />
<label>Week :</label> <span id="startDate"></span> - <span id="endDate"></span>
</body>
</html
>
我为此写了一个解决方案,突出了这一周。它仍然会选择选定的日期,但这对我来说很好。#week 是附加了日期选择器的输入框。
$('#week').datepicker({
beforeShowDay: $.datepicker.noWeekends,
duration : 0,
onChangeMonthYear: function() { setTimeout("applyWeeklyHighlight()", 100); },
beforeShow: function() { setTimeout("applyWeeklyHighlight()", 100); }
}).keyup(function() { setTimeout("applyWeeklyHighlight()", 100); });
function applyWeeklyHighlight()
{
$('.ui-datepicker-calendar tr').each(function() {
if($(this).parent().get(0).tagName == 'TBODY')
{
$(this).mouseover(function() {
$(this).find('a').css({'background':'#ffffcc','border':'1px solid #dddddd'});
$(this).find('a').removeClass('ui-state-default');
$(this).css('background', '#ffffcc');
});
$(this).mouseout(function() {
$(this).css('background', '#ffffff');
$(this).find('a').css('background','');
$(this).find('a').addClass('ui-state-default');
});
}
});
}
AntFalco 的答案很棒,但是如果您需要做我所做的事情,它就不能很好地工作。我需要一种方法来选择一周并将一周的第一天填充到输入框中,单击它会生成日期选择器。这是我用来完成此操作的代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/themes/base/jquery-ui.css">
<script type="text/javascript">
$(function() {
var startDate;
var endDate;
var selectCurrentWeek = function() {
window.setTimeout(function () {
$('#ui-datepicker-div').find('.ui-datepicker-current-day a').addClass('ui-state-active')
}, 1);
}
$('.datepicker').datepicker( {
showOtherMonths: true,
selectOtherMonths: true,
onSelect: function(dateText, inst) {
var date = $(this).datepicker('getDate');
startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());
endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() + 6);
var dateFormat = inst.settings.dateFormat || $.datepicker._defaults.dateFormat;
$(this).attr("value",$.datepicker.formatDate( dateFormat, startDate, inst.settings ));
selectCurrentWeek();
},
beforeShowDay: function(date) {
var cssClass = '';
if(date >= startDate && date <= endDate)
cssClass = 'ui-datepicker-current-day';
return [true, cssClass];
},
onChangeMonthYear: function(year, month, inst) {
selectCurrentWeek();
}
});
$('#ui-datepicker-div .ui-datepicker-calendar tr').live('mousemove', function() { $(this).find('td a').addClass('ui-state-hover'); });
$('#ui-datepicker-div .ui-datepicker-calendar tr').live('mouseleave', function() { $(this).find('td a').removeClass('ui-state-hover'); });
});
</script>
</head>
<body>
<input type="text" id="from_date" name="from_date" class="datepicker" />
<input type="text" id="to_date" name="to_date" class="datepicker" />
</body>
</html>
这也具有处理多个输入值的副作用。如果您需要某种“星期”选择器,那么这段代码是迄今为止最有用的。代码很少,因此对测试进行小的修改非常容易。此外,它适用于 minDate/maxDate 函数。
这是一篇文章,其中有一个示例,说明如何使用日期选择器选择一整周。
$(function()
{
$('.date-pick').datePicker({selectWeek:true,closeOnSelect:false});
});
我想做同样的事情,但也希望输入字段显示选定的星期范围——这就是我最终做的事情(基本上使用 altField 来存储选定的日期,但在输入字段中显示格式化的星期范围使用 datepicker beforeShow 回调替换为实际日期。Coffeescript 如下;要点可以在这里找到:https ://gist.github.com/2048010
weekchooser = ->
$('#datepicker').datepicker({
dateFormat: "M d, yy",
altFormat: "M d, yy",
altField: "#actualdate",
selectWeek: true,
firstDay: 1,
showOtherMonths: true,
selectOtherMonths: true,
beforeShow: ->
$('#datepicker').val($('#actualdate').val())
onClose: (date) ->
reformatWeek(date)
this.blur()
}).click ->
currentDay = $('.ui-datepicker-current-day')
currentDay.siblings().find('a').addClass('ui-state-active')
calendarTR = $('.ui-datepicker .ui-datepicker-calendar tr');
calendarTR.live 'mousemove', (event) ->
$(this).find('td a').addClass('ui-state-hover');
calendarTR.live 'mouseleave', (event) ->
$(this).find('td a').removeClass('ui-state-hover');
reformatWeek = (dateText) ->
$('#datepicker').datepicker('refresh')
current = parseInt($('.ui-datepicker-current-day').find('a').html())
weekstart = parseInt($('.ui-datepicker-current-day').siblings().find('a').first().html())
weekend = parseInt($('.ui-datepicker-current-day').siblings().find('a').last().html())
pattern = ///
^([a-zA-Z]+)\s+([0-9]{1,2})(,.*)
///
[month, day, year] = dateText.match(pattern)[1..3]
date = if weekstart > current
first_month = relativeMonth(month, -1)
"#{first_month} #{weekstart} - #{month} #{weekend}#{year}"
else if weekend < current
last_month = relativeMonth(month, 1)
"#{month} #{weekstart} - #{last_month} #{weekend}#{year}"
else
"#{month} #{weekstart} - #{weekend}#{year}"
$('#datepicker').val( date )
relativeMonth = (month, c) ->
monthArray = $('#datepicker').datepicker('option', "monthNamesShort")
index = monthArray.indexOf(month)
if c > 0
return if index + c > monthArray.length - 1 then monthArray[0] else monthArray[index + c]
else
return if index + c < 0 then monthArray[monthArray.length - 1] else monthArray[index + c]
我创建了一个基于最佳答案的 jQuery 插件。从https://github.com/Prezent/jquery-weekpicker或通过 Bower 获取。示例用法:
$('#selector').weekpicker({
startField: '#date-start',
endField: '#date-end'
});
该脚本突出显示从所选日期开始的一周。
在此处查看一个工作示例:http: //jsfiddle.net/frictionless/W5GMg/
逻辑:
beforeShowDay:为显示的日历中的每个日期运行。在显示日历和选择特定日期时调用它。
onSelect:函数从 selectedDay 开始捕获选定的星期, beforeShowDay 呈现选定的星期
这是一个适用于 Jquery 1.5.1 和 JQuery UI 1.8.1 的片段
$(function () {
var _dates=new Array();
$('#datepicker').datepicker({
beforeShowDay:function(_date){
if($.inArray(_date.getTime(),_dates)>=0)
return [true,"highlighted-week","Week Range"];
return[true,"",""];
},
onSelect:function(_selectedDate){
var _date=new Date(_selectedDate);
_dates=new Array();
for(i=0;i<7;i++){
var tempDate=new Date(_date.getTime());
tempDate.setDate(tempDate.getDate()+i);
_dates.push(tempDate.getTime());
}
}
});
});
您也许可以按照此讨论中的建议来实现您的星期选择功能:http ://code.google.com/p/jquery-datepicker/issues/detail?id=13
不过不幸的是,jQuery datepicker 似乎无法处理整整一周的选择。它需要自定义编码。
编辑: Frictionless 的答案很好,除了问题是如何选择整个星期(不是点击后的 6 天)。建议我在这里复制我的补丁。
这是我在我的网站上使用的简化版本。请注意,星期选择器与 <span> 标记挂钩,以显示一周的第一天和最后一天。这需要一个引用 /images/schedule.png 的触发按钮。
根据需要更改:
<style type="text/css">
.highlighted-week a.ui-state-default{
background: #FFFFFF;
border: 1px solid #AAAAAA;
color: #212121;
font-weight: normal
}
</style>
<!-- include jquery and jquery-ui here -->
<script type="text/javascript">
// This $(function()) block could be moved to another file. It's what I did.
$(function() {
var internal = 0;
if (typeof SVG == 'undefined') SVG = {};
if (typeof SVG.Weekpicker == 'undefined') SVG.Weekpicker = {};
SVG.Weekpicker.GetWeek = function(_selectedDate) {
var week = new Array();
/* ***NOTE*** This is the only line required to "fix" Frictionless' code. */
_selectedDate.setDate(_selectedDate.getDate()-_selectedDate.getDay());
for (i = 0; i < 7; i++) {
var tempDate = new Date(_selectedDate.getTime());
tempDate.setDate(tempDate.getDate() + i);
week.push(tempDate.getTime());
}
return week;
};
SVG.Weekpicker.Init = function(selector) {
var elem = $(selector);
var insert = $('<input type="hidden" name="weekpicker'+(++internal)+'" value="'+elem.html()+'" />');
SVG.Weekpicker._dates = SVG.Weekpicker.GetWeek(new Date());
insert = insert.insertAfter(elem);
insert.datepicker({
beforeShowDay: function(_date) {
if ($.inArray(_date.getTime(), SVG.Weekpicker._dates) >= 0)
return [true, "highlighted-week", "Week Range"];
return [true, "", ""];
},
onSelect: function(_selectedDate) {
var _date = new Date(_selectedDate);
SVG.Weekpicker._dates = SVG.Weekpicker.GetWeek(_date);
var start = new Date(SVG.Weekpicker._dates[0]);
var end = new Date(SVG.Weekpicker._dates[6]);
$(elem).html(($.datepicker.formatDate('MM d, yy', start, '')+' — '+$.datepicker.formatDate('MM d, yy', end, ''))+' ');
},
showOn: "button",
buttonImage: "/images/schedule.png",
buttonImageOnly: false,
showAnim: "slideDown",
});
};
});
$(document).ready(function() {
// Attach a week picker to the weekpicker <span> tag.
SVG.Weekpicker.Init("#weekpicker");
}
</script>
<body>
<span id="weekpicker"></span>
</body>
This is incredibly late, but I was searching for the same solution and could only find reference to these types of answers (i.e. for a different date picker). In my case, I'm using it inline, so that's how this code works. If you want it to pop-up with a week highlighted, you would have to modify. Here is something that works:
var selectedWeek;//remember which week the user selected here
$("#inlineDIVdatepicker").datepicker({
firstDay:1,
showOtherMonths:true,
onSelect: function(dateText){
selectedWeek = $.datepicker.iso8601Week(new Date(dateText));
} ,
//set the class 'week-highlight' for the whole week
beforeShowDay: function(d){
if (!selectedWeek) { return [true,''];}
if (selectedWeek == $.datepicker.iso8601Week(d)){
return [true,'week-highlight'];
}
return [true,''];
}
});
Then define some CSS (I haven't really done this part myself, so this is ugly):
#inlineDIVdatepicker .week-highlight a {
background:none;
background-color:yellow;
}
您可以在下面的链接中查看已回答的问题
如何使用 jQuery UI 日历/日期选择器一周而不是一天?
$(function() {
var startDate;
var endDate;
var selectCurrentWeek = function() {
window.setTimeout(function () {
$('.week-picker').find('.ui-datepicker-current-day a').addClass('ui-state-active')
}, 1);
}
$('.week-picker').datepicker( {
showOtherMonths: true,
selectOtherMonths: true,
onSelect: function(dateText, inst) {
var date = $(this).datepicker('getDate');
startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());
endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() + 6);
var dateFormat = inst.settings.dateFormat || $.datepicker._defaults.dateFormat;
$('#startDate').text($.datepicker.formatDate( dateFormat, startDate, inst.settings ));
$('#endDate').text($.datepicker.formatDate( dateFormat, endDate, inst.settings ));
selectCurrentWeek();
},
beforeShowDay: function(date) {
var cssClass = '';
if(date >= startDate && date <= endDate)
cssClass = 'ui-datepicker-current-day';
return [true, cssClass];
},
onChangeMonthYear: function(year, month, inst) {
selectCurrentWeek();
}
});
$('.week-picker .ui-datepicker-calendar tr').live('mousemove', function() { $(this).find('td a').addClass('ui-state-hover'); });
$('.week-picker .ui-datepicker-calendar tr').live('mouseleave', function() { $(this).find('td a').removeClass('ui-state-hover'); });
});
不适用于多个选择器/最后一个 jquery.ui。试试这个小重写:
jQuery(function() {
var startDate; // closure
var endDate;
var baseAttachHandler = jQuery.datepicker._attachHandlers;
jQuery.datepicker._attachHandlers = function(inst) {
baseAttachHandler.apply(this, [inst]);
var element_data = jQuery._data(inst.dpDiv.get(0));
var ori_handler_mouseover = element_data.events.mouseover[0].handler;
var ori_handler_mouseout = element_data.events.mouseout[0].handler;
// remove handlers
inst.dpDiv.undelegate("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a", 'mouseover');
inst.dpDiv.undelegate("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a", 'mouseout');
inst.dpDiv.undelegate("button, .ui-datepicker-prev, .ui-datepicker-next", 'mouseover');
inst.dpDiv.undelegate("button, .ui-datepicker-prev, .ui-datepicker-next", 'mouseout');
inst.dpDiv.find(".ui-datepicker-calendar tr").unbind('mouseover');
inst.dpDiv.find(".ui-datepicker-calendar tr").unbind('mouseout');
// attach proper ones
if (this._get(inst, "weekSelector")) {
inst.dpDiv.delegate("button, .ui-datepicker-prev, .ui-datepicker-next", 'mouseover', ori_handler_mouseover);
inst.dpDiv.delegate("button, .ui-datepicker-prev, .ui-datepicker-next", 'mouseout', ori_handler_mouseout);
inst.dpDiv.find(".ui-datepicker-calendar tr").bind('mouseover', function() {
jQuery(this).find('td a').addClass('ui-state-hover');
});
inst.dpDiv.find(".ui-datepicker-calendar tr").bind('mouseout', function() {
jQuery(this).find('td a').removeClass('ui-state-hover');
});
} else {
inst.dpDiv.delegate("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a", 'mouseover', ori_handler_mouseover);
inst.dpDiv.delegate("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a", 'mouseout', ori_handler_mouseout);
}
};
jQuery.datepicker.calcWeekBoundaries = function () {
var date = jQuery(this).datepicker('getDate');
if (date) {
var tmp = date.getDay();
if (tmp == 0) { // starting with monday, i'm italian ;-)
endDate = date;
startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - 6);
} else {
startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - tmp + 1);
endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - tmp + 7);
}
}
};
jQuery("#yourcontrol").datepicker(
jQuery.extend({}, jQuery.datepicker.regional["yourlanguage"], {
showOtherMonths: true
, selectOtherMonths: true
, changeMonth: true
, changeYear: true
, onSelect: function(dateText, inst) {
if (jQuery.datepicker._get(inst, "weekSelector")) {
jQuery.datepicker.calcWeekBoundaries.apply(this, []);
jQuery(this).datepicker('setDate', startDate);
}
inst.input.trigger("change");
}
, beforeShowDay: function(date) {
var inst = jQuery.data(this, "datepicker");
var cssClass = '';
if (jQuery.datepicker._get(inst, "weekSelector") && date) {
if(date >= startDate && date <= endDate) {
cssClass = 'ui-state-active';
}
}
return [true, cssClass];
}
, beforeShow: function(input, inst) {
jQuery.datepicker.calcWeekBoundaries.apply(this, []);
}
, weekSelector: true // the magic is here
})
);
});