こちらは 「ステップで学ぶ kintone カスタマイズ勉強会」 kintone devCamp Step2 ~kintone JavaScript API~ の復習コンテンツです。
🍙 はじめに
Step2 では最低限のセキュリティ対策について、 kintone JavaScript API による画面操作を勉強しました。
この記事では、Step2 の講義中に出てきた 用語 や 基本構文 のおさらいができるプチ用語集/問題集となっています。
🍙 目次
- 重要用語
- 理解度 Check!
- 演習問題
- 問題① (難易度:⭐⭐)
- 問題② (難易度:⭐⭐⭐)
- ステップアップ情報
🍙 重要用語
Step2 で出てきた重要な用語になります。これらの意味・用途はきちんと抑えておきましょう!
- app.record.○○.✕✕
- kintone.events.on();
- kintone のイベントオブジェクト
- イベントオブジェクトの操作
- イベントオブジェクトを返すとは
- 最低限のセキュアコーディング
- 即時関数
- 厳格モード
- ライブラリ
app.record.◯◯.✕✕
kintone 独自のイベント
kintone での画面操作を判断することができるイベント。
イベントの例
-
app.record.index.show
- アプリの一覧画面を開いた時
-
app.record.create.show
- レコードの追加画面を開いた時
-
**app.record.create.change.<フィールドコード>**
- レコードの追加画面にて、<フィールドコード>のフィールドの値を変更した時
-
app.record.create.submit
- レコードの追加画面にて、保存ボタンを押した時
※ 他にも様々なイベントが用意されているので、都度 kintone JavaScript API 一覧 を確認しましょう。
kintone.events.on();
kintone 用のイベント呼び出し関数
kintone 独自のイベントで何か処理をしたい場合に利用する。
利用例
- アプリの一覧画面を開いた時に処理をする
const showMessage = () => {
console.log('アプリの一覧画面を開いたね。');
};
kintone.events.on('app.record.index.show', showMessage);
- アプリの編集画面にて、保存ボタンを押した時
const showMessage = () => {
console.log('レコードを保存しようとしたね。');
};
kintone.events.on('app.record.edit.submit', showMessage);
kintoneのイベントオブジェクト
kintone 独自のイベントで渡される kintone 独自のオブジェクト
アプリの情報やレコードの情報を使いたい場合に利用することができる。
kintone のイベントオブジェクトの例
- app.record.index.show でのイベントオブジェクト
type: "app.record.index.show"
appId: 100
viewType: "list"
viewId: 20
viewName: "(すべて)"
records: Array(2)
0: {レコード番号: {…}, 更新者: {…}, 作成者: {…}, 更新日時: {…}, 作成日時: {…}, …}
1: {レコード番号: {…}, 更新者: {…}, 作成者: {…}, 更新日時: {…}, 作成日時: {…}, …}
length: 2
offset: 0
size: 2
date: null
- app.record.detail.show でのイベントオブジェクト
type: "app.record.detail.show"
appId: 100
recordId: 1
record:
レコード番号: {type: "RECORD_NUMBER", value: "1"}
更新者: {type: "MODIFIER", value: {…}}
作成者: {type: "CREATOR", value: {…}}
更新日時: {type: "UPDATED_TIME", value: "2020-02-06T04:27:00Z"}
作成日時: {type: "CREATED_TIME", value: "2020-02-06T04:27:00Z"}
文字列__1行_: {type: "SINGLE_LINE_TEXT", value: "cybozu"}
ドロップダウン: {type: "DROP_DOWN", value: "sample1"}
$revision: {type: "__REVISION__", value: "1"}
$id: {type: "__ID__", value: "1"}
※ イベントごとに受け取るオブジェクトの中身は異なるので、都度 console.log();
で確認すると良いです。
イベントオブジェクトの操作
- フィールドの値を書き換える
- フィールドの編集可/不可を設定する
- フィールドにエラーを表示する
- 画面上部にエラーを表示する
- ルックアップの取得を自動で行う
イベントオブジェクトを返すとは
イベントオブジェクトを操作した場合、そのイベントオブジェクトを kintone に返すことで画面上に反映されます。
最低限のセキュアコーディング
Step2 の講義では大きく2つのコーディングルールについて触れました。
その他、細かい注意事項については下記を参照してください。
▼ セキュアコーディングガイドライン
https://developer.cybozu.io/hc/ja/articles/201919400
即時関数
関数の定義と呼び出しが同時に実行される関数
定義する変数の影響範囲を、その即時関数内に制限することができる。
即時関数の利用例
- 即時関数を使うことで、別ファイルで定義している変数は読み取れない
- 影響範囲を自ファイルだけに制限できる
(() => {
const message = 'おはよう!';
console.log(message);
// -> おはよう!
})();
(() => {
console.log(message);
// -> Uncaught ReferenceError: message is not defined
})();
- 即時関数がないと、別ファイルで定義している変数が読み取れてしまう
const message = 'おはよう!';
console.log(message);
// -> おはよう!
console.log(message);
// -> おはよう!
kintone は複数の JavaScript ファイルを適用したり、複数のプラグインを適用することができるため、JavaScript 同士が 干渉(競合) する可能性があります。
予期せぬトラブルを避けるために、基本的には 即時関数 を使うようにすると良いです。
厳格モード
より的確なエラーチェックが行われる
今までエラーにならないような曖昧な実装がエラー扱いになり、潜在的な問題を発見しやすくなる。
厳格モードの利用例
- 変数定義をせずに変数を利用する場合
// 厳格モードなしの場合
message = 'おはよう!';
console.log(message);
// -> おはよう!
// (正常に動く)
// 厳格モードありの場合
'use strict';
message = 'おはよう!';
console.log(message);
// -> Uncaught ReferenceError: message is not defined
// (エラーが出て処理が止まる)
きちんと変数定義 const
を利用すると厳格モードありでも正常に動作する
// 厳格モードありの場合
'use strict';
const message = 'おはよう!';
console.log(message);
// -> おはよう!
// (正常に動く)
プログラム中に use strict;
と記載することで、以降の処理が厳格モードとなります。
※ use strict;
より前に記載したプログラムには厳格モードは適用されません。
こちらも、予期せぬトラブルを避けるために、基本的には 厳格モード を使うようにすると良いです。
ライブラリ
汎用性の高い複数のプログラムを再利用可能な形でひとまとまりにしたもの
ライブラリを使うことで「よく使う処理だが毎回一から作成するのは面倒」な処理を楽に書くことができる。
ライブラリの例
-
Day.js
- 日付の処理がしやすくなるライブラリ
-
chart.js
- グラフを描画しやすくなるライブラリ
- devnet Tips: Chart.js を使ってレーダーチャートを表示する
-
SweetAlert
- 美しいアラート画面を作成できるライブラリ
- devnet Tips: SweetAlert を使って、メッセージをスタイリッシュに表示させよう!
Cybozu CDN では、他にも様々なライブラリを提供しています。
🍙 理解度 Check!
Step2 講義の理解度を確認するための簡単な問題を用意しました。
頭の中でどんなプログラムを書けばよいかぱっと思いつくことができればOKです!
アプリの一覧画面でアラート表示
アプリの一覧画面を開いたときに「Hello World」とアラートを出すプログラムは・・・
答え(ここをクリックすると表示されます)
(() => {
'use strict';
const showMessage =() => {
window.alert('Hello World!');
}
kintone.events.on('app.record.index.show', showMessage);
})();
こちらの書き方でも可
(() => {
'use strict';
kintone.events.on('app.record.index.show', () => {
window.alert('Hello World!');
});
})();
レコード追加画面で初期値の挿入①
レコードの追加画面を開いたときに、文字列1行フィールド(フィールドコード:text)に
Hello World! という文字を挿入するプログラムは・・・
答え(ここをクリックすると表示されます)
(() => {
'use strict';
// 関数名はなんでも良いですが、通常は中の処理を表すものにします。
const setText = (event) => {
event.record.text.value = 'Hello World!';
return event;
}
kintone.events.on('app.record.create.show', setText);
})();
レコード追加画面で初期値の挿入②
レコードの追加画面を開いたときに、日付フィールド(フィールドコード:date)に
今月末の日付 を挿入するプログラムは・・・
答え(ここをクリックすると表示されます)
- Day.js を使う場合
// (別ファイル・URLとして Day.js ライブラリの適用を忘れずに)
(() => {
'use strict';
const setEndOfMonth = (event) => {
const now = dayjs();
const result = now.endOf('month').format('YYYY-MM-DD');
event.record.date.value = result;
return event;
};
kintone.events.on('app.record.create.show', setEndOfMonth);
})();
- Day.js を使わない場合
(() => {
'use strict';
const setEndOfMonth = (event) => {
// 今日の日付の取得
const now = new Date();
const nowYear = now.getFullYear();
const nowMonth = now.getMonth() + 1;
// 今月末の日付の取得
const monthEnd = new Date(nowYear, nowMonth, 0);
const monthEndYear = monthEnd.getFullYear();
const monthEndMonth = monthEnd.getMonth() + 1;
const monthEndDate = monthEnd.getDate();
const result = monthEndYear + '-' + monthEndMonth + '-' + monthEndDate;
event.record.date.value = result;
return event;
};
kintone.events.on('app.record.create.show', setEndOfMonth);
})();
🍙 演習問題
講義中に触れた内容に近い演習問題を用意しました。
これらの問題を難なく解くことができれば、Step2 の理解はもうばっちりです!
問題① (難易度:⭐⭐)
案件管理アプリにて、
「提案プラン」フィールドを 「Cプラン」 にすると、「オプション」フィールドが未選択になり編集不可となる
考え方
- イベントは何か
- 提案プランフィールドの値をどうやって取得するのか
- 「◯◯の場合、✕✕」という分岐をどうやって JavaScript で書くのか
- オプションフィールドの値を空にする方法は何か
ヒント
ヒント(ここをクリックすると表示されます)
-
イベントは何か
- レコード編集画面で提案プランを変更したときなので
app.record.edit.change.提案プラン
となる
- レコード編集画面で提案プランを変更したときなので
-
提案プランフィールドの値をどうやって取得するのか
- イベントオブジェクト内にあるものを利用する
- 提案プランフィールドの値は
event.record.提案プラン.value
となる
- 提案プランフィールドの値は
- イベントオブジェクト内にあるものを利用する
-
「◯◯の場合、✕✕」という分岐をどうやって JavaScript で書くのか
-
if文 を利用する
- 「変数 text の中身が cybozu の場合」という条件は
text === 'cybozu'
となる
- 「変数 text の中身が cybozu の場合」という条件は
-
if文 を利用する
-
オプションフィールドの値を空にする方法は何か
- オプションフィールドはチェックボックスのため、配列 というデータ構造で保存されている
-
Xオプションにチェックが入っている 場合、データ構造は
event.record.オプション.value === ['Xオプション']
となる
-「空にする = 空の配列を代入する」と考えると、event.record.オプション.value === [];
と表せる
-
Xオプションにチェックが入っている 場合、データ構造は
- オプションフィールドはチェックボックスのため、配列 というデータ構造で保存されている
if文
条件分岐を行うときのJavaScriptの記法
ある値に対して処理を分岐させたいときに利用します。今後必ず使うといって良いほど頻出の記法なのでここで覚えてしまいましょう!
if文の基本形は、
if (条件) {
// その条件にマッチした場合の処理
} else {
// それ以外の場合の処理
}
となります。例えば、数値を格納する変数 num
が 80以上かそれ未満かで分岐する場合は、
if (num >= 80) {
// numが80以上の場合
window.alert('80以上です');
} else {
// numが80以上ではない = 80未満の場合
window.alert('80未満です');
}
となります。3つ以上の分岐の場合は else if
を利用します。
if (条件①) {
console.log('条件①にマッチしたときに実行されるよ');
} else if (条件②) {
console.log('条件①にはマッチしないけど条件②にマッチしたときに実行されるよ');
} else if (条件③) {
console.log('条件①②にはマッチしないけど条件③にマッチしたときに実行されるよ');
} else {
console.log('条件①②③にはマッチしないときに実行されるよ');
}
また、else がないパターンもあります。
if (条件) {
// 条件にマッチした場合の処理
console.log('条件に合ったときに実行されるよ');
}
// 常に実行される処理
console.log('条件に関わらず常に実行されるよ');
答え
答え(ここをクリックすると表示されます)
const checkOption = (event) => {
const plan = event.record.提案プラン.value;
if (plan === 'Cプラン') {
event.record.オプション.value = [];
event.record.オプション.disabled = true;
} else {
event.record.オプション.disabled = false;
}
return event;
};
kintone.events.on('app.record.edit.change.提案プラン', checkOption);
else
の処理を書かないと提案プランをCプランから他のプランに変更したときに、オプションフィールドが編集不可のままになってしまうので要注意です。
問題② (難易度:⭐⭐⭐)
案件管理アプリにて、
レコード編集画面で保存ボタンを押したときに、
提案プランが「Aプラン」かつプラン費用が「0」だった場合、プラン費用フィールドの下部にエラーを出す
考え方
- イベントは何か
- 提案プランフィールド、プラン費用フィールドの値をどうやって取得するのか
- 「◯◯の場合、✕✕」という分岐をどうやって JavaScript で書くのか
- プラン費用フィールドの下側にエラーを出す方法は何か
ヒント
ヒント(ここをクリックすると表示されます)
-
イベントは何か
- レコード編集画面で保存ボタンを押したときなので
app.record.edit.submit
となる
- レコード編集画面で保存ボタンを押したときなので
-
提案プランフィールド、プラン費用フィールドの値をどうやって取得するのか
- イベントオブジェクト内にあるものを利用する
- 提案プランフィールドの値は
event.record.提案プラン.value
となる - プラン費用フィールドの値は
event.record.プラン費用.value
となる
- 提案プランフィールドの値は
- イベントオブジェクト内にあるものを利用する
-
「◯◯の場合、✕✕」という分岐をどうやって JavaScript で書くのか
- if文 を利用する
- 複数の条件を組み合わせる場合は
&&
||
を利用する-
&&
: かつ。 変数 text が cybozu、かつ変数 num が 100 の場合text === 'cybozu' && num === 100
-
||
: または。変数 text が cybozu、または kintone の場合text === 'cybozu' || text === 'kintone'
-
-
プラン費用フィールドの下側にエラーを出す方法は何か
-
event.record.<フィールドコード>.error = <エラーメッセージ内容>
と書くことでフィールドの下部にエラーメッセージを表示できる- https://developer.cybozu.io/hc/ja/articles/202166270#step6
- 今回は「プラン費用」フィールドなので、
event.record.プラン費用.error = 'Aプランの時は必須です。';
となる
-
答え
答え(ここをクリックすると表示されます)
const showError = (event) => {
const plan = event.record.提案プラン.value;
const money = event.record.プラン費用.value;
if (plan === 'Aプラン') {
if (!money || money === "0") { // プラン費用フィールドの値が「空の場合」と「0の場合」の両方を条件にする
event.record.プラン費用.error = 'Aプランの時は必須です。';
return event;
}
}
};
kintone.events.on('app.record.edit.submit', showError);
また、if文を1つにまとめることもできます。
const showError = (event) => {
const plan = event.record.提案プラン.value;
const money = event.record.プラン費用.value;
if (plan === 'Aプラン' && (!money || money === "0")) {
event.record.プラン費用.error = 'Aプランの時は必須です。';
return event;
}
};
kintone.events.on('app.record.edit.submit', showError);
🍙 ステップアップ情報
お疲れ様でした!復習はできましたでしょうか?
まだ難しいところはたくさんあると思いますが、わからないことはcybozu developer networkの記事をみたり、コミュニティを活用したりしながら引き続き頑張っていきましょう!
他にも予習・復習にお使いいただけるコンテンツがありますので、ぜひチャレンジしてみてください
cybozu developer network はじめようシリーズ
- kintone API 編(全12回)
cybozu developer network Tips
最後まで読んでいただきありがとうございました!
それではまた次回👋