0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

kintone でテーブルを変えたら自動で再計算し、結果の欄を編集不可にする(change イベントと disabled)

0
Posted at

やりたいこと

kintone の見積アプリで、

  • テーブルの数量や単価を変えたら、その場で行の金額と合計を計算し直したい
  • 計算結果の欄(金額・合計・消費税)は、人が書き換えられないようにしたい

計算フィールドで足りない(端数の処理が細かい、テーブルの外に合計を出したい、など)ときに、JavaScript で同じことをする書き方です。建設向けの見積書プラグインのコードで説明します。どのフィールドを使うかは、プラグインの設定(config)から読んでいます。

1. 見張るイベントを配列で並べる

kintone.events.on には、イベント名の 配列 を渡せます。作成・編集の「表示」「保存」と、決まったフィールドの「変更」をまとめて1つの関数に向けます(kintone/estimate/src/js/desktop.js)。

  var watched = [config.table, config.qty, config.price, config.rateField, config.welfare, config.discount].filter(Boolean);
  var editEvents = ['app.record.create.show', 'app.record.edit.show', 'app.record.create.submit', 'app.record.edit.submit'];
  watched.forEach(function(code) {
    editEvents.push('app.record.create.change.' + code, 'app.record.edit.change.' + code);
  });
  kintone.events.on(editEvents, recalc);

ポイントは4つあります。

  • change イベントは、フィールドコードごとに名前が決まる。 app.record.edit.change.数量 のように、見張るフィールドの数だけ並べます。フィールドコードを設定で選ぶプラグインでは、設定を読んでから配列を組み立てます。
  • テーブル自身のコードも入れる。 テーブルのフィールドコードの change イベントは、行を足したとき・消したときに起きます。行を消したら合計を減らしたいので、config.table も見張ります。テーブルの中の 数量 や 単価 の change は、セルを変えたときに起きます。
  • 設定で使わない(空の)ものは filter(Boolean) で外す。 空のコードで app.record.edit.change. という名前を登録しないためです。
  • show と submit でも計算する。 開いたときに古い値が入っていても直り、保存の直前にもう一度計算するので、計算前の値で保存されません。

2. 計算して、event.record に書き戻す

イベントの関数は event.record を書き換えて、event を返します。返した event の内容が画面に反映されます。

  function apply(record) {
    if (!record[config.table]) return record;
    var result = calc(record);
    if (config.amount) {
      result.lines.forEach(function(line) {
        var cell = line.row.value[config.amount];
        if (cell) cell.value = line.amount === null ? '' : String(line.amount);
      });
    }
    OUTPUTS.forEach(function(key) {
      var field = config[key] && record[config[key]];
      if (field) field.value = String(result[OUT_KEYS[key]]);
    });
    lockOutputs(record);
    return record;
  }

  function recalc(event) {
    apply(event.record);
    return event;
  }
  • テーブルの行は record[テーブル].value の配列で、1行は row.value[フィールドコード] です。行の金額は、その行のセルに直接入れます。
  • 数値フィールドに入れる値は 文字列 にします(String(...))。計算できなかった行は空文字にします。
  • calc の中身(小数の誤差を出さない計算)は別の記事にまとめました。

3. 結果の欄を編集不可にする:disabled

書き戻した欄は、人が上書きできないように disabled = true にします。

  // ---- 作成と編集の画面:計算結果をフィールドに入れる ----
  function lockOutputs(record) {
    OUTPUTS.forEach(function(key) {
      if (config[key] && record[config[key]]) record[config[key]].disabled = true;
    });
    if (config.amount && record[config.table]) {
      record[config.table].value.forEach(function(row) {
        if (row.value[config.amount]) row.value[config.amount].disabled = true;
      });
    }
  }

テーブルの中の欄は 行ごと に disabled を付けます。行を足したとき(テーブルの change)にも apply → lockOutputs が走るので、新しい行の金額の欄もすぐ編集不可になります。

4. 一覧の行内編集を忘れない

一覧の画面でも、鉛筆のボタンからその場で編集できます。ここを見落とすと、計算結果の欄を一覧から書き換えられてしまいます。

  // 一覧の行内編集。テーブルが届かないときは計算しない
  kintone.events.on('app.record.index.edit.show', function(event) {
    lockOutputs(event.record);
    return event;
  });
  kintone.events.on('app.record.index.edit.submit', recalc);
  • app.record.index.edit.show で、結果の欄を編集不可にします。
  • app.record.index.edit.submit で、保存の前に計算し直します。

行内編集の event.record にはテーブルが入っていないことがあります。そのため apply の頭で if (!record[config.table]) return record; として、何もせずに返しています。原価管理のプラグインでは、この場合も結果の欄を編集不可にしてから返しています(kintone/genka/src/js/desktop.js)。

  function apply(record) {
    // 一覧の行内編集などでテーブルが届かないときは、書き込み先を0にしないよう何もしない
    if (!record[config.table] || !record[actualTable]) {
      lockOutputs(record);
      return record;
    }
    // (中略)
  }

テーブルが届かないまま計算すると、合計が0になって保存されてしまいます。「届かないなら書かない」が安全側です。

5. 設定が済んでいなければ何もしない

ファイルの頭で、必要な設定がそろっていなければすぐ抜けます。

  var config = kintone.plugin.app.getConfig(PLUGIN_ID) || {};
  if (!config.table || !config.name || !config.qty || !config.price) return;

イベントを登録する前に抜けるので、設定前のアプリの画面には何も起きません。

まとめ

  • kintone.events.on にはイベント名の配列を渡せる。change はフィールドコードごとに並べ、テーブル自身のコードも入れる(行の追加・削除)。
  • event.record の値は文字列で書き戻し、event を返す。結果の欄は disabled = true。テーブルの中は行ごと。
  • 一覧の行内編集(index.edit.show / index.edit.submit)も同じように扱う。テーブルが届かないときは書かない。

ソースと配布先

この記事のコードは、建設向けの無料の kintone プラグイン「見積書作成プラグイン」の一部です。

※ kintone はサイボウズ株式会社の登録商標です。このプラグインと記事は、サイボウズ株式会社の公式のものではありません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?