libreria full example bootstrap jquery jquery-plugins jquery-mobile jquery-selectors fullcalendar

jquery - example - fullcalendar multiple cell select en dispositivo móvil?



libreria full calendar (6)

He creado una aplicación de calendario completo para dispositivos móviles como Android y iPhone usando Phonegap. Estoy usando el complemento Jquery Touch Punch junto con el complemento Jquery fullcalendar. El método ''select'' de fullcalendar funciona bien en la web. Puedo seleccionar la celda múltiple en la vista mensual del calendario completo en el navegador web. Sin embargo, en la aplicación nativa de Android / iPhone no puedo seleccionar varias celdas (rango de fechas) del calendario. Todo lo que ocurre es que cuando hago clic en la celda para seleccionar el rango de fechas, se activa el método ''seleccionar'' antes de permitirme seleccionar varias fechas en el dispositivo. ¿Hay alguna forma de superar este problema? Gracias de antemano. Aquí está el Jsfiddle .

Código de muestra:

// 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 }); }); });

[Petición humilde a los moderadores: no cierren esta pregunta a menos que se resuelva. Gracias]


¿Qué tal si agregamos oyentes de eventos a las celdas del calendario ya inicializado y aplicamos alguna magia, como esta:

$(''#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); });

Sé que esto es un poco de bajo nivel en comparación con el resto de tu código, pero eso puede ser útil. Estos eventos solo funcionarán en teléfonos móviles y probablemente podrá lograr el comportamiento deseado. Lo siento, no hay tiempo para probar este enfoque yo mismo, tal vez lo intente más tarde en jsFiddle.



Después de muchas búsquedas, no encontré una respuesta simple y clara, así que lo hice solo, y aquí está:

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''); } });


Esta respuesta se encontró en otra publicación de : ¿cómo podemos especificar el rango de fechas personalizado con fullcalendar?

Puede llamar a esta función para obtener eventos de un rango de fechas. Sin embargo, esto solo le brindará 30 días de eventos.

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''); } }


Solo para agregar a esta vieja pregunta ...

Una solución sin toque de toque:

Personalmente, he implementado el calendario completo para mobilie y estaba teniendo problemas con el manejo de touchmove de multiselect, así que decidí hacerlo todo solo en función de los objetos html day.

Acabo de obtener el alto / ancho de lo que primero se selecciona y cuento la distancia movida en relación a esa altura / ancho. Requiere una función SelectDates (date1, date2) para manejar lo que quieras con el rango de fecha seleccionado.

Aquí está mi código:

$(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); } })

Además ... si SelectDates () realiza algún trabajo pesado, puede desear que solo se active cada x cantidad de píxeles movidos o x cantidad de milisegundos ... o eso o simplemente guardar los valores y luego procesarlos cuando detenga . My SelectDates () agregó css al calendario, así que quería que se disparara continuamente con el movimiento táctil.


otra solución es Datebox. Lo he implementado en mi aplicación móvil jquery, es fácil de usar. y muy bueno para ambos en la computadora, móvil, tblet http://dev.jtsage.com/jQM-DateBox2/