kintone API

アンチパターンから学ぶ 条件書式の実装(一覧画面)

目次

はじめに

表形式の一覧画面で、期限切れのレコードを赤くハイライトしたり、特定の列だけ背景色を変えたりするカスタマイズを実装することがあります。 こうしたスタイル変更のカスタマイズには、一見動作しているように見えても、リスクを抱える実装パターンが存在します。

この記事では、一覧画面でレコード行や列のスタイルを変更するカスタマイズについて、以下の2つを解説します。

  • アンチパターンとそのリスク
    たとえば、DOM操作で一覧のテーブル要素を直接操作するカスタマイズは、ある日突然kintoneのUI刷新で動作しなくなるリスクや、レコードとDOM要素の対応が不確実になるといった課題を抱えています。
  • 推奨される実装方法とその利点
    スタイルを設定・取得するAPIを使用することで、レコードIDとフィールドコードで対象を特定し、DOM構造に依存しない安全なスタイル制御を可能にしたり、モバイル対応がしやすくなります。

アンチパターンと推奨される実装方法を、サンプルコードを交えて比較しながら紹介します。 既存のカスタマイズのリスク確認や、新たに実装する際の参考にしてください。

information

レコード画面のスタイル制御については、以下の記事を参照してください。
アンチパターンから学ぶ 条件書式の実装(詳細・編集・追加画面)

今回紹介するAPI

API 概要
kintone.app.setRecordListStyle() 表形式一覧のスタイルを設定
kintone.app.getRecordListStyle() 表形式一覧のスタイルを取得

次の画像は期限日を過ぎたレコードの期限日列にスタイルを適用し、赤く強調した例です。

この見た目を、DOM操作で実現する方法と、APIで実現する方法の2つのアプローチで比較します。

サンプルコードでは、以下のフィールドを使用しています。

フィールド名 フィールドコード フィールドタイプ
期限日 期限日 日付

アンチパターン1:querySelectorAll()のDOM操作による一覧のスタイル変更

一覧画面の行やセルにスタイルを適用する方法として、document.querySelectorAll()でテーブルのDOM要素を直接操作するパターンがあります。

warning
注意

以下のコードはAPIを使った実装に置き換えることが推奨される書き方です。
新規のカスタマイズでは、後述するsetRecordListStyle()を使用してください。

 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
// 非推奨: この書き方は setRecordListStyle() を使った実装への置き換えを推奨します
(() => {
  'use strict';

  kintone.events.on('app.record.index.show', (event) => {
    // テーブル行のDOM要素を直接取得
    const rows = document.querySelectorAll('.recordlist-row-gaia');
    rows.forEach((row, index) => {
      const record = event.records[index];
      if (!record) return;

      const deadline = new Date(record['期限日'].value);
      const today = new Date();

      if (deadline < today) {
        // 行内のセルから期限日の値を含む要素を探してスタイルを適用
        const cells = row.querySelectorAll('td');
        for (const cell of cells) {
          if (cell.textContent.includes(record['期限日'].value)) {
            cell.style.backgroundColor = '#ffcccc';
            cell.style.color = '#cc0000';
            cell.style.fontWeight = 'bold';
          }
        }
      }
    });

    return event;
  });
})();

このアプローチには以下のリスクがあります。

リスク 説明
DOM構造への完全な依存 .recordlist-row-gaiaのようなクラス名はkintoneが実装上の都合でつけた名前であり、外部からの利用を想定していません。
UIの刷新で予告なく変更される可能性があり、カスタマイズの動作が停止するリスクを伴います。
また、DOM要素のスタイルを直接変更することには以下のリスクもあります。
・kintoneの標準機能が動作しなくなる可能性がある
・イベントの発行タイミングでDOMが再描画された際に、適用したスタイルがリセットされる
レコードとDOM要素の対応が不確実 event.recordsの順序とDOM要素の順序は必ずしも一致するとは限りません。
要素とレコードの対応づけを自前で行う必要があり、誤った行にスタイルを適用してしまうリスクがあります。
列単位のスタイル制御が困難 特定のフィールド列だけにスタイルを適用するには、DOM構造を詳細に解析する必要があります。
解析ロジックが複雑になるにつれて、コードが難読化してバグが混入するリスクが高まります。
モバイル非対応 PC版とモバイル版ではDOM構造が異なるため、スタイル操作のコードを別途書く必要があります。
管理するコードが増えることで、保守コストの増大やバグが混入するリスクが高まります。

アンチパターン2:getFieldElements()のDOM操作による一覧のスタイル変更

一覧画面の行やセルにスタイルを適用する別の方法として、kintone.app.getFieldElements()でkintoneのDOM要素を直接操作するパターンもあります。

warning
注意

以下のコードはsetRecordListStyle()を使った実装に置き換えることが推奨される書き方です。
新規のカスタマイズでは、後述するsetRecordListStyle()を使用してください。

 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
// 非推奨: この書き方は setRecordListStyle() を使った実装への置き換えを推奨します
(() => {
  'use strict';

  kintone.events.on('app.record.index.show', (event) => {
    // getFieldElements()でフィールド列のDOM要素を取得
    const fieldElements = kintone.app.getFieldElements('期限日');
    if (!fieldElements) return event;

    fieldElements.forEach((element, index) => {
      const record = event.records[index];
      if (!record) return;

      const deadline = new Date(record['期限日'].value);
      const today = new Date();

      if (deadline < today) {
        element.style.backgroundColor = '#ffcccc';
        element.style.color = '#cc0000';
        element.style.fontWeight = 'bold';
      }
    });

    return event;
  });
})();

前述のアンチパターン1とは違い、クラス名に依存せずDOM要素を取得できます。
しかしながら、このアプローチには以下のリスクがあります。

リスク 説明
標準機能への悪影響 取得した要素の内部構造を直接変更すると、kintoneの標準機能が動作しなくなるリスクがあります。
今は動作していても、kintoneのアップデート後も動作するとは限りません。
スタイルの意図しないリセット イベントの発行タイミングでDOMが再描画された際に、適用したスタイルがリセットされるリスクがあります。
レコードとDOM要素の対応が不確実 getFieldElements()で取得した要素の順序とレコードの順序は必ずしも一致するとは限りません。
要素とレコードの対応づけを自前で行う必要があり、誤った行にスタイルを適用してしまうリスクがあります。

後述のsetRecordListStyle()を使った実装でこれらのリスクを回避できます。

推奨される実装方法:setRecordListStyle()による一覧スタイル制御

kintone.app.setRecordListStyle()を使用することで、レコードIDとフィールドコードを指定してスタイルを適用できます。
DOM要素の探索が不要になり、正確にスタイルを制御できます。

 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
(() => {
  'use strict';

  kintone.events.on('app.record.index.show', async (event) => {
    const today = new Date();
    const body = [];

    for (const record of event.records) {
      const deadline = new Date(record['期限日'].value);
      if (deadline < today) {
        body.push({
          recordId: record.$id.value,
          style: [{
            columnType: 'FIELD',
            column: '期限日',
            content: {
              color: '#cc0000',
              fontWeight: 'bold'
            },
            background: {
              backgroundColor: '#ffcccc'
            }
          }]
        });
      }
    }

    if (body.length > 0) {
      await kintone.app.setRecordListStyle({body});
    }

    return event;
  });
})();

DOM操作によるスタイル変更と比較して、以下の点が改善されています。

改善点 説明
DOM構造に依存しない レコードIDとフィールドコードでスタイルの対象を指定するため、kintoneのDOM構造の変更に影響を受けません。
レコードIDで行を確実に特定 DOM要素のインデックスではなくレコードIDで対象行を指定するため、誤ったスタイルの適用が起こりません。
列単位の柔軟なスタイル制御 フィールドコードや操作列(columnType: 'ACTION')を指定して、列ごとに個別のスタイルを適用できます。
PC/モバイルで統一されたAPI PC版はkintone.app.setRecordListStyle()、モバイル版はkintone.mobile.app.setRecordListStyle()です。
getRecordListStyle()も同様にモバイル版が用意されています。

スタイル設定APIの使い方

ここでは、setRecordListStyle()でできることをさらに詳しく説明します。設定できるプロパティの種類、スタイルの解除方法に加えて、getRecordListStyle()と組み合わせた使い方も紹介します。

setRecordListStyle()で設定できるプロパティ

setRecordListStyle()では、セルの内容(content)とセルの背景(background)の2つの領域に対してスタイルを設定できます。
指定可能なプロパティの詳細は、以下を参照してください。
setRecordListStyle()のAPIリファレンス

スタイルの適用の解除

各プロパティに'DEFAULT'を指定してスタイルを解除できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// 特定のプロパティだけ解除
await kintone.app.setRecordListStyle({
  body: [{
    recordId: '1',
    style: [{
      columnType: 'FIELD',
      column: '期限日',
      content: {
        color: 'DEFAULT' // 文字色だけ戻す
      }
    }]
  }]
});

// すべてのスタイルを一括で解除
await kintone.app.setRecordListStyle('DEFAULT');

getRecordListStyle()で現在のスタイルを確認する

getRecordListStyle()を使えば、setRecordListStyle()で適用した現在のスタイルを取得できます。
戻り値はheader(ヘッダー行)とbody(一覧本体)をもつオブジェクトです。

次のコードは、一覧画面にボタンを配置し、期限切れレコードのハイライト表示をオン・オフする例です。
getRecordListStyle()で取得した各レコードのbackground.backgroundColorを確認し、ハイライト済みかどうかを判定しています。

 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
(() => {
  'use strict';

  kintone.events.on('app.record.index.show', async (event) => {
    const headerSpace = kintone.app.getHeaderSpaceElement();
    if (!headerSpace || headerSpace.querySelector('#highlight-toggle')) {
      return event;
    }

    const button = document.createElement('button');
    button.id = 'highlight-toggle';
    button.textContent = 'ハイライト切替';
    button.style.cssText = 'margin:0 0 8px 45px;';
    button.onclick = async () => {
      const currentStyle = await kintone.app.getRecordListStyle();

      // いずれかのレコードにハイライトが適用されているか確認
      const isHighlighted = Array.isArray(currentStyle?.body) && currentStyle.body.some(
        (item) => item.style?.some(
          (s) => s.background?.backgroundColor &&
                 s.background.backgroundColor !== 'DEFAULT'
        )
      );

      if (isHighlighted) {
        await kintone.app.setRecordListStyle('DEFAULT');
      } else {
        const today = new Date();
        const body = [];

        for (const record of event.records) {
          const deadline = new Date(record['期限日'].value);
          if (deadline < today) {
            body.push({
              recordId: record.$id.value,
              style: [{
                columnType: 'FIELD',
                column: '期限日',
                content: {
                  color: '#cc0000',
                  fontWeight: 'bold'
                },
                background: {
                  backgroundColor: '#ffcccc'
                }
              }]
            });
          }
        }

        if (body.length > 0) {
          await kintone.app.setRecordListStyle({body});
        }
      }
    };

    headerSpace.appendChild(button);
    return event;
  });
})();

getRecordListStyle()の詳細は、以下を参照してください。
getRecordListStyle()のAPIリファレンス

実装時に押さえておきたいこと

APIを使用する際に知っておきたい制限事項、非同期処理やモバイル対応について案内します。事前に把握しておくことで、実装後のトラブルを未然に防げます。

APIの制限事項

対応する一覧の種類と指定可能なプロパティ

setRecordListStyle()には、利用できる一覧の種類やインライン編集時の挙動などの制約があります。
また、DOM操作では任意のCSSプロパティを設定できましたが、APIではcontentbackgroundの領域ごとに指定可能なプロパティが決まっています。
詳細は以下を参照してください。
一覧画面のスタイルの設定 - 制限事項

レコード画面のスタイル制御

setRecordListStyle()は表形式の一覧画面で使用するAPIです。
レコードの追加・編集・詳細画面でのスタイル制御にはsetFieldStyle()/getFieldStyle()を使用してください。
詳しくは以下の記事を参照してください。
アンチパターンから学ぶ 条件書式の実装(詳細・編集・追加画面)

非同期処理の活用について

setRecordListStyle()getRecordListStyle()は非同期なAPIです。
async/awaitを使用して処理してください。
詳しくは次のページを参照してください。

モバイル版での利用について

モバイル版ではkintone.mobile名前空間のAPIを使用してください。

PC版 モバイル版
kintone.app.setRecordListStyle() kintone.mobile.app.setRecordListStyle()
kintone.app.getRecordListStyle() kintone.mobile.app.getRecordListStyle()

まとめ

  • setRecordListStyle()で、DOM操作に頼らず一覧画面のスタイルを制御できます。
  • getRecordListStyle()で、現在のスタイルを取得し、トグルや条件分岐に活用できます。
  • レコードIDとフィールドコードで対象を特定するため、DOM構造への依存を排除し、kintoneのUI刷新に影響を受けない保守性の高いカスタマイズを実現できます。

一覧画面のスタイル制御APIを使用することで、kintoneカスタマイズの信頼性が向上します。
条件書式のカスタマイズでは積極的にこれらのAPIを活用してください。

information

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