LoginSignup
47
25

More than 5 years have passed since last update.

Angular Material の "Datepicker" の見た目と戦う

Posted at

Angular Material で Datepicker を使おうとした時のお話です。
Angular 自体は 4 です。

Datepicker の Document は以下。
https://material.angular.io/components/datepicker/overview

デフォルトだと以下の絵のように <input> に表示されるテキストが M/d/yyyy になるようです。
更に曜日の表記も馴染みがない。
この見た目を変更するべく調査したのです。

20170928120737_e.png

まずは、デフォルト状態

<md-form-field>
  <input mdInput [mdDatepicker]="picker" placeholder="Choose a date">
  <md-datepicker-toggle mdSuffix [for]="picker"></md-datepicker-toggle>
  <md-datepicker #picker></md-datepicker>
</md-form-field>

そのままコピペしたわけですが、
最初の絵のように普通に使える Datepicker なのですが、
<input> に表示されるテキストが M/d/yyyy になっています。

フォーマットを変えたい!
何かフォーマットを指定する手段はないものか?

ロケールを指定

  import { Component, OnInit } from '@angular/core';
+ import { DateAdapter, NativeDateAdapter } from '@angular/material';

  @Component({
    selector: 'datepicker-example',
    templateUrl: './datepicker-example.component.html',
    styleUrls: ['./datepicker-example.component.css']
  })
  export class DatepickerExampleComponent implements OnInit {

-   constructor() {
+   constructor(dateAdapter: DateAdapter<NativeDateAdapter>) {
+     dateAdapter.setLocale('de-DE');
    }

    ngOnInit() {
    }
  }

最初に見つけたのはロケール指定。
日本っぽいカレンダーになってくれるだろうか?
ということで早速やってみる。
もちろん dateAdapter.setLocale('ja'); である。

20170928120834e.png

こんな感じの絵になった。
yyyy/M/d のようであるが良い感じだ。
曜日も 日 月 火... と良い感じだ。
ついでに Year の表記も SEP 2017 から 2017年9月 に、
Month の表記も SEP から 9月 に変わって日本らしくなった。

しかし、全部の日にちに "日" が付いている・・・。
なんとも気持ち悪い。
(執筆時には見慣れてて気持ち悪さ半減しておりましたが...)

これより先を弄るとなると Provider を上書きしてやる必要がありそうです。
https://material.angular.io/components/datepicker/overview#customizing-the-date-implementation
https://material.angular.io/components/datepicker/overview#customizing-the-parse-and-display-formats
https://material.angular.io/components/datepicker/overview#localizing-labels-and-messages

とりあえず Google Developer Tools

20170930222520.png

mat-calendar-body-cell-content か...

calendar-body っぽいところを探す

https://github.com/angular/material2/blob/master/src/lib/datepicker/calendar-body.html#L42
にありました。

どうやら {{item.displayValue}} が、実際の値を表示しているようです。

これを追っていくと...

@Input() ということは、どこかで設定している人がいるはず!

mat-calendar-body の [rows] を探す

https://github.com/angular/material2/blob/master/src/lib/datepicker/month-view.html#L9
にいました。

次は _weeks だ!
さっきと同じく ts 側にいるはずだ!

_weeks を探す

https://github.com/angular/material2/blob/master/src/lib/datepicker/month-view.ts#L171
ここで値を突っ込んでいました。

おもむろに console.log(dateNames[i]) をしてみると...

CHIBI: 1日
CHIBI: 2日
CHIBI: 3日
CHIBI: 4日
CHIBI: 5日

それっぽい!
dateNames[i] の代わりに適当な文字列を入れてみても...

20170928120834.png

これだ...!!

dateNames は以下のコードで取得されている。
https://github.com/angular/material2/blob/master/src/lib/datepicker/month-view.ts#L157

DateAdapter が出てきた。
さっきさらっと流した Provider 上書きの出番!
https://material.angular.io/components/datepicker/overview#customizing-the-date-implementation

Provider 上書き

  import { Component, OnInit } from '@angular/core';
  import { DateAdapter, NativeDateAdapter } from '@angular/material';

+ class MyDateAdapter extends NativeDateAdapter {
+   getDateNames(): string[] {
+     const dateNames: string[] = [];
+     for (let i = 0; i < 31; i++) {
+       dateNames[i] = String(i + 1);
+     }
+     return dateNames;
+   }
+ }

  @Component({
    selector: 'datepicker-example',
    templateUrl: './datepicker-example.component.html',
    styleUrls: ['./datepicker-example.component.css'],
+   providers: [
+     {provide: DateAdapter, useClass: MyDateAdapter}
+   ]
  })
  export class DatepickerExampleComponent implements OnInit {


    constructor(dateAdapter: DateAdapter<NativeDateAdapter>) {
      dateAdapter.setLocale('ja');
    }

    ngOnInit() {
    }
  }

:tada::tada::tada:

20170928120928.png

最後にmemo

上記 Stack Overflow を見ると MD_DATE_FORMATS をいじったり
NativeDateAdapter の format() をオーバーライドしたりしている。
いまいち良くわからないまま試してみたものの、上手くいかず今回の方法に落ち着きました。

何かしら使うかもしれないので、とりあえずリンクだけ残す。
特に format は yyyy/MM/dd な形式にするときに使いそうだ。

47
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
47
25