関連レコード一覧フィールドは関連性が1:Nの場合は標準機能で設定できますが、テーブルの内容を条件とするような、関連性がN:Nの場合は標準機能で設定できません。
こちらのQ&Aの回答
のように詳細データのアプリを別個作成して対応するなどの方法もありますが、今回は、JavaScript APIを利用して関連レコード一覧のテーブルを作成、表示するカスタマイズ方法を説明したいと思います。
デモ環境で実際に動作を確認できます。
https://dev-demo.cybozu.com/k/295/
ログイン情報は
cybozu developer networkデモ環境
で確認してください。
kintoneアプリの作成
固定リンクがコピーされました
サンプルのアプリとして、学習塾クラスの管理アプリを作成します。
生徒管理アプリとクラス管理アプリを作成して、生徒管理アプリから複数のクラスをルックアップ選択し、クラス管理アプリでは、そのクラスに登録した生徒を一覧表示するように設定します。
1人の生徒が複数のクラスを選択でき、ひとつのクラスには複数の生徒が登録されるので、N:Nの関連性となります。
クラス管理アプリの作成
固定リンクがコピーされました
次の画像とテーブルを参考にクラス管理アプリを作成します。
フィールドの種類 |
フィールド名 |
フィールドコード |
備考 |
レコード番号 |
クラス番号 |
class_no |
|
文字列(1行) |
クラスコード |
class_code |
|
文字列(1行) |
クラス名 |
class_name |
|
スペース |
|
student_list |
テーブル表示スペース |
生徒管理アプリの作成
固定リンクがコピーされました
次の画像とテーブルを参考に生徒管理アプリを作成します。
フィールドの種類 |
フィールド名 |
フィールドコード |
備考 |
レコード番号 |
生徒番号 |
student_no |
|
文字列(1行) |
生徒コード |
student_code |
|
文字列(1行) |
氏名 |
student_name |
|
ルックアップ |
クラスコード |
class_code |
テーブル |
文字列(1行) |
クラス名 |
class_name |
テーブル |
作成した「クラス管理アプリ」に次のソースコードを参考にしたJavaScriptファイルを作成し、適用します。
テーブルのHTMLのクラス名は、kintoneのスタイルに調和するよう、
こちら
のプラグイン用スタイルシートを参考にしています。
こちらの
GitHub上のスタイルシート
をダウンロードし、アプリに反映してください。
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
|
/*
* N:N(複数対複数)の関連レコード一覧を自作する
* Copyright (c) 2022 Cybozu
*
* Licensed under the MIT License
*/
(() => {
'use strict';
kintone.events.on(['app.record.detail.show', 'app.record.edit.show'], (event) => {
const record = event.record;
const subAppId = '{生徒管理アプリID}';
// 増殖バグ回避
if (document.getElementById('student_list') !== null) {
return event;
}
// To HTML escape
const escapeHtml = (str) => {
return str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
};
// スペースを取得
const subtableSpace = kintone.app.record.getSpaceElement('student_list');
// Rest API
const params = {
app: subAppId,
query: `class_code in ("${record.class_code.value}") order by student_no asc limit 500`,
fields: ['$id', 'student_code', 'student_name']
};
kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then((resp) => {
// success:生徒一覧を表示する
const tableRecords = resp.records;
let studentTable = `<table class="kintoneplugin-table">
<thead>
<tr>
<th class="kintoneplugin-table-th" style="width: 250px;">
<span class="title">コード</span>
</th>
<th class="kintoneplugin-table-th" style="width: 250px;">
<span class="title">氏名</span>
</th>
</tr>
</thead>
<tbody>`;
for (let i = 0; i < tableRecords.length; i++) {
studentTable += `<tr>
<td>
<div class="kintoneplugin-table-td-control">
<a href="/k/${subAppId}/show#record=${escapeHtml(tableRecords[i].$id.value)}" target="_blank">
${escapeHtml(tableRecords[i].student_code.value)}
</a>
</div>
</td>
<td>
<div class="kintoneplugin-table-td-control">
${escapeHtml(tableRecords[i].student_name.value)}
</div>
</td>
</tr>`;
}
studentTable += `</tbody></table>`;
subtableSpace.innerHTML = studentTable;
}, (error) => {
// error:エラーの場合はメッセージを表示する
let errmsg = 'レコード取得時にエラーが発生しました。';
// レスポンスにエラーメッセージが含まれる場合はメッセージを表示する
if (typeof error.message !== 'undefined') {
errmsg += '\n' + error.message;
}
subtableSpace.appendChild(document.createTextNode(errmsg));
});
return event;
});
})();
|
レコード詳細表示およびレコード編集イベントのブロックに生徒一覧テーブル生成処理を記述します。
9
10
|
kintone.events.on(['app.record.detail.show', 'app.record.edit.show'], (event) => {
});
|
REST APIを使って、生徒管理アプリからクラス登録した生徒の情報を取得します。
なお、queryのパラメーターには、クラスコードが一致するレコードのみを取得するように指定します。
取得するフィールドは、レコード番号、「生徒コード」、「生徒氏名」となります。
27
28
29
30
31
|
// Rest API
const params = {
'app': subAppId,
'query': `class_code in ("${record.class_code.value}") order by student_no asc limit 500`,
'fields': ['$id', 'student_code', 'student_name']
|
レコードの取得が成功した場合に生徒一覧のテーブルを生成します。
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then((resp) => {
// success:生徒一覧を表示する
const tableRecords = resp.records;
let studentTable = `<table class="kintoneplugin-table">
.
.
.
<tbody>`;
for (let i = 0; i < tableRecords.length; i++) {
studentTable += `<tr>
.
.
.
</tr>`;
}
studentTable += `</tbody></table>`;
subtableSpace.innerHTML = studentTable;
|
生徒コードをクリックすると該当の生徒レコードを表示するようにリンクを設定します。
52
53
54
|
<a href="/k/${subAppId}/show#record=${escapeHtml(tableRecords[i].$id.value)}" target="_blank">
${escapeHtml(tableRecords[i].student_code.value)}
</a>
|
取得した生徒レコードから、「氏名」を表示します。
なお、クロスサイトスクリプティングの対策として、特殊文字をエスケープ処理しています。
「生徒管理アプリ」、「クラス管理アプリ」それぞれにいくつかデータを入力します。
生徒管理アプリから、いくつかクラスをルックアップで登録し、「クラスアプリ管理」上に生徒一覧のテーブルが表示されていることを確認します。
こちらのQ&Aの回答
にあるように詳細アプリを作成して、標準機能で対応も可能です。
しかし、JavaScript APIでカスタマイズすれば、わざわざ詳細データ設定用のアプリを作成しなくて済みます。
コード自体も意外とシンプルですので、ぜひ試してみてください。