移动设备上的fullcalendar多单元格select?
我使用Phonegap为Android和iPhone等移动设备创build了一个fullcalendar应用程序。 我正在使用Jquery Touch Punch Plugin和Jquery fullcalendar插件。 fullcalendar的“select”方法在Web上运行良好。 我可以在Web浏览器上的完整日历的月视图中select多个单元格。 但是,在本机的Android / iPhone应用程序,我无法select日历的多个单元格(date范围)。 所有发生的事情是,当我点击单元格来selectdate范围,然后在select设备上的多个date之前触发“select”方法。 有没有办法克服这个问题? 先谢谢你。 这是Jsfiddle 。
示例代码:
// 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 }); }); });
[谦逊的请求主持人:请不要closures这个问题,除非解决。 谢谢]
如何将事件侦听器添加到已经初始化的日历的单元格中并应用一些魔法,如下所示:
$('#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上尝试。
另一个解决scheme是Datebox。 我已经在我的jquery移动应用程序中实现了它,它易于使用。 非常适合电脑,手机,tblet http://dev.jtsage.com/jQM-DateBox2/
只是为了增加这个老问题
无冲头的解决scheme:
我个人实现了mobilie的fullcalendar,并且遇到了multiselect的touchmove处理问题,所以我决定只是基于html天对象本身。
我只是得到第一次select的高度/宽度,并计算移动的距离与高度/宽度的关系。 它需要一个SelectDates(date1,date2)函数来处理你想要做的select的date范围。
这是我的代码:
$(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毫秒数量就会触发它,或者只是保存值,然后停止处理。 我selectdate()添加到日历的CSS,所以我希望它随着触摸移动运动不断发射。
这个答案是在另一个StackOverflow文章中find的: 我们如何使用fullcalendar指定自定义date范围?
你可以调用这个函数来获取date范围内的事件。 不过,这只会给你带来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'); } }
经过大量的search,我发现没有简单明确的答案,所以我自己做了,这里是:
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'); } });
从我的经验来看,我从来没有发现日历作为这种任务的好select。 尝试使用datepicker来代替 – http://jquerymobile.com/demos/1.0a4.1/experiments/ui-datepicker/