twinssbc / Ionic2-Calendar

A calendar component based on Ionic framework
https://ionic-calendar-demo.stackblitz.io
MIT License
388 stars 197 forks source link

Need to tap twice to fire onEventSelected on iOS #199

Closed Avislux closed 7 years ago

Avislux commented 7 years ago

Hi. On iOS devices there's a problem when trying to click on events. I have to tap an event twice to fire onEventSelected, which I have set to push another view. There's also a small delay before the page is pushed. This doesn't happen in any other device I've tested. Any work around? Thanks.

twinssbc commented 7 years ago

@Avislux Have you tested it in multiple IOS version or only on a specific version? Also could you debug to locate the delay actually happens on certain line(s) of code?

Avislux commented 7 years ago

I have this happening on the latest iOS version on my iPad, as well as the version before it. This also happens on someone else's iPhone. I only have problems on a built app. If I open the app in my iPad's Safari hosted on local network using ionic serve I don't get this issue. I believe it has to do with using (click) vs (tap) in the template.

I'm also trying to build a fork but I'm having problems on how to do it properly.

twinssbc commented 7 years ago

@Avislux The delay happens on which view, monthview, weekview or dayview? I added tappable attribute in some places to remove the 300ms delay, but not all places, for example the event detail section in monthview. If you want to customize the event detail section, you could use the custom template, no need to modify the source code.

Avislux commented 7 years ago

It happens in monthview. I wasn't aware of the template customization. That might actually solve all my little issues. Would it be possible to color a day in monthview differently if it has an event with a specific property?

twinssbc commented 7 years ago

@Avislux Yes, the default template is as below

        <template #monthviewDefaultDisplayEventTemplate let-view="view" let-row="row" let-col="col">
            {{view.dates[row*7+col].label}}
        </template>

It only displays the date label by default. view.dates[row*7+col] actually has below data structure.

export interface IMonthViewRow {
    current?: boolean;
    date: Date;
    events: IEvent[];
    hasEvent?: boolean;
    label: string;
    secondary: boolean;
    selected?: boolean;
    disabled: boolean;
}

So you could use ngClass or ngStyle on some custom fields, like view.dates[row*7+col].events[0].customProperty to generate some customized css style.

Avislux commented 7 years ago

So I tried something like this.

<template #monthTemplate let-view="view" let-row="row" let-col="col">
<div  [ngClass]="{'open-color':view.dates[row*7+col].events[0].allDay, 'closed-color': holidayClosed}">{{view.dates[row*7+col].label}}</div>
 </template>

This gives me a bunch of errors saying TypeError: Cannot read property 'allDay' of undefined when I try to load the calendar page. Trying it with a custom property gives me a similar error. Ultimately I want the cell color to change based on a custom event property "flag", which is set to 0, 1, or 2.

I used [ngClass]="{'open-color':view.dates[row*7+col].events[1] and expectedly colors the cells with more than one event with a different color. So at least I know it can work.

twinssbc commented 7 years ago

@Avislux I think this is because on some date, there's no event, so when you access events[0].allDay, you get read property of undefined error. You could try the ?. syntax.

Avislux commented 7 years ago

Thanks for your help. That was the issue, but then I wondered how to check for all events in a day rather than a specific event. So I did this: [ngClass]="{'open-color': checkFlags(view.dates[row*7+col].events) == 2, 'closed-color': checkFlags(view.dates[row*7+col].events) == 1}

    checkFlags(events){
        let highestFlag = 0;
        for (let i = 0; i < events.length;i++){
            if (events[i].flag >highestFlag){
                highestFlag = events[i].flag;
            }
        }
        return highestFlag;
    }

And it worked perfectly. Only problem was that the background color won't fill the entire cell by itself due to padding on the surrounding tds. So I had to mess with the css a bit more.

 .open-color {
    background-color: rgb(255, 225, 92);
    margin:-8px;
    padding:8px 0;
  }
  .closed-color {
    background-color: rgb(255, 26, 35);
    margin:-8px;
    padding:8px 0;
  }