我遇到beforeShowDay
的问题。
当我加载页面时,直到我点击日历中的某一天,才会突出显示我要突出显示的日期。此外,如果我单击下个月按钮并返回原始月份,则“选定”日期会按预期突出显示。
因此,只有在日历的初始绘制时,日期才会突出显示,因为我已经编程了它们。日历中的任何点击都会自行修复。
我错过了初始选项吗?请参阅下面的代码示例。我的测试网址在受保护的目录中,用户/测试/测试通过。看看右栏底部的迷你卡。切换到下个月,然后回来查看我的问题。请注意5月份突出显示的日期。另请注意,在发生点击之前,“年份”下拉列表也会丢失。
http://www.urbanbands.com/dev/cgi-bin/links/eventmgr.cgi?do=list
代码:
<script>
$(document).ready(function(){
// get the current date
var today = new Date();
var m = today.getMonth(), d = today.getDate(), y = today.getFullYear();
// Need list of event dates for THIS month only from database.
// Declare 'dates' var before adding "beforeShowDay" option to the datepicker,
// otherwise, highlightDays() does not have the 'dates' array.
dates = [];
fetchEventDays(y, m+1);
$('#datepicker').datepicker({
dateFormat: 'yy-mm-dd',
changeMonth: true,
changeYear: true,
setDate: today,
inline: false
});
$('#datepicker').datepicker('option', 'onChangeMonthYear', fetchEventDays);
$('#datepicker').datepicker('option', 'beforeShowDay', highlightDays);
$('#datepicker').datepicker('option', 'onSelect', getday);
// ------------------------------------------------------------------
// getday
// ------------------------------------------------------------------
function getday(dateText, inst) {
$('#content').load('http://www.mydomain/eventmgr.cgi?do=view_day;date='+dateText+' #eventMgr_content', function() {
alert('Load was performed. '+dateText);
});
}
// ------------------------------------------------------------------
// fetchEventDays
// ------------------------------------------------------------------
function fetchEventDays(year, month) {
var paramStr ='?do=get_event_dates&yr=' + year + '&mo=' + month;
$.get('<%config.db_cgi_url%>/eventmgr-ajax.cgi'+ paramStr, function(data) {
var recur_dates = data.split(',');
for(var i = 0; i < recur_dates.length; i++) {
var date_parts = recur_dates[i].split('-');
dates.push(new Date(date_parts[0], date_parts[1]-1, date_parts[2]));
}
// This causes dates with events to highlight on initial draw, but
// when clicking to the next month, it switches back to orig month.
// $('#datepicker').datepicker('option', {}); // Refresh
});
}
// ------------------------------------------------------------------
// highlightDays
// ------------------------------------------------------------------
function highlightDays(date) {
for (var i = 0; i < dates.length; i++) {
if ((dates[i].getTime() == date.getTime())) {
return [true, 'highlight'];
}
}
return [true, ''];
}
});
</script>
答案 0 :(得分:4)
谢谢@kingjiv你是100%正确的。日历在get请求完成之前显示。我尝试使用when
方法,但无法异步获取日期。基本上我必须在显示日历之前显示的日期,所以我不得不使用async: false
(不是真的)。
我已经包含了完整的代码,演示了如何使用beforeShowDay
选项突出显示从数据库中提取的多个事件。使用asyc: false
修复了突出显示的日期未在初始绘制中突出显示的问题。还包括用于改变细胞背景颜色的css。
还有一个小问题,'年'下拉菜单没有显示在初始绘图上,但我已经确认这只发生在FireFox 4中。任何点击日历都会导致显示年份菜单。 Safari在初始绘图时正确显示年份菜单。
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<style type="text/css">
/* Dates with events on them. Text color - red, background - pastel yellow. */
td.highlight, table.ui-datepicker-calendar tbody td.highlight a {
background: none !important;
background-color: #fffac2 !important;
color: #FF0000;
}
/* This is Today's day in rightsidebar mini calendar (datepicker). */
/* Restore style to that of a default day, then just bold it. */
.ui-state-highlight, .ui-widget-content .ui-state-highlight {
border: 1px solid #d3d3d3;
background: #e6e6e6 url(http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;
font-weight: bold;
color: #555555;
}
/* This is the selected day in the inline datepicker. */
.ui-state-active, .ui-widget-content .ui-state-active {
color: #000000;
opacity: 1.0;
filter:Alpha(Opacity=100);
border: 1px solid #000000;
}
/* Add a little separation between month and year select menus */
.ui-datepicker select.ui-datepicker-month {
width: 42%;
margin-right: 6px;
}
</style>
<script>
$(document).ready(function(){
// get the current date
var today = new Date();
var m = today.getMonth(), d = today.getDate(), y = today.getFullYear();
// Get a list of dates that contain events in THIS month only from database.
// Declare and populate 'eventDates' array BEFORE adding "beforeShowDay" option to
// the datepicker. Otherwise, highlightDays() will have an empty 'eventDates' array.
var eventDates = [];
fetchEventDays(y, m+1); // Get events for the current year and month.
$('#datepicker').datepicker();
$('#datepicker').datepicker('option', 'onChangeMonthYear', fetchEventDays);
$('#datepicker').datepicker('option', 'beforeShowDay', highlightDays);
$('#datepicker').datepicker('option', 'onSelect', getday);
$('#datepicker').datepicker('option', 'dateFormat', 'yy-mm-dd');
$('#datepicker').datepicker('option', 'changeYear', true);
$('#datepicker').datepicker('option', 'changeMonth', true);
$('#datepicker').datepicker('option', 'yearRange', '2010:2012');
$('#datepicker').datepicker('option', 'showButtonPanel', true);
// Disable all dates prior to today.
// $('#datepicker').datepicker('option', 'minDate', new Date(y, m, d));
// ------------------------------------------------------------------
// getday - Replaces the #content div of the current page with
// the content of the page that is created and displayed via perl
// ------------------------------------------------------------------
function getday(dateText, inst) {
$('#content').load('<%config.db_cgi_url%>/eventmgr.cgi?do=view_day;date='+dateText+' #eventMgr_content', function() {
// alert('load was performed. '+dateText);
});
}
// ------------------------------------------------------------------
// fetchEventDays - The ajax call below is synchronous (NOT asynchronous).
// eventDates array must be populated prior to adding the beforeShowDay option
// to the datepicker, otherwise, highlightDays() will have an empty eventDates array.
// ------------------------------------------------------------------
function fetchEventDays(year, month, inst) {
var url ='<%config.db_cgi_url%>/eventmgr-ajax.cgi?do=get_event_dates&yr=' + year + '&mo=' + month;
$.ajax({
url: url,
async: false,
success: function(result){
var event_dates = result.split(',');
for(var i = 0; i < event_dates.length; i++) {
var date_parts = event_dates[i].split('-');
eventDates.push(new Date(date_parts[0], date_parts[1]-1, date_parts[2]));
}
}
});
}
// ------------------------------------------------------------------
// highlightDays - Add a custom css class to dates that exist in the
// eventDates array. Must also add the css for td.highlight (above).
// ------------------------------------------------------------------
function highlightDays(date) {
for (var i = 0; i < eventDates.length; i++) {
if ((eventDates[i].getTime() == date.getTime())) {
return [true, 'highlight'];
}
}
return [true, ''];
}
});
</script>
答案 1 :(得分:3)
我无法看到jQuery.when将如何提供帮助(看起来它不会推迟日期选择器中的事件)但是我设法通过禁用选择器来避免async = false,然后在收到数据时刷新ajax回调
var available_days = [];
var data = get_selected();
var today = new Date();
data['year'] = today.getFullYear();
data['month'] = today.getMonth() + 1;
$.get('{% url views.get_availability %}', data,
function(get_data) {
$("#datepicker").datepicker("destroy");
available_days = get_data['available_days'];
$("#datepicker").datepicker({
onChangeMonthYear: function(year, month, inst) {
$("#datepicker").datepicker("disable");
available_days = [];
data['year'] = year;
data['month'] = month;
$.get('{% url views.get_availability %}', data,
function(get_data) {
available_days = get_data["available_days"];
$("#datepicker").datepicker("refresh");
$("#datepicker").datepicker("enable");
}
);
},
beforeShowDay: function(date) {
return [$.inArray(date.getDate(), available_days) >= 0, ''];
},
onSelect: function(dateText, inst) { showTimes(dateText, data); },
dateFormat: "dd-mm-yy",
});
}
);
答案 2 :(得分:1)
我看不到您的示例,因为系统会提示您输入用户名和密码。但是,请参阅下面我认为正在发生的事情。
$.get
只是制作AJAX get请求的简写。 AJAX是异步的,意味着你调用它并且它不等待响应。所以基本上,可能发生的是在获取请求完成之前显示日历。
我可以通过两种方式解决这个问题。一种方法是将你的get转换为完整的ajax调用并设置async : true
。
http://api.jquery.com/jQuery.ajax/
另一种选择(可能是更好的选择)是使用when
。 When
基本上允许您在执行任何其他操作之前等待ajax请求完成。这允许它仍然是异步的,但确保不会过早地执行依赖代码。这样,可以在ajax调用和依赖代码之间执行其他操作。