フィールド編集後イベントで他フィールドの値をマスタより取得し、変更

お世話になっております。

実現したいこと:アプリ①の「app.record.index.edit.change.[フィールドコード]、app.record.edit.change.[フィールドコード]」イベントにて、下記を行いたいと思っています。

1.アプリ①のフィールドAを変更

2.アプリ②よりフィールドAに紐づく値Xを取得

3.アプリ①のフィールドBの値をXに変更

 

現状、手順2までは実装できているものの、手順3で躓いています。

おそらくapp.record.edit.change.[フィールドコード]イベントにてAPIを使用しているためpromiseが使用できず、return eventがうまく動作しないため値の変更が行われないと思うのですが、回避策等はあるのでしょうか。

それとも、app.record.index.edit.submitなどのイベントで代用するしかないのでしょうか。

ご教授願います。

 

m.uさん

お世話になっております。

kintone.app.record.set()でセットできるかと思います。
https://developer.cybozu.io/hc/ja/articles/201942014#step4

changeイベント時にはkintone.app.record.set()がそのままでは使用できません。
(You cannot call kintone.app.record.set() in handler or during processing a handler. のエラーが出ます)

ひとつの方法としてsetTimeoutでイベントのプロセスが終わってから実行するという手があります。
以下は数値フィールドが変更された場合にその数値のレコードIDを持つ担当者名を引っ張ってきて
文字列フィールドの値を変更する、というエラー処理もない適当なものですが、
基本的には作成されているソースをsetTimeoutの中に突っ込んで、return eventで更新しようとしていた値を
kintone.app.record.set()で返してあげればよいと思います。

kintone.events.on(['app.record.edit.change.数値', 'app.record.create.change.数値'], function (e) {
setTimeout(() => {
const data = kintone.app.record.get();
const id = data.record['数値'].value;
kintone.api(kintone.api.url('/k/v1/records.json', true), 'GET', { app: 887, query: `$id = "${id}"` }).then((res) => {
data.record['文字列'].value = res.records[0]['担当者名'].value;
kintone.app.record.set(data);
});
}, 0); // 0だけど先にプロセスが終わるのYou cannot call!と怒られなくなる
return e;
});

 

コメントいただきありがとうございます。

bz様のソースで試したところ、‘app.record.edit.change.フィールドコード’ イベントでは理想の動きを確認できました。

ありがとうございます。

ただ、’app.record.index.edit.change.フィールドコード’ イベントですとkintone.app.record.get()やkintone.app.record.set()使用できないようです。

こちらのイベントについては実装は難しいのでしょうか?

ご教授いただきたく存じます。

はい、こちらにあるようにkintone.app.record.get()もset()も

  • レコード詳細
  • レコード追加
  • レコード編集
  • レコード印刷

でしか使えません。
じゃあ「app.record.index.edit.change」中にAPI(kintone.api(kintone.api.url(‘/k/v1/record.json’, true), 'POST’~…)で
書き換えてやりゃあいいじゃん、と思うのですが、これができるんですが、できないのです。
というのも、edit.change発火時にAPIでレコードを書き換えることはできるのですが、書き換えたところで
それは裏側のデータが書き換わっただけで、一覧上の書き換えたいフィールドのinputの値は変わらないのです。
(なので保存するとまた書き換えたいフィールドの値は元に戻ってしまう)

ではどうするのかというと、これも非常に笑ってしまうぐらい強引な我流の方法ですが、
「edit.change」イベントは介さず、発火元のinputの値が書き換えられたタイミングで
書き換えたいフィールドのinputタグの値を変更してしまうのです。

// 発火元フィールドコード:数値
// 書き換えたいフィールドコード:文字列

// エンピツアイコンクリックしたらinputを監視
kintone.events.on('app.record.index.edit.show', function (e) {
const targetFields = kintone.app.getFieldElements('数値');
targetFields.forEach((field) => {
if (field.querySelector('input')) {
field.querySelector('input').addEventListener('change', function () {
const val = this.value; // inputの入力値
// ここで何らかの処理
const result = `hoge${val}`;
kintone.app.getFieldElements('文字列').forEach((field) => {
if (field.querySelector('input')) {
field.querySelector('input').value = result;
}
});
});
}
});
return e;
});

※フィールドIDを取得した方がスマートな感じがするかもですが、とりあえず動いたのでこれで提出

他に何かもっとよい方法があったらどなたか教えてください。

 

※m.uさんには説明不要だと思いますが、初心者の方のためにフォローしておきますと、
上記のように中でPromise処理などをしなくてよい普通の場合は、こうでよいのですからね。

kintone.events.on('app.record.index.edit.change.数値', function (e) {
e.record['文字列'].value = `hoge${e.record['数値'].value}`;
return e;
});

bz様

コメントいただきありがとうございます。

上記のソースで理想の動きが実現できました!

本当にありがとうございました。