新規投稿
フォローする

レコードの同時編集を防止

kintoneでは、複数のユーザーが同時に1つのレコードを編集した場合、保存時にエラーが出るようになっています。

この機能によってレコードの先祖返りは防げますが、せっかく編集したレコードが保存できないのは残念ですよね。 今回は、複数のユーザーが同時に1つのレコード編集画面を開くこと自体を防ぐカスタマイズを紹介します。

サンプル

あるユーザーがレコード編集画面を開いているときには、ほかのユーザーがレコード編集画面を開けないようにします。

フォーム設定

アプリに以下のフィールドを追加します。

コード

下記「sample.js」を読み込みます。

・sample.js

(function () {
  "use strict";
  var revisionCheck = function (event) {
    return kintone.api(kintone.api.url('/k/v1/record', true), 'GET', {
      app: kintone.app.getId(),
      id: kintone.app.record.getId(),
    }).then(function (response) {
      return event.record.$revision.value === response.record.$revision.value;
    });
  };
  var changeState = function (editing) {
    return kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', {
      app: kintone.app.getId(),
      id: kintone.app.record.getId(),
      record: {
        編集中: {
          value: editing ? kintone.getLoginUser().id : 0
        }
      }
    });
  };
  kintone.events.on([
    'app.record.detail.show',
  ], function (event) {
    revisionCheck(event).then(function (revisionMatch) {
      if (!revisionMatch) location.reload();
    });
  });
  kintone.events.on([
    'app.record.edit.show',
  ], function (event) {
    revisionCheck(event).then(function (revisionMatch) {
      if (!revisionMatch) {
        location.reload();
        return;
      }
      if (Number(event.record.編集中.value)) {
        if (event.record.編集中.value !== kintone.getLoginUser().id) {
          alert('ほかのユーザーが編集中です.');
          history.back();
          return;
        }
        document.getElementsByClassName('gaia-ui-actionmenu-cancel')[0].addEventListener('click', function () {
          changeState(false).then(function () {
            location.reload();
          })
        })
        window.addEventListener('beforeunload', function (e) {
          changeState(false);
        });
        window.addEventListener('unload', function (e) {
          changeState(false);
        });
      } else {
        changeState(true).then(function () {
          location.reload();
        });
      }
    });
  });
  kintone.events.on([
    'app.record.edit.submit.success',
  ], function (event) {
    changeState(false);
  });
})();

※Chrome、Firefoxで動作確認しております。
※Chromeでは「beforeunload」イベントで編集中のフラグを除去しているため、ページ離脱をキャンセルした場合は正しく動作しません。(解決方法をご存じでしたら、ぜひ教えていただきたいです。)
※DOMのclass名を利用しているため、kintoneの仕様変更により動作しなくなる可能性があります。

5

1件のコメント

Avatar
奈良橋

江田 篤史 様

突然のご連絡失礼いたします。

「レコードの同時編集を防止」のサンプルプログラムを利用させていただいております奈良橋と申します。

当プログラムについて、お伺いしたいことが2点ございましたので、ご連絡させていただきました。

1点目:
レコード編集画面を開いた後に、その画面中にあるパンくずリストのいずれかの項目、あるいはホームボタン(ブラウザのホームボタンではございません)を押してkintoneの別ページに移動した後、当該レコードのレコード詳細画面、あるいはレコード一覧画面を開くと、当該レコードの編集中フィールドの値が、最後にレコード編集画面を開いた者のユーザIDとなっておりました。そのため、他のユーザーが当該レコードを編集することができませんでした。

コードの48~53行目にあるwindowオブジェクトの「beforeunload」「unload」イベントで、ブラウザのページ移動トリガーを検知し、編集中フィールドを「0」にする処理となっております。
恐らくではありますが、kintoneの他のページに移ることが、それらのイベントのトリガーとならないことが原因ではないかと思いました。しかし、自分自身では対処方法が分かりかねる状況です。

上記の挙動を解消するための方法についてご教授いただけませんでしょうか。


2点目:
レコード編集画面で、編集中フィールド以外の他のフィールドを書き換えた後、ブラウザの戻るボタンや別なサイトに移動しようとすると、ページ離脱をするかどうかの画面が出てきます。この画面が出てきているとき、または、キャンセルボタンを押すと、他のユーザがそのレコードのレコード編集画面を開くことができてしまいます。

コードの48~50行目にあるwindowオブジェクトの「beforeunload」イベントハンドラの処理をコメントアウトすると、上記の挙動はなくなりました。しかし、これらの処理については何らかの動作に対応するため記述しているかと思われるため、現在はコメントアウトせずに利用しております。

そこで、「beforeunload」イベントハンドラを記述した理由についてご教授いただけますでしょうか。


お伺いしたいことは以上となります。
分かりにくい文面となってしまい申し訳ございませんが、上記2点について何卒ご教授いただきますよう、よろしくお願い申し上げます。

0
サインインしてコメントを残してください。