kintoneのプラグインを作るとき、動作そのものよりも先に詰まりやすいのが設定画面です。プラグインは「アプリごとに設定を持てる」のが素のJavaScriptカスタマイズとの一番の違いですが、その設定画面は自分でHTMLとJavaScriptを用意して作る必要があります。用意された部品があるわけではないので、最初は何をどこに書けばいいのか分かりにくいところです。
この記事では、テキストを1つ保存するだけの最小構成を作りながら、設定値がどう保存されてどう読み出されるのかを確認します。
ファイル構成
src/
├── manifest.json
├── html/
│ └── config.html
├── js/
│ ├── config.js
│ └── desktop.js
└── css/
├── 51-modern-default.css
└── config.css
51-modern-default.css はサイボウズが配布しているプラグイン用のスタイルシートで、これを読み込むとkintoneの標準設定画面に近い見た目になります。自分でCSSを書かなくてもボタンや入力欄が整うので、最初は入れておくのがおすすめです。
manifest.jsonで設定画面を宣言する
config に、設定画面のHTMLと、そこで読み込むJS・CSSを書きます。
{
"manifest_version": 1,
"version": "1.0.0",
"type": "APP",
"name": { "ja": "サンプルプラグイン", "en": "Sample Plugin" },
"description": { "ja": "設定画面のサンプルです。", "en": "Config sample." },
"icon": "image/icon.png",
"config": {
"html": "html/config.html",
"js": ["js/config.js"],
"css": ["css/51-modern-default.css", "css/config.css"]
},
"desktop": {
"js": ["js/desktop.js"]
}
}
config.js に書いたJavaScriptは設定画面でだけ動き、desktop.js はレコード画面で動きます。この2つは別世界で、共通しているのは「同じ設定値を読める」ことだけです。
config.html
<html> や <body> は書きません。設定画面の中に埋め込まれる断片として書きます。
<section class="settings">
<h2 class="settings-heading">サンプルプラグインの設定</h2>
<p class="kintoneplugin-desc">
レコード画面に表示するメッセージを入力してください。
</p>
<div class="kintoneplugin-row">
<label for="message">表示メッセージ</label>
<input type="text" id="message" class="kintoneplugin-input-text">
</div>
<div class="kintoneplugin-row">
<button id="save" class="kintoneplugin-button-dialog-ok">保存</button>
<button id="cancel" class="kintoneplugin-button-dialog-cancel">キャンセル</button>
</div>
</section>
kintoneplugin- で始まるクラスが、先ほどの 51-modern-default.css で定義されているものです。
config.js
ここが本体です。ポイントは、プラグインIDを引数で受け取る形で書くことです。
(function (PLUGIN_ID) {
'use strict';
// 保存済みの設定を読み込む
var config = kintone.plugin.app.getConfig(PLUGIN_ID);
var messageEl = document.getElementById('message');
messageEl.value = config.message || '';
// 保存
document.getElementById('save').addEventListener('click', function () {
var value = messageEl.value.trim();
if (!value) {
alert('メッセージを入力してください。');
return;
}
kintone.plugin.app.setConfig({ message: value });
});
// キャンセル
document.getElementById('cancel').addEventListener('click', function () {
history.back();
});
})(kintone.$PLUGIN_ID);
kintone.$PLUGIN_ID は設定画面でだけ参照できるグローバル変数で、そのプラグイン自身のIDが入っています。これを即時関数の引数として渡すのが定番の書き方です。
setConfig() を実行すると、保存後に自動でアプリの設定画面に戻ります。第2引数にコールバックを渡すと自動遷移せず自分で処理を続けられますが、最小構成では不要です。
desktop.js から読む
保存した値は、レコード画面側からも同じ方法で取り出します。
(function (PLUGIN_ID) {
'use strict';
var config = kintone.plugin.app.getConfig(PLUGIN_ID);
kintone.events.on('app.record.detail.show', function (event) {
console.log(config.message);
return event;
});
})(kintone.$PLUGIN_ID);
設定画面と同じ getConfig() を使うだけです。ここが繋がっていることを確認できれば、設定画面まわりは理解できたと言っていいと思います。
ハマりどころ
設定値は文字列しか保存できない
これが最初の関門です。setConfig() に渡すオブジェクトの値は、すべて文字列である必要があります。配列やオブジェクトを保存したい場合は JSON.stringify() で文字列にしてから渡し、読むときに JSON.parse() で戻します。
// 保存
kintone.plugin.app.setConfig({ items: JSON.stringify(list) });
// 読み込み
var list = config.items ? JSON.parse(config.items) : [];
真偽値も同様で、true ではなく 'true' として保存されます。読み出すときに config.enabled === 'true' と比較する必要があるので、うっかり if (config.enabled) と書くと文字列 'false' が真になって混乱します。
保存しただけでは反映されない
setConfig() は設定を保存するだけで、アプリには適用されません。アプリ設定画面に戻ったあと「アプリを更新」を押して初めて動作に反映されます。設定を変えたのに挙動が変わらないときは、だいたいこれです。
フィールド一覧を取るときはプレビュー環境のAPIを使う
設定画面でフィールドを選ばせたい場合、フィールド情報の取得先に注意が必要です。運用環境のAPIだと、まだ「アプリを更新」していない変更が反映されていません。設定画面で扱うなら、プレビュー環境側を見るほうが実態に合います。
kintone.api(
kintone.api.url('/k/v1/preview/app/form/fields', true),
'GET',
{ app: kintone.app.getId() }
).then(function (resp) {
console.log(resp.properties);
});
設定が空のときを考慮する
初回インストール直後、getConfig() は空のオブジェクトを返します。プロパティに直接アクセスすると undefined になるので、必ずデフォルト値を用意してください。設定項目が増えてきたら、読み込み処理を関数にまとめてデフォルト値を1か所で管理すると楽になります。
おわりに
設定画面は、getConfig() と setConfig() の2つだけ理解すれば形になります。あとは保存する値が文字列に限られることさえ押さえておけば、項目が増えても同じやり方で拡張できます。
この設定画面を実際に使ったプラグインを作るまでの経緯は、noteのほうに書いています。