詳細検索

AngularUI Calendar (FullCalendar) dayClick not work expectedly on iOS

Avatar
by furuyamah
3 min read

AngularUI Calendar (FullCalendar) dayClick not work expectedly on iOS
Translated from 日本語 • View original

This is a story from angularUI Calendar 1.0.0 and FullCalendar 2.1.1 that I put in bower.

AngularUI Calendar http://angular-ui.github.io/ui-calendar/ perfectly meets your need for calendars in Angular WEB apps.

However, if you use dayClick to switch from month display to agendaDay display with day cell clicks, it doesn't work well on iPhone for some reason.

To be precise, if you try to press and hold for a second or so instead of tapping, or lightly drag the sun cell, dayClick will be called.

Why!

After thinking about it for about 3 days, I managed to deal with it, so I'll share it. By the way, AngularUI Calendar is a wrapper for FullCalendar, so it should work for those who are suffering from similar problems with FullCalendar.... is.

Causes

drag event is due to the difference in the handling of events. dayClick is not called in the click event. It is called by detecting the end of drag. Safari on iOS (or rather, webkit?) Other than that, the moment you tap and release your finger, the drag start and drag end event will occur, but on iOS, it seems that the drag end event does not occur unless you drag or keep tapping for a while.

I fixed the FullCalendar.js to call dayClick in the tap event.

Near line 4038

    coordMap: null, // a GridCoordMap that converts pixel values to datetimes
    cellDuration: null, // a cell's duration. subclasses must assign this ASAP
    isTouch : false, // separate touch and scroll.

// Renders the grid into the `el` element.

Near line 4093

        this.el.on('mousedown', function(ev) {
            if (
                !$(ev.target).is('.fc-event-container *, .fc-more') && // not an an event element, or "more.." link
                !$(ev.target).closest('.fc-popover').length // not on a popover (like the "more.." events one)
            ) {
                _this.dayMousedown(ev);
            }
        });

this.el.on('touchstart', function (ev) {
            this.isTouch = true;
        });

this.el.on('touchmove', function (ev) {
            this.isTouch = false;
        });

this.el.on('touchend', function (ev) {
                if (this.isTouch == false) {
                    //may be scroll.
                    return;
                }
                if (
                    !$(ev.target).is('.fc-event-container *, .fc-more') && // not an an event element, or "more.." link
                    !$(ev.target).closest('.fc-popover').length // not on a popover (like the "more.." events one)
                ) {
                    _this.touchEnd(ev);
                }
            }
        );

this.bindSegHandlers(); // attach event-element-related handlers. in Grid.events.js
    },

touchEnd: function(ev){
        console.log("touch end called.");
        var _this = this;
        var view = this.view;

this.coordMap.build();
        var cell = _this.coordMap.getCell(ev.originalEvent.pageX, ev.originalEvent.pageY);
        var dayEl = _this.getCellDayEl(cell);
        view.trigger('dayClick', dayEl[0], cell.date, ev);
    },

// Process a mousedown on an element that represents a day. For day clicking and selecting.
    dayMousedown: function(ev) {

If you simply catch touchend, the behavior may be strange when you are dragged, so I also catch touchstart and touchmove to identify drag and tap.

I hope you find it helpful!

Changed fullcalendar.js fullcalendar.js

Related Articles