Подтвердить что ты не робот

Полный календарный выбор ячейки на мобильном устройстве?

Я создал приложение fullcalendar для мобильных устройств, таких как Android и iPhone, с помощью Phonegap. Я использую плагин JQuery Touch Punch Plugin вместе с плагином Jquery fullcalendar. Метод "select" fullcalendar отлично работает в Интернете. Я могу выбрать несколько ячеек в представлении месяца полного календаря в веб-браузере. Тем не менее, в приложении для родного Android/iPhone я не могу выбрать несколько ячеек (диапазон дат) календаря. Все, что происходит, - это когда я нажимаю на ячейку, чтобы выбрать диапазон дат, тогда запускается метод "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 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
        });

    });
});

[Смиренный запрос модераторам: Пожалуйста, не закрывайте этот вопрос, если он не будет разрешен. Спасибо]

4b9b3361

Ответ 1

Как насчет добавления прослушивателей событий в ячейки уже инициализированного календаря и применения некоторой магии, например:

$('#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.

Ответ 2

Этот ответ был найден в другом сообщении StackOverflow: Как мы можем указать пользовательский диапазон дат с полным календарем?

Вы можете вызвать эту функцию, чтобы получать события из диапазона дат. Однако это приведет к 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');
    }
}

Ответ 3

другое решение - Datebox. Я реализовал его в своем мобильном приложении jQuery, его простой в использовании. и очень хорош как для компьютера, мобильного телефона, так и для http://dev.jtsage.com/jQM-DateBox2/

Ответ 4

Просто добавьте этот старый вопрос...

Решение без касания:

Я лично внедрил fullcalendar для мобили, и у меня возникли проблемы с обработкой мультиплекса touchmove, поэтому я решил сделать все это только на основе самих объектов html day.

Я просто получаю высоту/ширину того, что было сначала выбрано, и подсчитайте расстояние, перемещенное относительно этой высоты/ширины. Для этого требуется функция SelectDates (date1, date2), чтобы обрабатывать все, что вы хотите сделать, с помощью daterange вашего выбора.

Вот мой код:

        $(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() делает тяжелый подъем, вы можете захотеть, чтобы он срабатывал только при каждом количестве перемещенных пикселов или х миллисекундах... либо это, либо просто сэкономить значения, а затем выполнить обработку когда вы остановитесь. Мой SelectDates() добавил css в календарь, поэтому я хотел, чтобы он срабатывал непрерывно с движением касания.

Ответ 5

После многих поисков я не нашел простого и ясного ответа. Итак, я сделал это сам, и вот он:

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