Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calendar month is bugged inside a modal #591

Open
Quentius opened this issue Mar 23, 2021 · 11 comments
Open

Calendar month is bugged inside a modal #591

Quentius opened this issue Mar 23, 2021 · 11 comments

Comments

@Quentius
Copy link

Quentius commented Mar 23, 2021

The calendar inside my modal is bugged.

Description:
The Arrows next to the date (Februari 2021 as example) Ain't working on the screenshot. To make the swiping work, and actually be able to click on dates I need to swipe the calendar manually to the month next. Thats where the current date is.

It is important to check the dates in the pictures
Example swipe: https://ibb.co/QN6TMfg
How it is right now: https://ibb.co/gzRgWqh
How it should be: https://ibb.co/ZT49tLX

Typescript:

import {AfterViewInit, Component, OnInit} from '@angular/core';
import {ModalController} from '@ionic/angular';
import { DatePipe } from '@angular/common';

@Component({
  selector: 'app-cal-modal-activity',
  templateUrl: './cal-modal-activity.page.html',
  styleUrls: ['./cal-modal-activity.page.scss'],
})
export class CalModalActivityPage implements AfterViewInit {
  calendar = {
    mode: 'month',
    selected: null,
    currentDate: new Date()
  };
  eventSource = [];
  viewTitle: string;
  currentDate = new Date();
  startUpdate: any;
  endUpdate: any;


  startDate: Date = this.currentDate; // TODO Not working yet. Hour + 1, min + 15
  endDate = this.currentDate.setHours( + 1);
  // TODO Fix that user can select own time (Check randomevents for the code)
  event = {
    title: '',
    desc: '',
    startTime: this.currentDate,
    endTime: '',
  };
  onInit() {
    console.log(this.endDate);
  }

  constructor(private modalCtrl: ModalController) { }

  ngAfterViewInit() {
    const hidden = document.getElementById('hidden');
    hidden.style.display = 'none';
    document.getElementById('hidden2').setAttribute('style', 'display: none');
  }
  save() {
    this.modalCtrl.dismiss({event: this.event});
  }
  onViewTitleChanged(title) {
    this.viewTitle = title;
  }
  onTimeSelected(ev) {
    console.log('ev: ', ev);
    this.event.startTime = new Date(ev.selectedTime);
    this.startDate = new Date(ev.selectedTime);
  }
  close() {
    this.modalCtrl.dismiss();
  }
  showCalendar() {
    const hidden = document.getElementById('hidden');
    if (hidden.style.display === 'none') {
      hidden.style.display = 'block';
      document.getElementById('calendar').setAttribute('style', 'display: block');
      document.getElementById('hidden2').setAttribute('style', 'display: block');
    } else {
      hidden.style.display = 'none';
      document.getElementById('calendar').setAttribute('style', 'display: none');
      document.getElementById('hidden2').setAttribute('style', 'display: none');
    }
  }
  next() {
    this.calendar.currentDate = new Date(this.calendar.currentDate.setMonth(this.calendar.currentDate.getMonth() + 1));
  }
  back() {
    this.calendar.currentDate = new Date(this.calendar.currentDate.setMonth(this.calendar.currentDate.getMonth() - 1));
  }
  updateStart(startUpdate) {
    const datepipe: DatePipe = new DatePipe('en-US');
    const newDate = (datepipe.transform(startUpdate, 'd MMM. y HH:mm'));
    console.log(newDate);
  }
  updateEnd(endUpdate) {
    const datepipe: DatePipe = new DatePipe('en-US');
    const newDate = (datepipe.transform(endUpdate, 'd MMM. y HH:mm'));
    console.log(newDate);
  }
}

HTML:

<ion-toolbar>
    <ion-buttons slot="start">
        <ion-button (click)="close()">
            <ion-icon name="close" slot="icon-only"></ion-icon>
        </ion-button>
    </ion-buttons>
    <ion-title>New event</ion-title>
    <ion-buttons slot="end">
        <ion-button (click)="save()">
            <ion-icon name="checkmark" slot="icon-only"></ion-icon>
        </ion-button>
    </ion-buttons>
</ion-toolbar>

<ion-content>
    <ion-item lines="none">
        <ion-label position="stacked">Title</ion-label>
        <ion-input [(ngModel)]="event.title" type="text"></ion-input>
    </ion-item>
    <ion-item lines="none">
        <ion-label position="stacked">Description</ion-label>
        <ion-input [(ngModel)]="event.desc" type="text"></ion-input>
    </ion-item>
    <div style="width: 100%; height: 1.5%;color: transparent;"><h2 style="margin-top: 0;"></h2></div>
    <ion-item lines="none">
        <ion-label position="fixed">Whole day</ion-label>
        <ion-toggle slot="end">
        </ion-toggle>
    </ion-item>
    <ion-item lines="none" class="ion-no-padding start" (click)="showCalendar()">
        <ion-label class="startlabel" position="fixed">Start</ion-label>
        <h5 slot="end">{{startDate | date: 'd MMM. y'}}</h5>
    </ion-item>
    <ion-item id="hidden" lines="none" class="ion-no-padding">
        <ion-label class="startlabel" position="fixed">Time</ion-label>
        <ion-datetime slot="end" placeholder="{{startDate | date: 'HH:mm'}}" displayFormat="HH:mm" (ionChange)="updateStart(this.startUpdate)" [(ngModel)]="startUpdate"></ion-datetime>
    </ion-item>
    <ion-item id="hidden2" lines="none" class="ion-no-padding">
        <ion-label class="startlabel">{{ viewTitle }}</ion-label>
        <ion-button class="block" fill="clear" (click)="back()">
            <ion-icon class="swipe" name="arrow-back" slot="icon-only"></ion-icon>
        </ion-button>
        <ion-button class="block" fill="clear" (click)="next()">
            <ion-icon class="swipe" name="arrow-forward" slot="icon-only"></ion-icon>
        </ion-button>
    </ion-item>
        <calendar
                id="calendar"
                [eventSource]="eventSource"
                [calendarMode]="calendar.mode"
                [currentDate]="calendar.currentDate"
                (onTitleChanged)="onViewTitleChanged($event)"
                (onTimeSelected)="onTimeSelected($event)"
        ></calendar>
    <ion-item lines="none">
        <ion-label position="fixed">End</ion-label>
        <ion-datetime slot="end" placeholder="{{endDate | date: 'HH:mm'}}" displayFormat="HH:mm" min="1990" (ionChange)="updateEnd(this.endUpdate)" [ngModel]="endUpdate" minuteValues="0,5,10,15,20,25,30,35,40,45,50,55"></ion-datetime>
    </ion-item>
</ion-content>

SCSS

* {
  color: #e6e6e6;
  --color: #e6e6e6;
  --background: #161616;
}
ion-toolbar {
  --background: #466c46;
  color: #e6e6e6;
}
ion-button {
  --background: 0;
}
:host ::ng-deep {
  .event-detail-container {
    display: none;
  }
  .monthview-container {
    height: auto !important;
  }
  .monthview-primary-with-event {
    background-color: white !important;
  }
  .monthview-selected {
    background-color: #578054 !important;
  }
  .monthview-primary-with-event, .calendar-event-inner{
    background-color: rgba(30, 44, 29, 0.86) !important;
    &.monthview-selected {
      background-color: rgba(87, 128, 84, 0.64) !important;
    }
  }
  .monthview-current {
    background: rgba(255, 255, 255, 0.14)!important;
    &.monthview-selected {
      background-color: #578054 !important;
    }
  }
  td, th {
    border: 0 !important;
  }
  .monthview-datetable {
    border: 1px solid rgba(36, 36, 36, 0.33)!important;
    background: rgba(52, 52, 52, 0.14)!important;
  }
  .event-detail-container { //De events display
    display: none!important;
  }

}
ion-datetime {
  text-align: right;
  padding: 0;
}
ion-content {
  margin: 5%;
}
ion-toggle {
  --background: #252525;
  --background-checked: #578054;
}
#hidden, #calendar {
  display: none;
}
ion-icon.swipe {
  color: #578054;
}
ion-item, ion-input, :host ::ng-deep.monthview-container {
  --background: #1a1a1a;
  background: #1a1a1a;
}
ion-item {
  border-bottom: 1px solid rgba(118, 118, 118, 0.81);
  //margin: 0 4% 0 5.5%;
}
ion-input {
  --padding-top: 2px!important;
  --padding-bottom: 4px!important;
}
h5 {
  font-size: 17px;
}
#calendar {
  width: 90%;
  margin: auto 5% 5% 5%;
}
.start {
  //margin: 0 4% 0 5.5%;
  border-top: 1px solid rgba(118, 118, 118, 0.81);
}
.startlabel {
  padding-left: 16px;
}


The red surrounded line is the issue. Is there a way to remove it?
Screenshot_1

@twinssbc
Copy link
Owner

@Quentius If I understand correctly, you mean you can't use the arrow button to change the month to previous/next month?
I tried your code, it seems working.
I notice you did a lot of pure JavaScript DOM manipulations, I suggest not to do that as Angular may not notice these changes. You also override some CSS styles, try to remove them to see if it works. If you want to hide the event detail section, there's a showEventDetail option.

@davidecampello
Copy link

Hello! I have the same problem.
I'm not doing any manual dom manipulation and I'm using the component inside a modal... Have you found a solution?
I can try to provide a demo in case.
The problem for me appear after the second time I open the modal

@davidecampello
Copy link

Maybe the problem is that the calendar store some data into a service and they are not reinitialized when a component is destroied and recreated?

@davidecampello
Copy link

Hello, i created a small stackblitz example to show the problem:
https://stackblitz.com/edit/ionic-5-angular-10-start-template-x8pmlu?file=src/app/tab1/calendar-modal.component.ts
Calendar work fine the first time but after it show a wrong month and slides work in "free" mode.
Thanks for the help

@davidecampello
Copy link

Hi @twinssbc! Can you please look if the problem is simple to solve now that there is a stackbliz? Many Thanks for your time

@Quentius
Copy link
Author

Screencast-from-29-07-21-15_57_30
Here is a video of my issue. If i open the modal i cant select a date without first swiping to the next month.

@twinssbc
Copy link
Owner

twinssbc commented Aug 3, 2021

@davidecampello @Quentius The reason because of this issue is the calendar was loaded before the page is fully rendered.
To solve it, you could add ngif to hide the calendar at the beginning, and set it to true in the ionViewDidEnter event.

For example,

This is the template, notice I use showCalendar to control the visibility

    <ion-header>
      <ion-toolbar>
        <ion-title>{{ viewTitle }}</ion-title>
        <ion-buttons slot="end">
          <ion-button (click)="today()">
            Today
          </ion-button>
          <ion-button (click)="changeMode('month')">M</ion-button>
          <ion-button (click)="changeMode('week')">W</ion-button>
          <ion-button (click)="changeMode('day')">D</ion-button>
          <ion-button (click)="loadEvents()">Load Events</ion-button>
          <ion-button (click)="close()">close</ion-button>
        </ion-buttons>
      </ion-toolbar>
    </ion-header>

    <ion-content *ngIf="showCalendar">
    <calendar
        [calendarMode]="calendar.mode"
        [currentDate]="calendar.currentDate"
        (onCurrentDateChanged)="onCurrentDateChanged($event)"
        (onEventSelected)="onEventSelected($event)"
        (onTitleChanged)="onViewTitleChanged($event)"
        (onTimeSelected)="onTimeSelected($event)"
        [step]="calendar.step"
      >
      </calendar>
    </ion-content>

Then in the component ts

  showCalendar:boolean;

  ionViewDidEnter() {
    this.showCalendar = true;
  }

@davidecampello
Copy link

Thank you very much @twinssbc, I'll try and let you know

@cfirmo33
Copy link

@davidecampello @Quentius

  showCalendar:boolean;

  ionViewDidEnter() {
    this.showCalendar = true;
  }

Thanks guys, it´s worked fine.

@sriptter
Copy link

@davidecampello @Quentius

  showCalendar:boolean;

  ionViewDidEnter() {
    this.showCalendar = true;
  }

Thanks guys, it´s worked fine.

Hi. this works also for me but i'm facing another issue which is i can't acess the calendar programaticaly in the ts file using viewchild

@zzyong666
Copy link

zzyong666 commented Jun 15, 2022

image

ngAfterViewInit(){ setTimeout(() => { this.myCalendar.update(); }) }

Use this method after init. it´s worked fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants