我已经使用Phonegap为Android和iPhone等移动设备创建了一个完整的日历应用程序。我正在使用Jquery Touch Punch插件和Jquery fullcalendar插件。fullcalendar的"select"方法在web上运行良好。我可以在网络浏览器上的完整日历的月份视图中选择多个单元格。然而,在原生android/iPhone应用程序上,我无法选择日历的多个单元格(日期范围)。所发生的一切都是,当我点击单元格选择日期范围时,会触发"选择"方法,然后允许我在设备上选择多个日期。有没有办法克服这个问题?提前谢谢。这是Jsfidle。
示例代码:
// FullCalendar v1.5
// Script modified from the "theme.html" demo file
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#calendar').fullCalendar({
theme: true,
header: {
left: 'prev,next today',
center: 'title',
right: 'month'
},
editable: true,
disableDragging: true,
disableResizing: true,
droppable: true,
drop: function( date, allDay, jsEvent, ui ){
console.log(jsEvent);
console.log(ui);
},
// add event name to title attribute on mouseover
eventMouseover: function(event, jsEvent, view) {
if (view.name == "month") {
$(jsEvent.target).attr('title', event.title);
}
//alert(event.id);
},
// For DEMO only
// *************
events: [
{ id: 1,
title: 'User1',
start: '2012-09-01',
end: '2012-09-01',
color:'#E9B33E',
className: 'user-class1'},
{ id: 2,
title: 'User2',
start: '2012-09-06',
end: '2012-09-06',
color:'#00813E',
className: 'user-class2'},
{ id: 3,
title: 'User3',
start: '2012-09-06',
end: '2012-09-06',
color:'#E59238',
className: 'user-class3'},
{ id: 4,
title: 'User4',
start: '2012-09-06',
end: '2012-09-06',
color:'#00813E',
className: 'user-class4'},
{ id: 5,
title: 'User5',
start: '2012-09-08',
end: '2012-09-08',
color:'#00813E',
className: 'user-class5'},
],
eventRender: function(event,element,calEvent) {
element.attr('id',this.id);
if(this.id!=5){
element.find(".fc-event-title").after($("<br/><span class="fc-event-icons"></span>")
.html("<img src="http://png-5.findicons.com/files//icons/2018/business_icons_for/16/passport.png" onclick="javascript:iconsAlert("+this.id+",'passport')" class="icon"/>"+
"<img src="http://findicons.com/files//icons/1571/chalkwork_payments/16/card_visa.png" onclick="javascript:iconsAlert("+this.id+",'visa')" class="icon" />"+
"<img src="http://findicons.com/files//icons/894/banking_stuff/16/postage_stamp.png" onclick="javascript:iconsAlert("+this.id+",'traveldoc')" class="icon" />"+
"<img src="http://findicons.com/files//icons/756/ginux/16/richtext.png" onclick="javascript:iconsAlert("+this.id+",'entrystamp')" class="icon" />"));
}
element.droppable({
accept: '*',
tolerance: 'touch',
//activeClass: 'ui-state-hover',
//hoverClass: 'ui-state-active',
drop: function(ev, ui) {
//console.log(ev.id);
alert(this.id);
//for(param in ui){ console.log(ev.id);}
}
});
},
selectable: true,
selectHelper: true,
select: function(start, end, allDay) {
alert("Cell selected from "+$.fullCalendar.formatDate(start, 'yyyy-MM-dd')+" to "+$.fullCalendar.formatDate(end, 'yyyy-MM-dd'));
},
eventClick: function(calEvent, jsEvent, view) {
if (!$(jsEvent.target).hasClass("icon")) {
alert("UserID:"+calEvent.id);
}
}
});
$('#external-events div.passport-event,.visa-event,.entrystamp-event,.traveldoc-event').each(function() {
// create an Event Object (http://arshaw.com/fullcalendar/docs/event_data/Event_Object/)
// it doesn't need to have a start or end
var eventObject = {
title: $.trim($(this).text()), // use the element's text as the event title
className: $(this).attr('class')
};
// store the Event Object in the DOM element so we can get to it later
$(this).data('eventObject', eventObject);
// make the event draggable using jQuery UI
$(this).draggable({
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
});
});
[向主持人提出谦虚的请求:除非问题得到解决,否则请不要关闭。谢谢]
将事件侦听器添加到已经初始化的日历的单元格中,并应用一些魔法,比如:
$('#calendar table.fc-border-separate td.ui-widget-content').on('touchstart', function (event) {
/* touch start processing, probably cancelling like*/
event.preventDefault();
event.stopImmediatePropagation();
function mouseMoveHandler (event) {
/* processing actual drag */
/* possible also cancelling default behavior and instead calling Calendar API */
}
function mouseUpHandler (event) {
/* processing mouse up */
/* some clean up */
$(document).off('touchmove', mouseMoveHandler)
.off('touchend touchleave touchcancel', mouseUpHandler);
}
$(document).on('touchmove', mouseMoveHandler)
.on('touchend touchleave touchcancel', mouseUpHandler);
});
我知道与您的其他代码相比,这有点低级,但这会有所帮助。这些活动只能在手机上进行,你可能会实现想要的行为。很抱歉没有时间自己尝试这种方法,也许我稍后会在jsFiddle上尝试。
另一个解决方案是Datebox。我已经在jquery移动应用程序中实现了它,它很容易使用。在电脑、手机、tblet上都很好http://dev.jtsage.com/jQM-DateBox2/
只是为了增加这个老问题。。。
一种无接触冲头的解决方案:
我个人已经为mobilie实现了完整的日历,并且在多选的触摸移动处理方面遇到了问题,所以我决定只基于html day对象本身来完成这一切。
我只得到第一次选择的高度/宽度,并计算相对于该高度/宽度移动的距离。它需要SelectDates(date1,date2)函数来处理您想要对所选日期范围执行的任何操作。
这是我的代码:
$(document).on('touchmove', '.fc-day', function (e) {
var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
var $startElement = $(this);
var moveStartDate = new Date($startElement.data('date'));
var timezoneOffset = moveStartDate.getTimezoneOffset() * 60000;
moveStartDate.setTime(moveStartDate.getTime() + timezoneOffset);
var rect = $startElement[0].getBoundingClientRect();
var DayHeight = $startElement[0].clientHeight;
var DayWidth = $startElement[0].clientWidth;
var xdif = 0;
if (touch.pageX < rect.left) {
xdif = touch.pageX - rect.left;
}
if (touch.pageX > rect.right) {
xdif = touch.pageX - rect.right;
}
var xDaysAwayDecimal = xdif == 0 ? 0 : (xdif / DayWidth);
var xDaysAway = xdif >= 0 ? Math.ceil(xDaysAwayDecimal) : Math.floor(xDaysAwayDecimal);
var ydif = 0;
if (touch.pageY < rect.top) {
ydif = touch.pageY - rect.top;
}
if (touch.pageY > rect.bottom) {
ydif = touch.pageY - rect.bottom;
}
var yDaysAwayDecimal = ydif == 0 ? 0 : (ydif / DayHeight);
var yDaysAway = ydif >= 0 ? Math.ceil(yDaysAwayDecimal) : Math.floor(yDaysAwayDecimal);
var dayModifier = (yDaysAway * 7) + xDaysAway;
var moveEndDate = new Date(moveStartDate);
moveEndDate.setDate(moveEndDate.getDate() + dayModifier);
if (moveStartDate > moveEndDate) {
SelectDates(moveEndDate, moveStartDate);
}
else {
SelectDates(moveStartDate, moveEndDate);
}
})
此外。。如果你的SelectDates()做了任何繁重的工作,你可能只想让它每移动x个像素或x毫秒激发一次。。。要么保存这些值,然后在停止时进行处理。我的SelectDates()在日历中添加了css,所以我希望它能通过触摸移动动作连续触发。
这个答案在另一篇StackOverflow帖子中找到:我们如何使用fullcalendar指定自定义日期范围?
您可以调用此函数来获取日期范围内的事件。然而,这将只为您带来30天的活动。
function GetAgendaEvents(datefrom, dateTo) {
var fromDate = new Date($("#from").val());
var toDate = new Date($("#to").val());
if (fromDate.getTime() <= toDate.getTime()) {
$('#fullcal').fullCalendar('removeEvents').fullCalendar('addEventSource', events);
$('#fullcal').fullCalendar('refetchEvents');
var filteredEvent = $('#fullcal').fullCalendar('clientEvents', function (event) {
return event.start >= fromDate && event.start <= toDate;
});
$('#fullcal').fullCalendar('gotoDate', fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate());
$('#fullcal').fullCalendar('changeView', 'agenda'/* or 'basicDay' */);
$('#fullcal').fullCalendar('removeEvents').fullCalendar('addEventSource', filteredEvent);
$('#fullcal').fullCalendar('refetchEvents');
}
}
经过大量搜索,我没有找到简单明了的答案,所以,我自己做了它,它是:
var calendar = $('#calendar').fullCalendar({
..
....
..
dayRender: function( date, cell) {
$(cell).on("touchend",function(event){
var startDate = date;
var x= event.originalEvent.changedTouches[0].clientX;
var y = event.originalEvent.changedTouches[0].clientY
var endDate = moment($(document.elementFromPoint(x, y)).attr("data-date"),"YYYY-MM-DD");
if(endDate>startDate){
calendar.fullCalendar( 'select', startDate, endDate.add('days', 1));
}else{
calendar.fullCalendar( 'select', endDate, startDate.add('days', 1));
}
});
},
select: function(start, end, allDay, jsEvent, view) {
..
....
..
calendar.fullCalendar('unselect');
}
});
根据我的经验,我从未发现日历是完成此类任务的好选择。请尝试改用日期选择器-http://jquerymobile.com/demos/1.0a4.1/experiments/ui-datepicker/