kintone.events.onを効率化する

にメンテナンス済み

kintone JavaScript API の中でも、特に頻繁に利用するのがkintone.events.onです。

kintone.events.onは、kintone アプリケーションのイベントをフックして、カスタマイズを行うための関数です。

活用することで、「レコードを新規作成した時だけ〇〇を実行する」「レコードを編集した時だけ〇〇を実行する」といった、特定のタイミングでの処理を実装することができます。

しかし、kintone.events.onは、1 つのアプリに複数回登場することもあり、新しい機能を追加する上でまず初めに書かないといけないコードです。

頻繁に利用するものだからこそ、もっと効率的に書きたいと思ったことはないでしょうか。

このページではkintone.events.onを内包し、機能を代替する便利な関数の作り方・使い方を紹介します。

イベント登録を肩代わりする関数

今回定義する関数は以下です。IE でも動く記述方法と、新しい記述方法それぞれ用意しました。

// es5
/**
 * @param {{events: string[]; action: (event) => event}} configs
 */
function launch(configs) {
  for (var i = 0; i < configs.length; i++) {
    var config = configs[i];

    kintone.events.on(config.events, config.action);
  }
}

// esnext
/**
 * @param {{events: string[]; action: (event) => event}} configs
 */
const launch = (configs) => {
  for (const { events, action } of configs) {
    kintone.events.on(events, action);
  }
};

使い方

通常のイベント登録は以下のように行います。

kintone.events.on(['app.record.create.show', 'app.record.edit.show'], (event) => {
  console.log('レコード作成・編集時に実行されます');
  return event;
});

kintone.events.on(['app.record.index.show'], (event) => {
  console.log('レコード一覧で実行されます');
  return event;
});

前述した launch 関数の場合は以下のようになります。

const eventsA = ['app.record.create.show', 'app.record.edit.show'];
const actionA = (event) => {
  console.log('レコード作成・編集時に実行されます');
  return event;
};

const eventsB = ['app.record.create.show', 'app.record.edit.show'];
const actionB = (event) => {
  console.log('レコード一覧で実行されます');
  return event;
};

launch([
  { action: actionA, events: eventsA },
  { action: actionB, events: eventsB },
]);

launch 関数を使った場合は、複数のイベントタイプ・実行イベントのペアを配列として渡し、ひとまとめで実行することとなります。

ここまでだと書き方を変えただけでコードが長くなっていますし、何のメリットがあるのかまだ分かりづらいと思います。

まとめてモバイルに対応させる

先ほどの launch 関数を以下のように書き換えます。

/**
 * @param {{events: string[]; action: (event) => event}} configs
 */
const launch = (configs) => {
  for (const { events, action } of configs) {
    const mobileEvents = events.map((event) => 'mobile.' + event);

    kintone.events.on([...events, ...mobileEvents], action);
  }
};

const mobileEvents = events.map((event) => "mobile." + event);の部分を追加しています。

この 1 行を追加するだけで、launch から登録された全てのイベントを一括でモバイル版でも実行するよう変更できます。

まとめて実行可否を制御する

続いて、複数のイベントに対して共通する、実行可否を制御したい場合の記述方法です。

/**
 * @param {{events: string[]; action: (event) => event}} configs
 */
const launch = (configs) => {
  for (const { events, action } of configs) {
    const handler = (event) => (enables(event) ? action(event) : event);

    kintone.events.on(events, handler);
  }
};

const enables = (event) => {
  return event.record['valid'].value;
};

const handler = (event) => enables(event) ? action(event) : event;を追加しました。 関数 enables の結果によって、launch に登録された全てのイベントの実行可否が制御できます。 また、実行可否を判定する関数を引数にすることで、動的に制御することもできます。

まとめてエラー処理を行う

複数のイベントで共通するエラー処理が必要な場合は以下のように記述します。

/**
 * @param {{events: string[]; action: (event) => event}} configs
 */
const launch = (configs) => {
  for (const { events, action } of configs) {
    const handler = (event) => {
      try {
        action(event);
      } catch (error) {
        errorHandler(event, error);
      }
    };

    kintone.events.on(events, handler);
  }
};

const errorHandler = (event, error) => {
  console.error(`${event.record.$id.value}でエラーが発生しました`, error);
};

これによってすべてのイベント登録前にエラー処理で覆わなくても、launch に登録するだけで汎用的なエラー処理を実行することができます。 例えばエラー処理の中で kintone REST API を使用し、エラーログを別アプリに残す処理を入れておけば、作業者の報告が無くても発生したエラーを確認したりできます。

みなさんの kintone カスタマイズのお役に立てれば幸いです。 最後まで読んでいただき、ありがとうございました。

#kintone #javascript