kintoneのチェックボックスのチェックされた順番を取得してみた

# はじめに

お久しぶりです。
今年に入って記事をまだ1本も書いていないってことに気づき、
「おっとこれはまずいな・・・」ってことで記事を書きます 笑

今回のネタは初心に戻ってkintoneオンリーカスタマイズの
**「チェックボックスのチェックされた順番を取得する」** です。

> チェックボックス `A|B|C` を `B→C→A`の順にチェックした、とかを取得したい！
> （おそらくどこかではニーズがありそう）

ただ、kintoneカスタマイズでのイベントオブジェクトでは、
チェックボックスの配列はチェックされた順番に関係なく、設定順に格納されます。

> `B→C→A` の順でチェックを付けても、配列には `['A', 'B', 'C']` と格納される

イベントオブジェクトから順番が取得できないことになるので、ちょっとJSをゴニョっとして実装してみました。

# 今回作ったもの

![orderCheckbox.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153051/1cdc8a8e-5c4f-e153-4169-39bb1b8162a4.gif)
（GIFが早いw）

# プログラムのポイント

いくつか開発する上でポイントがあったのでまとめてみたいと思います。

まずフィールドコードは変数にまとめています。

```javascript
  const FIELDS = {
    CHECK_BOX: 'チェックボックス',
    TEXT1: '文字列1',
    TEXT2: '文字列2',
    TEXT3: '文字列3',
  }
```

## 1. チェックボックスの変更イベントで、チェックされた値を格納する

まずは今回のキモとなる部分から。
チェックボックスの変更イベントで変数に値を格納していくのですが、
上記にもあるようにkintoneのイベントオブジェクトはチェックした順番ではなく設定順に格納されるため、ちょっと工夫が必要です。
![理想.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153051/d78ea71d-2824-709c-ed0c-75a8b0b2cea3.png)

最初の1回目は普通に`Array.push`等で変数配列に追加すれば良いですが、
2回目のチェック時にそのままの処理だと `['sample2', 'sample1', 'sample2']`となってしまいます。

ということで、変数配列に値がなかったらpushするっていう処理を入れています。

```javascript
  let checkbox = [];
   
  kintone.events.on([
    `app.record.index.edit.change.${FIELDS.CHECK_BOX}`,
    `app.record.create.change.${FIELDS.CHECK_BOX}`,
    `app.record.edit.change.${FIELDS.CHECK_BOX}`,
  ], (event) => {
    event.record[FIELDS.CHECK_BOX].value.forEach((val) => {
      if (!checkbox.includes(val)) {
        checkbox.push(val);
      }
    });
  });
```

## 2. チェックを外したときの挙動を考慮

1.の処理でチェックをした順に変数配列に格納されるので動きとしてはいけてそうですが、
このままだとチェックを外したときに変数配列の中身がそのままになるのでちょっとおかしくなります。

ということで、次の処理として
`変数配列の中身でイベントオブジェクトのチェックボックスの中身と一致していないものは削除する`
という処理を入れます。

![理想2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153051/3b6e8800-d9c4-0fe9-96b4-7e9b9e73fbb1.png)


```javascript
// event.record[FIELDS.CHECK_BOX].value.forEach((val) => {
//   if (!checkbox.includes(val)) {
//     checkbox.push(val);
//   }
// });
  checkbox.forEach((val) => {
    if (!event.record[FIELDS.CHECK_BOX].value.includes(val)) {
      checkbox = checkbox.filter((v) => v !== val);
    }
  });
```

# 完成コード

ということで出来上がったコードはこちら。

```javascript
(() => {
  'use strict';

  const FIELDS = {
    CHECK_BOX: 'チェックボックス',
    TEXT1: '文字列1',
    TEXT2: '文字列2',
    TEXT3: '文字列3',
  }

  let checkbox = [];

  kintone.events.on([
    `app.record.index.edit.change.${FIELDS.CHECK_BOX}`,
    `app.record.create.change.${FIELDS.CHECK_BOX}`,
    `app.record.edit.change.${FIELDS.CHECK_BOX}`,
  ], (event) => {
    event.record[FIELDS.CHECK_BOX].value.forEach((val) => {
      if (!checkbox.includes(val)) {
        checkbox.push(val);
      }
    });

    checkbox.forEach((val) => {
      if (!event.record[FIELDS.CHECK_BOX].value.includes(val)) {
        checkbox = checkbox.filter((v) => v !== val);
      }
    });

    event.record[FIELDS.TEXT1].value = checkbox[0];
    event.record[FIELDS.TEXT2].value = checkbox[1];
    event.record[FIELDS.TEXT3].value = checkbox[2];
    return event;
  });
})();
```

# 追加開発

ちなみに、**チェックボックスの初期値でチェックが付いていたらどうなるの？** というのも思いついたので、
その場合はshowイベントの処理を入れればOKかと。

```javascript
  kintone.events.on(['app.record.create.show', 'app.record.edit.show'], (event) => {
    checkbox = event.record[FIELDS.CHECK_BOX].value;
    event.record[FIELDS.TEXT1].value = checkbox[0];
    event.record[FIELDS.TEXT2].value = checkbox[1];
    event.record[FIELDS.TEXT3].value = checkbox[2];
    return event;
  });
```

初期値で複数にチェックが入っている場合、そこに順番はないはずなので気にしない。

# おわりに

これ、意外と使えると思うんですよ。
**優先度順にチェックを付けてください** とかあると思うんですよ。

まぁ、その状況に遭遇したときに「あ、そういえば・・」てな感じで思い出してもらえると！
それでは！≧(+･` ཀ･´)≦