kintoneのJavaScriptカスタマイズにおけるフィールド値変更時イベント（Changeイベント）の利用は最小限にしよう

[Cybozu Devnetコミュニティ](https://developer.cybozu.io/hc/ja/community/posts)で回答させていただくことが多いのですが、カスタマイズの傾向として、様々なイベントの中でも比較的Changeイベントが利用されがちであると認識しています。

ただ、私個人としては積極的にフィールド値変更時イベント（以降 Changeイベント）を使うのはあまりいい手ではないと思っています。
今回は、Changeイベントを使いすぎると良くない点と、改善案、Changeイベントを利用するべきシーンについて考えてみます。

Changeイベントについて詳細は[こちら](https://developer.cybozu.io/hc/ja/articles/201941984-%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E8%BF%BD%E5%8A%A0%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88#step3)
Changeイベントで気をつけること、という[記事](https://qiita.com/t_numata/items/bc6f302fc2664b47385f)もありましたので参考にどうぞ。

# Changeイベントをおすすめしない理由
## 1. あるフィールドを変更したとき、なにかが起こる（副作用が起こる）、ということは暗黙的で分かりづらい
郵便番号フィールドを編集すると、住所フィールドに反映させるようなカスタマイズをしたとしましょう。一見便利ですが、郵便番号を入れたからと言って住所にすぐ反映されてしまうこと作用があることは非常に暗黙的で、住所から入力をしたい場合などは上書きをしてしまうことになるので、使い方によっては不親切になってしまうことがあります。
Changeイベントを多様してしまうと、このフィールドを変更すると何がおこるのか？ということを意識する必要がでてきます。
![Notification_Center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31957/aa8ca4da-7323-f325-7c64-da7a16ee6d3c.png)

## 2. 必要以上に実行される可能性が高い（特にAPI）
値を変更するたびに処理が走ってしまいますので、外部通信・APIの利用や、重い処理などをしていると、UXとしてもよくないです。
## 3. 予想外のバグを産んでしまいがちでカスタマイズやデバッグのハードルが高くなる
軽い使い方ならば問題ありませんが、なんでもかんでもChangeイベントを利用していると、、、フィールドAが変わるとフィールドBに影響がある、フィールドBが変わるとフィールドCに影響がある、など、数珠つなぎになったり複雑になってきてしまい、予想外のことが起きたりデバッグやカスタマイズのハードルが上がります。
## 4. Promiseに対応していない
個人的にはやはりこれが大きいと思っており、Changeイベントだけ、Promiseに対応していません。そのため、外部APIやkintone REST APIの結果を待って何かをする、ということが非常にやりづらいです。
kintone.app.record.set()などでフィールドに反映することはできますが、小手先テクニックが必要になってきますし、細かい制御に難があります。
※参考：[Promise対応イベント一覧](https://developer.cybozu.io/hc/ja/articles/201941954-%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E5%87%A6%E7%90%86%E3%81%AE%E8%A8%98%E8%BF%B0%E6%96%B9%E6%B3%95)


# 改善案
## 1. 保存実行前イベント（以降 Submitイベント）などその他イベント駆使する
特にSubmitイベントは、JavaScriptカスタマイズにおいて下記の理由で都合がいいケースが多いです。
- 保存ボタンを押すときに必ず実行される
- フィールドのデータを操作できる
- Promiseに対応している
- 保存直前でデータのチェック（バリデーション）など、保存されたデータの正しさを担保できる etc

入力したデータをチェックしたかったり、フィールドAのデータによってフィールドBのデータを変更したい、などのカスタマイズはまさにSubmitイベントが適切でしょう。
保存時にデータを書き換える場合、アラートダイアログなどで明示的に利用者に何が起こるかも示すこともできます。（暗黙性を回避できる）

## 2. レコード作成画面表示イベントでボタンなどを設置して明示的にする
前述でもあった、郵便番号フィールドを住所フィールドに反映されるケースを考えてみましょう。この場合は、たしかに郵便番号を入れたタイミングで反映されてほしいタイミングもある（保存実行前ではおそすぎる）と思います。
そのような場合は、スペースフィールドなどを用いてボタンを設置し、それを押すことで住所が自動入力にされるようにするといいと思います。
利用者にとって何が起こるのか明示的ですし、郵便番号が間違っていた場合の制御なども非常にシンプルでやりやすくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31957/fa700149-da93-d5e8-5b89-a54b16f82f4d.png)


# Changeイベントを使うべきシーン
Changeイベントは下記のようなシーンでの利用が好ましいかと思います。
## 1. バリデーションを入力しているフィールドにエラーをリアルタイムに出したい
  保存直前前イベントは全体のフィールドのバリデーションとエラー表示は行なえますが、それだと入力が全て終わったあとになるのでエラーを表示するにはおそすぎて体験が悪くなる場合があります。その時はChangeイベントで細かく出すといいかと思います。ただし、保存直前でバリデーションするのはマストだと思いますので、バリデーションという意味ではSubmitイベントで、その体験を良くするという意味でChangeイベントを使うというニュアンスがいいと思います。
![kintoneでエラーメッセージを表示したり消したりする方法_-_Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31957/cdd9631f-f92a-0034-e29d-d18019d5a8fd.png)

## 2. フォームの見た目に関することなどフィールド・フォームの制御
  例えばラジオボタンで、選択したものに応じてその後のフィールドの表示制御を行いたいケースはまさにChangeイベントが向いています。

参考: [回答の条件によって別フィールドの表示/非表示を切り替える](https://developer.cybozu.io/hc/ja/articles/202377614)

![Notification_Center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31957/56b0c6e5-8199-5a41-f317-6ba909384522.png)

ただしこれも複雑にしすぎるとバグの温床となりますので、フォーム自体をシンプルにしたり並びに注意するほうがいいです。
また、表示されてないフィールドのデータをどうするか、などデータの制御に関してもChangeイベントでやるよりもSubmitイベントと分担するとよりよいとおもいます。
## 3. その他フィールドのデータに直接影響がないカスタマイズ
例えば入力した住所フィールドに入力したデータに応じて表示している地図の表示を変更する、などは直接データに影響がありませんのでわかりやすいカスタマイズだと思います。
このようにChangeフィールドをつかってもシンプルさを保てるカスタマイズであれば積極的に利用していいかと思います。

# そもそもなぜChangeイベントが使われがちなのか？
これも個人的な考えなのですが、おそらくExcelの代替としてkintoneを利用するなどで、 **リアルタイムに反映される感覚をExcelから持ち込んでいる** のではないかと思ってます。
その感覚は理解できますし、利用する利用者もそれを求めているケースもあると思います。
ただし、Excelであっても、あるデータを変えると他のデータが変わるということはあくまで式で表現されます。これはkintoneでは計算フィールドでやれます。（残念ながらExcelほど高機能ではなく足らない部分はありますが...）
Excel VBAの実行も基本的にはフォームやボタンが設置されていて、実行が明示的ではないでしょうか。同様に、kintoneもなにか作用があるものはボタンを設置するなどで利用者に示せばいいのではないかと思います。
そもそも **kintoneとExcelは違う製品** である、という前提に立つことも大事ですね。
![Notification_Center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31957/bada3bf9-c95d-ebad-ee0b-db55c76603b2.png)
参考: [簡単Excelマクロ入門！マクロボタンで作業を自動化：後編](https://www.hello-pc.net/howto-excel/macro_2/)

複雑なカスタマイズになってしまうのはもちろんChangeイベントに限らないず様々なケースがあります。なので、大変ではありますが利用者側にも理解をもらいつつ、よりシンプルに保つカスタマイズをしてメンテナンスコストを最小限にするのが大事です。（利用者と開発者の対話が必要）

# まとめ
Changeイベントを利用して、フィールドAを入力するとフィールドBやフィールドCが自動で入力される、というのは確かに体験としてはいいですし、カスタマイズのしがいもあると感じるでしょう。
ただし前述の通りその思惑がはまらない利用者の場合はおせっかいとなってしまったりバグの温床になったりと悪い側面もあるので、最低限にとどめ、これもボタンの設置やSubmitイベントに代替していくといいでしょう。
また、念の為ですが、ここで述べたいのは **「Changeイベントは悪」ということではなく、「コードはシンプルになるように保ちましょう、その一環としてChangeイベントは適材適所で利用しましょう」** という考えです。

あくまで個人の考えですので上記とは違うご意見や、他にもこういうのはChangeイベントに向いてる・向いてないなど何かあれば記事に反映させますのでぜひコメントいただければと思います🙏