こんにちは、BBGの清水です。
ngx-bootstrapのmodalとng-fullcalendarを併用した時におきた問題について話します。
やりたいこと
- fullcalendarで実装していたカレンダーをAngularアプリケーション内に表示したい
- カレンダーは、
ngx-bootstrap
のmodal上に表示したい
環境
- Angular: 6.0.0
- jquery: ^3.2.1
- ngx-bootstrap: ^3.1.3
- fullcalendar: 3.6.1
- ng-fullcalendar: ^1.7.1
Angularで使えそうなcalendarライブラリを探していたら次の2つが見つかりました。
- ng-fullcalendar
- angular-calendar
angular-calendar の方が人気なのかーと思いつつも
今回は、fullcalendarで作られたカレンダーのリプレースだったのでng-fullcalendar
を起用しました。
ng-fullcalendarを使ってみる
ソースコードはこんな感じです。(installなどはdocsにあるので省略します。)
<div bsModal #modal="bs-modal" class="modal" role="dialog">
<div class="modal-dialog">
<div class="fullcalendar-content" *ngIf="calendarOptions">
<div class="fullcalendar-header">
...
</div>
<ng-fullcalendar [options]="calendarOptions" ... >
</ng-fullcalendar>
</div>
</div>
import { Component, OnInit } from '@angular/core';
import { CalendarComponent } from 'ng-fullcalendar';
import { Options } from 'fullcalendar';
@Component({ ... })
export class CalendarComponent implements OnInit {
calendarOptions: Options;
constructor(){}
ngOnInit() {
this.calendarOptions = {
allDayText: '終日',
contentHeight: 600,
editable: true,
eventLimit: false,
events: [],
firstDay: 0,
header: false,
locale: 'ja',
slotLabelFormat: 'H:mm',
selectable: true,
timeFormat: 'H:mm',
views: {
month: {
columnFormat: 'ddd',
titleFormat: 'YYYY年MM月',
},
week: {
columnFormat: 'MM/DD(ddd)',
titleFormat: 'YYYY年MM月DD日',
},
day: {
columnFormat: 'MM/DD(ddd)',
titleFormat: 'YYYY年MM月DD日(ddd)',
},
},
};
}
}
カレンダーのヘッダはカスタムしたかったので、デフォルト表示をfalseにしました。
問題がおきた。。
モーダルを開いてみると日付エリアが表示されない問題が、、
モーダル以外で表示しようとすると期待した動作をしました。
これは、bootstraptとfullcalendarを併用した時に発生するfullcalendarのバグのようです。
bootstrapの他module内にfullcalendarを表示しようたら同じような現象がおきた、という人もいました。
解決
bootstrapのmoduleを表示した後に、カレンダーの表示をしてあげれば解決しそうだったのでModalModuleのonShown
を使用して次のような実装に修正しました。
import { Component, OnInit, ViewChild } from '@angular/core';
import { CalendarComponent } from 'ng-fullcalendar';
import { Options } from 'fullcalendar';
import { ModalDirective } from 'ngx-bootstrap/modal';
@Component({ ... })
export class CalendarComponent implements OnInit {
calendarOptions: Options;
@ViewChild('modal') modal: ModalDirective;
constructor(){}
ngOnInit() {
this.modal.onShown.subscribe(() => {
this.calendarOptions = { ... };
});
}
}
終わりに
ng-fullcalendarでfullcalendarのカレンダーが簡単に利用できました。
ただ、bootstrapと併用するとバグがあるのと、まだAnugular7以降には対応してなさそうなので今後Angularのバージョンに追随していくのかが気になっています。
angular-calendar
も今度触ってみようと思います!