kintoneにおけるテーブル操作の基本(テーブルの構造・行の追加)

目次

はじめに

kintoneで便利なテーブルですが、JavaScriptカスタマイズで取得して操作する場合は、入れ子構造が深く複雑になります。
本記事では、テーブルの構造と行の追加方法について解説します。
行の更新方法や削除方法については、次の記事を参照してください。

テーブルの操作の方法

テーブルの構造

テーブルがどのような構造になっているかを図に示しました。
特に、テーブルのオブジェクトの中には3階層にわたってvalueがあるので注意してください。

実際のオブジェクトを示すとこのようになります。(テーブル以外のフィールドは省略)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
  "テーブル": {
    "type": "SUBTABLE",
    "value": [
      {
        "id": "1923",
        "value": {
          "行番号": {
            "type": "NUMBER",
            "value": "1"
          },
          "テキスト": {
            "type": "SINGLE_LINE_TEXT",
            "value": "サンプルテキスト1"
          },
          "チェックボックス": {
            "type": "CHECK_BOX",
            "value": [
              "チェック1"
            ]
          }
        }
      },
      {
        "id": "1925",
        "value": {
          "行番号": {
            "type": "NUMBER",
            "value": "2"
          },
          "テキスト": {
            "type": "SINGLE_LINE_TEXT",
            "value": "サンプルテキスト2"
          },
          "チェックボックス": {
            "type": "CHECK_BOX",
            "value": [
              "チェック2"
            ]
          }
        }
      }
    ]
  }
}

サンプルアプリ:テーブル操作

JavaScriptカスタマイズでテーブルの操作ができるサンプルアプリを、デモ環境で公開しています。

デモ環境

デモ環境で実際に動作を確認できます。
https://dev-demo.cybozu.com/k/313/ (External link)

ログイン情報は cybozu developer networkデモ環境で確認してください。

このアプリでは、「追加」「更新」「削除」ができます。

  • 追加ボタンを押したとき:「追加_テキスト」「追加_チェックボックス」フィールドの値をテーブルに追加する。
  • 更新ボタンを押したとき:「更新_行番号」で指定したテーブルの対象の「テキスト」フィールドを「更新_テキスト」「更新_チェックボックス」で更新する。
  • 削除ボタンを押したとき:「削除_行番号」で指定したテーブルの対象の行を削除する。

デモアプリのサンプルコード

デモアプリのサンプルコードは次のとおりです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
 * テーブル操作のサンプルコード
 * Copyright (c) 2024 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */
(() => {
  'use strict';
  kintone.events.on(['app.record.create.show', 'app.record.edit.show'], (e) => {

    // 追加ボタンを設置
    const addSpace = kintone.app.record.getSpaceElement('addSpace');
    const addButton = document.createElement('button');
    addButton.innerHTML = '追加';
    addButton.onclick = addRow;
    addSpace.appendChild(addButton);

    // 更新ボタンを設置
    const updateSpace = kintone.app.record.getSpaceElement('updateSpace');
    const updateButton = document.createElement('button');
    updateButton.innerHTML = '更新';
    updateButton.onclick = updateRow;
    updateSpace.appendChild(updateButton);

    // 削除ボタンを設置
    const deleteSpace = kintone.app.record.getSpaceElement('deleteSpace');
    const deleteButton = document.createElement('button');
    deleteButton.innerHTML = '削除';
    deleteButton.onclick = deleteRow;
    deleteSpace.appendChild(deleteButton);
    return e;
  });

  // 行追加関数
  const addRow = () => {
    const record = kintone.app.record.get().record;
    const addText = record.追加_テキスト.value;
    const addCheckBox = record.追加_チェックボックス.value;
    record.テーブル.value.push({
      value: {
        行番号: {
          value: '',
          type: 'NUMBER',
        },
        テキスト: {
          value: addText,
          type: 'SINGLE_LINE_TEXT',
        },
        チェックボックス: {
          value: addCheckBox,
          type: 'CHECK_BOX',
        }
      }
    });
    resetRowNo(record);
    kintone.app.record.set({record: record});
  };

  // 行更新関数
  const updateRow = () => {
    const record = kintone.app.record.get().record;
    const updateText = record.更新_テキスト.value;
    const updateCheckBox = record.更新_チェックボックス.value;
    const targetRowNo = record.更新_行番号.value;
    record.テーブル.value.forEach((row) => {
      if (row.value.行番号.value === targetRowNo) {
        row.value.テキスト.value = updateText;
        row.value.チェックボックス.value = updateCheckBox;
      }
    });
    resetRowNo(record);
    kintone.app.record.set({record: record});
  };

  // 行削除関数
  const deleteRow = () => {
    const record = kintone.app.record.get().record;
    const targetRowNo = record.削除_行番号.value;
    record.テーブル.value.forEach((row, i) => {
      if (row.value.行番号.value === targetRowNo) {
        record.テーブル.value.splice(i, 1);
      }
    });
    resetRowNo(record);
    kintone.app.record.set({record: record});
  };

  // 行番号更新関数
  const resetRowNo = (record) => {
    record.テーブル.value.forEach((row, i) => {
      row.value.行番号.value = i + 1;
    });
  };
})();

行を追加するサンプルコード

本記事ではデモアプリのサンプルコードから、テーブルの行を追加するサンプルコードを抜き出して紹介します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
 * テーブル操作(行追加)のサンプルコード
 * Copyright (c) 2024 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */
(() => {
  'use strict';
  kintone.events.on(['app.record.create.show', 'app.record.edit.show'], (e) => {

    // 追加ボタンを設置
    const addSpace = kintone.app.record.getSpaceElement('addSpace');
    const addButton = document.createElement('button');
    addButton.innerHTML = '追加';
    addButton.onclick = addRow;
    addSpace.appendChild(addButton);

    return e;
  });

  // 行追加関数
  const addRow = () => {
    const record = kintone.app.record.get().record;
    const addText = record.追加_テキスト.value;
    const addCheckBox = record.追加_チェックボックス.value;
    record.テーブル.value.push({
      value: {
        行番号: {
          value: '',
          type: 'NUMBER',
        },
        テキスト: {
          value: addText,
          type: 'SINGLE_LINE_TEXT',
        },
        チェックボックス: {
          value: addCheckBox,
          type: 'CHECK_BOX',
        }
      }
    });
    resetRowNo(record);
    kintone.app.record.set({record: record});
  };

  // 行番号更新関数
  const resetRowNo = (record) => {
    record.テーブル.value.forEach((row, i) => {
      row.value.行番号.value = i + 1;
    });
  };
})();

JavaScriptカスタマイズ全体の構成

このJavaScriptカスタマイズは、「テーブルの行追加」部分と「スペースフィールドにボタンを設置する」部分に分かれます。
今回は「テーブルの行追加」について解説しますので、「スペースフィールドにボタンを設置する」方法は次の記事を参考にしてください。

レコード詳細画面にボタンを配置してみよう

スペースフィールドにボタンを設置する処理
12
13
14
15
16
17
    // 追加ボタンを設置
    const addSpace = kintone.app.record.getSpaceElement('addSpace');
    const addButton = document.createElement('button');
    addButton.innerHTML = '追加';
    addButton.onclick = addRow;
    addSpace.appendChild(addButton);
テーブルの行を追加する処理
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  // 行追加関数
  const addRow = () => {
    const record = kintone.app.record.get().record;
    const addText = record.追加_テキスト.value;
    const addCheckBox = record.追加_チェックボックス.value;
    record.テーブル.value.push({
      value: {
        '行番号': {
          value: '',
          type: 'NUMBER',
        },
        'テキスト': {
          value: addText,
          type: 'SINGLE_LINE_TEXT',
        },
        'チェックボックス': {
          value: addCheckBox,
          type: 'CHECK_BOX',
        }
      }
    });
    resetRowNo(record);
    kintone.app.record.set({record: record});
  };
テーブルの行番号を更新する処理
47
48
49
50
51
52
  // 行番号更新関数
  const resetRowNo = (record) => {
    record.テーブル.value.forEach((row, i) => {
      row.value.行番号.value = i + 1;
    });
  };

以下に、それぞれの部分ごとに解説をします。

ボタン設置部分

ここでは、スペースフィールドへのボタン設置と、ボタン押下時の設定をそれぞれいれています。
下記は「追加ボタン」の後続に宣言している「行追加」の関数を指定しています。

1
addButton.onclick = addRow();

行追加処理

テーブルは配列で表現されていますので、JavaScriptでいうと配列の最後に値を追加する処理を書きます。
配列に行を追加するにはpush()を使います。
push()の中にはテーブルの行に相当するvalueを指定します。
このとき、テーブル内のすべてのフィールドのフィールドコードやtype, valueも指定する必要があります。

テーブルへ1行追加するためのコード(例)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
record.テーブル.value.push({
  value: {
    '行番号': {
      value: 1,
      type: 'NUMBER',
    },
    'テキスト': {
      value: 'テキスト本文',
      type: 'SINGLE_LINE_TEXT',
    },
    'チェックボックス': {
      value: ['チェック1'],
      type: 'CHECK_BOX',
    }
  }
});
行追加のイメージ

サンプルアプリのコードの行追加部分の解説

前述の例のとおりpush()をつかって行を追加します。
このサンプルでは、追加/更新/削除すべてのタイミングでresetRowNo()という関数を呼んで行番号をリセットしています。
詳しくは 行番号リセット処理で説明します。

record取得と追加する行にセットするための値を代入する
24
25
26
    const record = kintone.app.record.get().record;
    const addText = record.追加_テキスト.value;
    const addCheckBox = record.追加_チェックボックス.value;
push()で行を追加する

このとき、すべてのフィールドのvalue/typeを指定する必要があります。

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    record.テーブル.value.push({
      value: {
        '行番号': {
          value: '',
          type: 'NUMBER',
        },
        'テキスト': {
          value: addText,
          type: 'SINGLE_LINE_TEXT',
        },
        'チェックボックス': {
          value: addCheckBox,
          type: 'CHECK_BOX',
        }
      }
    });
行番号には空文字を指定する

行追加の直後に行番号を更新するため、行番号には空文字を指定します。

29
30
31
32
        '行番号': {
          value: '',
          type: 'NUMBER',
        },
行番号を更新する関数(後述)
43
    resetRowNo(record);
ここまでの変更内容をrecordに反映させる
44
    kintone.app.record.set({record: record});

行番号リセット処理

サンプルアプリでは追加/更新/削除どの関数を使っても毎回最後に行番号をリセットしています。
行番号更新と削除と同じようにforEach()で繰り返し処理をして、番号を書き換えています。
リセット処理は各追加/更新/削除関数で呼ばれるため、recordデータは引数に渡しています。

47
48
49
50
51
52
  // 行番号更新関数
  const resetRowNo = (record) => {
    record.テーブル.value.forEach((row, i) => {
      row.value.行番号.value = i + 1;
    });
  };

補足

保存時に処理を実行させたい場合

サンプルアプリでは、編集画面でボタンを押したときに動作するものなので、 レコードの値を取得する レコードに値をセットするを利用しています。
保存時に処理を実行させる場合は、 レコード編集画面で保存するときのイベントを使って引数eventに渡されるrecordを編集すればOKです。

.forEach() などの繰り返し処理について

通常のfor文よりも、forEach()map()reduce()などの繰り返し処理が便利ですので、下記リンクを参考にしてください。
forEach, map, filterなどをつかってkintoneのrecords配列をもっと上手に扱う (External link)

information

このTipsは、2024年9月版kintoneで動作を確認しています。