チェックボックスで選択したものをサブテーブルにセットする

kintoneでルックアップ。
1つルックアップするのはそんなに問題ないですが、
サブテーブル内などでたくさんルックアップしないといけないとき面倒だと思いませんか？

↓面倒かもしれないルックアップの作業
![d.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/5ca9137b-11fe-d2da-a2fb-2e2e1baf4f79.gif)

今回はそんなときに使えるかも知れないカスタマイズです。

# アプリの準備
マスタアプリとカスタマイズするアプリの2種類作りましょう。

## マスタアプリ

文字列(1行)フィールドと数値フィールドを設置しました。
重複禁止設定は不要です。

| フィールド種類 | フィールドコード |
|:-:|:-:|
| 文字列(1行)  | だんご  |
| 数値  | 確率  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/5753288c-63ec-bab3-2194-7d8a963bbd0b.png)

## カスタマイズするアプリ

| フィールド種類 | フィールド名 | フィールドコード |
|:-:|:-:|:-:|
| スペース  |  -- | spDango  |
| テーブル  | テーブル  | テーブル  |
| 文字列(複数行)  | 結果  | 結果  |

**テーブル内フィールド**

| フィールド種類 | フィールド名 | フィールドコード |
|:-:|:-:|:-:|
|文字列(1行)   | 注文しただんご  | だんご  |
|数値   | 確率  | 確率  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/617c9686-5f0b-1cdb-f2c8-281dff1757ec.png)


# JavaScript

まずはおなじみ、追加・編集画面表示イベント。
処理を書くところ～にコードを追記していきます。
非同期処理するので`async`をお忘れなく

```js
// 追加／編集画面表示
kintone.events.on(
  ["app.record.create.show", "app.record.edit.show"],
  async (event) => {

    // 処理を書くところ～

    return event;
  }
);
```

## マスタアプリからレコードを取得する
まずはだんごマスタからだんごの一覧をゲットしましょう。
一括取得には100件縛りはありますがひとまず100件超えしないのでそのまま取得してきます。

https://developer.cybozu.io/hc/ja/articles/202331474#step2

```js
// だんご一覧を取得
const resp = await kintone.api(
  kintone.api.url("/k/v1/records", true),
  "GET",
  { app: マスタアプリのID }
);
```

## スペースフィールドに取ってきたレコードの情報を表示する
次に、スペースフィールド内にマスタから取ってきただんごの情報を並べます。
`document.createElement()`でhtmlを書いている感じです。
もっとシンプルに書ける方法ないかな・・・。

```js
// スペースフィールド内にだんご一覧を作る
const spDango = kintone.app.record.getSpaceElement("spDango");
const dangoDiv = document.createElement("div");

// ボタン作成
const btn = document.createElement("button");
btn.textContent = "テーブルにセット";
dangoDiv.appendChild(btn);

// だんご一覧（チェックボックス付き）を作成
const dangoTable = document.createElement("table");
const dangoTBody = document.createElement("tbody");
// tbodyには、ボタンクリック時に必要になるのでidをつけておく
dangoTable.id = "dangoTBody";
// だんごの数分行<tr>を作る
resp.records.forEach((record) => {
  const fields = ["だんご", "確率"]; // マスタのフィールドコード
  const tr = document.createElement("tr");
  tr.id = record.レコード番号.value;
  const chktd = document.createElement("td");
  const chk = document.createElement("input");
  chk.type = "checkbox";
  chktd.appendChild(chk);
  tr.appendChild(chktd);
  fields.forEach((f) => {
    const td = document.createElement("td");
    const txt = document.createTextNode(record[f].value);
    td.appendChild(txt);
    tr.appendChild(td);
  });
  dangoTBody.appendChild(tr);
});
dangoTable.appendChild(dangoTBody);
dangoDiv.appendChild(dangoTable);
spDango.appendChild(dangoDiv);
```

## ボタンクリックイベント
次に、作成したボタンをクリックしたときの動きを作ります。
チェックした行のだんごをサブテーブルに追加します。

```js
// ボタンクリック
btn.addEventListener("click", (event) => {
  // レコードのフィールド値を取得
  const tbr = kintone.app.record.get();
  // だんご一覧のtbodyのオブジェクトをid指定で取得する
  const dtb = document.querySelector("#dangoTBody");
  // チェックしただんごを重複してサブテーブルに追加できないようにするにはココでクリアしておくとOK
  tbr.record.テーブル.value = [];
  // サブテーブルに追加する行
  const tmpRows = [];
  
  // HTMCollectionではforEachは動かないのでArray.prototype.forEach.callに変更
  Array.prototype.forEach.call(dtb.rows, (r, idx) => {
    if (r.cells[0].firstElementChild.checked) {// チェックのあるだんごを追加する
      // サブテーブルに追加する行を作成する
      const tmpRow = {
        id: null,
        value: {
          だんご: { type: "SINGLE_LINE_TEXT", value: resp.records[idx].だんご.value, },
          確率: { type: "NUMBER", value: resp.records[idx].確率.value, },
        },
      };
      tmpRows.push(tmpRow);
    }
  });
  // フィールド値を更新
  tbr.record.テーブル.value = tmpRows;
  // サブテーブルに反映
  kintone.app.record.set(tbr);
});
```

## おまけ要素
記事の主旨からは離れますが、乱数が確率より大きかったら発動！みたいな小ネタも実装してみました。

```js
// 保存
kintone.events.on(
  ["app.record.create.submit", "app.record.edit.submit"],
  async (event) => {
    if (event.record.テーブル.value.length > 0) {
      let memo = "🍡発動しただんごパワー🍡";
      event.record.テーブル.value.forEach((r) => {
        // 乱数が確率より大きかったら発動
        if (Number(r.value.確率.value) > Math.random() * 100) {
          memo = memo + "\n" + r.value.だんご.value + "パワー";
        }
      });
      event.record.結果.value = memo;
    } else {
      event.record.結果.value = "";
    }
    return event;
  }
);
```

# 動作確認 ＆ まとめ

このように一覧からチェックボックスで選択したものをサブテーブルに追加できます。
![dd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/61225f1a-966b-66d3-2f46-80e38b977b15.gif)

ルックアップの代わりにすることもできるかも！？
何かの参考になったらいいなぁ。