Angularでカレンダーから日付を取得する「date-time-picker」を導入してみた

最近Angularを利用した開発をしているのですが、その中で利用していた `date-time-picker` というパッケージの差し替えを行ったので記録として残しておきたいと思います。
2020.03.23

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは!DA(データアナリティクス)事業本部 インテグレーション部の大高です。

最近Angularを利用した開発をしているのですが、その中で利用していた date-time-picker というパッケージの差し替えを行ったので記録として残しておきたいと思います。

▽具体的には以下のようなイメージのものになります。

また、実際の作業では移行をしましたが、既存コードとの絡みで複雑になるので、今回はスクラッチのプロジェクトへの導入をまとめてみたいと思います。

経緯

元々は下記のリポジトリのパッケージを利用していました。

ですが、下記のIssueにあるように開発がストップしてしまっているようです。

Angularのバージョンアップ作業(v8 to v9)を行っている中で、旧パッケージではAngular 9に対応されていなかったのですが、フォークされた新しいリポジトリではAngular 9への対応もしていたので、乗り換えをしてみました。

以下が新しいリポジトリです。

前提

Angularは 9.0.6 を利用しています。

$ ng --version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 9.0.6
Node: 12.13.0
OS: linux x64

Angular: 9.0.6
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.6
@angular-devkit/build-angular     0.900.6
@angular-devkit/build-optimizer   0.900.6
@angular-devkit/build-webpack     0.900.6
@angular-devkit/core              9.0.6
@angular-devkit/schematics        9.0.6
@ngtools/webpack                  9.0.6
@schematics/angular               9.0.6
@schematics/update                0.900.6
rxjs                              6.5.4
typescript                        3.7.5
webpack                           4.41.2

パッケージマネージャはyarnを利用しています。

$ yarn --version
1.22.4

導入してみる

では、パッケージのREADMEを見つつ、スクラッチのプロジェクトを作成して導入してみましょう。

プロジェクトの作成

まずはプロジェクトを作成します。

$ ng new hello-dtp
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? Sass   [ https://sass-lang.com/documentation/syntax#the-indented-syntax ]
CREATE hello-dtp/README.md (1025 bytes)
~省略~
CREATE hello-dtp/e2e/src/app.po.ts (301 bytes)
✔ Packages installed successfully.
    Successfully initialized git.

app.component.htmlを修正してテンプレートを削除し、下記のコードのみにしておきます。

<router-outlet></router-outlet>

パッケージの導入

angular-datetime-pickerをインストールします。

$ cd hello-dtp
$ yarn add @danielmoncada/angular-datetime-picker

styles.sassにcssをインポートします。

@import "~@danielmoncada/angular-datetime-picker/assets/style/picker.min.css"

app.module.tsを修正して、OwlDateTimeModuleOwlNativeDateTimeModuleモジュールを追加しておきます。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    OwlDateTimeModule,
    OwlNativeDateTimeModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

ここまで、一旦起動させようとすると2020/03/23現在ではエラーが起きています。

$ yarn start
~(略)~
ERROR in The target entry-point "@danielmoncada/angular-datetime-picker" has missing dependencies:
 - @angular/cdk/a11y
 - @angular/cdk/overlay
 - @angular/cdk/portal
 - @angular/cdk/keycodes
 - @angular/cdk/coercion
 - @angular/cdk/platform
 - moment

@angular/cdkmomentが必要なようですが、依存関係解決ができていないようです。追加します。

$ yarn add @angular/cdk moment

追加したら、再挑戦します。

$ yarn start
~(略)~
: Compiled successfully.

無事、コンパイルできたので実装に進みます。

コンポーネントの作成とルーティング設定

では、まずは簡単に表示させてみます。下記コマンドでコンポーネントを作成します。

$ ng generate component datetime-picker

コンポーネントを作成したらテンプレート側を下記のように修正し、ベーシックな物で実装します。

<input [owlDateTime]="dt1" [owlDateTimeTrigger]="dt1" placeholder="Date Time">
<owl-date-time #dt1></owl-date-time>

app-routing.module.tsにルーティング設定をして起動します。

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DatetimePickerComponent } from './datetime-picker/datetime-picker.component';


const routes: Routes = [
  {
    path: '',
    component: DatetimePickerComponent
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

と、エラーになりました。BrowserAnimationsModule が必要ですね。

ERROR Error: Found the synthetic listener @transformPicker.done. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.

以下で追加して、app.module.tsBrowserAnimationsModuleを追加します。

$ yarn add @angular/animations
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { DatetimePickerComponent } from './datetime-picker/datetime-picker.component';

import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker';

@NgModule({
  declarations: [
    AppComponent,
    DatetimePickerComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    OwlDateTimeModule,
    OwlNativeDateTimeModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

起動すると無事表示されました!

カレンダーを日本語化する

さて、ここまでで利用には問題ありませんが、カレンダー表示を日本語表示にしたいので、日本語化してみます。

日本語化をするには、下記に記載のとおりOWL_DATE_TIME_LOCALEにロケールを設定する必要があります。デフォルトでは、OWL_DATE_TIME_LOCALELOCALE_IDを利用するとのことなので、app.module.tsprovidersLOCALE_IDの設定をします。

NgPickDatetime | Localization and Formats

また、デフォルトではen-USのロケールデータしかないので、ja-JPのロケールデータも併せてインポートします。

Angular 日本語ドキュメンテーション - 国際化 (i18n)

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { registerLocaleData } from '@angular/common';
import localeJa from '@angular/common/locales/ja';
import { NgModule, LOCALE_ID } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { DatetimePickerComponent } from './datetime-picker/datetime-picker.component';

import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker';

registerLocaleData(localeJa);

@NgModule({
  declarations: [
    AppComponent,
    DatetimePickerComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    OwlDateTimeModule,
    OwlNativeDateTimeModule,
  ],
  providers: [
    {
      provide: LOCALE_ID,
      useValue: 'ja-JP'
    },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

これで日本語化もできました!

まとめ

以上、「date-time-picker」の紹介でした。Angular MaterialでもDatepicker は用意されていますが、こちらは日本語化もしやすく、時刻と併せて利用したい場合になかなか便利なパッケージなので、うまく利用していきたいと思います。

どなたかのお役に立てば幸いです。それでは!