kintoneで本日時点での年齢を計算する

kintoneを使ってメンバー管理をしたいということになりましたが，なぜかkintoneでは本日時点での年齢を計算できないので，いろいろな記事を参考にjavascriptで実装しました．登録手順を忘れてしまわないように手順をまとめておきます．

### 前提条件

+ アルゴリズムについては参考情報の考え方を流用しています
+ 「生年月日」フィールド（文字列）に登録された生年月日を取得し，「年齢」フィールド（計算）に結果を表示します
+ フォーム，一覧のいずれでもエラーなく動くようにします
+ 登録時の年齢は「基準日付」をもとに計算します

### 参考情報

https://www.messiahworks.com/archives/4554

https://developer.cybozu.io/hc/ja/articles/202640900-%E7%B5%8C%E9%81%8E%E5%B9%B4%E6%95%B0%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B

### 環境整備

一度登録したJavascriptファイルをkintone上で編集できるようにするプラグイン「JSEdit for kintone」．登録後に修正したい場合にはとても便利です．

https://developer.cybozu.io/hc/ja/articles/205452613-kintone%E4%B8%8A%E3%81%A7%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0JS%E3%82%84CSS%E3%82%92%E7%B7%A8%E9%9B%86%E3%81%A7%E3%81%8D%E3%82%8B%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3-JSEdit-for-kintone-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86

### フォームを作成

kintoneで下記のフォームを作成します．
![生年月日と年齢.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268426/dea1d02d-11dc-e087-d558-91469dab93b1.png)

なお，年齢の「計算式」にはあらかじめ

```
(基準日付-生年月日)/86400/365
```

を登録してあります．

### 年齢計算Javascriptファイルの作成

年齢計算の関数については，参考情報にある関数の内容を入れます．

```autocalc_age.js
// 20210331 年齢自動計算
// 以下のページを参考に修正．
// https://www.messiahworks.com/archives/4554

(function() {

  // 生年月日が入っているフィールドコード名
  const BIRTHDAY_FIELD_NAME = '生年月日';
  // 年齢を設定するフィールドコード名
  // (基準日付-生年月日)/86400/365
  const AGE_FIELD_NAME = '年齢';

  "use strict";

  // 現在の年齢計算する関数
  function getYearMonth(arg_yyyy_mm_dd) {
    // 参考ページのロジックをコピー
  }

  // フォームへの表示
  kintone.events.on(['app.record.detail.show'], function (event) {
    var record = event.record; // 保存前の画面上のレコード

    // 生年月日
    var emBirthDay = kintone.app.record.getFieldElement(BIRTHDAY_FIELD_NAME);

    // 年齢
    var emAge = kintone.app.record.getFieldElement(AGE_FIELD_NAME);

    // 年齢を表示するためのラベルを生成
    var emLabel = document.createElement("label");
    var emDiv = document.createElement("span");
    emAge.appendChild(emDiv);
    emDiv.appendChild(emLabel);

    // 年齢文字列を取得
    var valBirthday = getYearMonth(record[BIRTHDAY_FIELD_NAME]['value']);

    // 年齢の設定
    emLabel.appendChild(document.createTextNode("（" + valBirthday + "歳）"));

    return event;
  });

  // レコード一覧表示
  kintone.events.on(['app.record.index.show'], function (event) {
    //0件Hit対策
    if (!event.size){
      return;
    }

    // レコード配列をローカル変数に格納
    var records = event.records;

    // 年齢列を取得
    var emAge = kintone.app.getFieldElements(AGE_FIELD_NAME);

    // レコード数の分だけループ
    for (var i = 0; i < records.length; i++) {
      var record = records[i];

      // 値の取得
      var record_data = record[BIRTHDAY_FIELD_NAME]['value'];

      if( record_data !== '' && emAge !== null ){
        // DOM要素の取得し、年齢を追加
          var part = emAge[i];
          part.innerHTML = "<DIV><SPAN>（" + getYearMonth(record_data) + "歳）</SPAN></DIV>";
      }
    }

    return event;
  });

})();
```

### kintoneへの登録

初回は，「Javascript/CSSでカスタマイズ」から今作成したファイルを登録します．
PC用のJavascriptファイルとスマートフォン用のJavaScriptファイルが分かれているので，
それぞれに対して「アップロードして追加」を選択して登録します．

![kintone_カスタマイズ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268426/f55a132a-32d9-71e3-9170-c0f3ae021559.png)

![autocalc追加.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268426/8300ee9c-5245-32f7-aa74-3a911b2d4a4b.png)

画面左上の「保存」ボタンを押すと，JavaScriptが登録されます．

### 画面上の表示

一覧では計算した年齢のみ，フォームでは，登録時の（基準日に対する）年齢と計算した年齢を両方表示します．

１．一覧での表示
![一覧での年齢表示.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268426/c7c23f81-604e-4672-f875-261a58cc5e74.png)

２．フォームでの表示
![フォームでの年齢表示.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268426/11e3c349-95f6-4dcb-841f-63bdef4c36c5.png)

### 登録済みのJavascriptファイルの編集

「プラグイン」画面から，JSEdit for Kintoneの設定を開くと，編集画面が出てきます．
いちいち登録しなくても良いので，非常に便利です．

![JSEdit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268426/ea00ea70-1079-16b7-4a97-53d1db8e49cb.png)

![JSEdit編集画面.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268426/5e8bdaf4-d599-3ed0-a330-c872017a03b9.png)