複数条件に対応した表示(この番号ならこの名前…)をさせたい

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

kintoneをカスタマイズしたい!からJavaScript勉強中の初心者です。
先日上記の内容で質問し、色々いじったらうまく動作するようになりました。

そこから、設置したフィールドに自分のID番号が出るということで
せっかくなら”○○さんが編集中”という表示ができたらと思っております。

文字列フィールドの中にIF(編集中=1,"佐藤さんが編集中”,“編集OK”)のような計算式を入れるなどで行こうと思いましたが、数人ならOKなのですがIFS関数が使えないため20人ほど入れるのは難しいな…というところで止まっています。

計算式が無理ならカスタマイズをと思いましたが、うまく見つけることができませんでした。

1なら佐藤さん、2なら鈴木さん・・・を実現するためのヒントをいただけませんでしょうか。

よろしくお願いいたします。

【追記】

調べていたらswich文がよさそうです
コードの一番下に追記してみたのですが、うまくいきません。。
なにがおかしいのか教えていただけますと幸いです。

編集中というフィールドにIDが生まれるので、そこが1ならどう、2ならどう…をしていき
誰というフィールドにその状況を表示させたいです。
(編集中フィールドを置き換えるのでもいいです)

現状は、編集していないときはIDが0になるのですが、2でも0でも佐藤さんが編集中!のままになってしまいます。
あと、再読み込みを毎回させられます(これは追記なしでもありましたが毎回ではなかったような気がします)

(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);
  });
 
kintone.events.on(['app.record.detail.show',
  ],function(event) {revisionCheck(event).then(function(revisionMatch) {if(!revisionMatch)location.reload();
    });

   switch (record['編集中'].value) {
        case '2':
          record['誰'].value = '佐藤さんが編集中!';
          break;
        case '3':
          record['誰'].value = '鈴木さんが編集中!'; 
          break;
          case '4':
          record['誰'].value = '高橋さんが編集中!';
          break;
         case '5':
          record['誰'].value = '小林さんが編集中!';
          break;
        case '6':
          record['誰'].value = '田中さんが編集中!'; 
          break;
        default:
          record['誰'].value = '編集OK!';
          break;
}
});kintone.events.on(['app.record.edit.submit.success',
  ],function(event) {changeState(false);
  });
  
  return event;
})();
1 Like

@sakanako さん

こんばんは、質問の内容的にswitch分が作動しないってことなので少し気になったので回答させていだきますね!
record[‘編集中’].valueと書かれてますが、 recordに対して定義されてないため作動してないのかなと考えております。
イベント’app.record.detail.show’の引数eventの配列の中でrecordという配列があるので、大概いつも

const record = event.record;

と言う風にrecord変数に定義する必要があるかと思われますね。

1 Like

ブレークポイントを設定して、想定外の動きをする箇所がどうなってるかなどもぜひみてみてください〜

1 Like

@sakanako さん

何度も返信申し訳ないです、改めて見ると気になる点がいくつかあったのでヒントになるかわかりませんが、以下に箇条書きでさせていただきますね。

気になる点

・ずっとリロードされるとのことでしたが、コードみてみると今開いてるレコードを編集中になるとevent変数をrevisionCheck関数に引数として渡したリビジョン(保存のバージョンを管理する番号)とRESTAPIで今開いてるレコードを取得して、リビジョン番号を取得して見比べている。
→状況から考えられることは、RESTAPIが失敗してリビジョンを取得できず、結果的にrevisionMatchにreturn されるものがないからfalseになって毎回リロードかかってしまう。

・'app.record.detail.show’イベントでは、kintone.app.record.get() と kintone.app,record.set()で取得およびレコードをセットしてあげないとレコードは更新されません。 加えてこの処理の後に画面のリロードを挟まないと画面表示されているレコードの値は変わりません。

以上簡単に気になったところをお伝えいたしました。

2 Likes

Yuki_Minamitani様
ご回答ありがとうございます。
swichi文の始まりを以下のようにしたら作用しました。

kintone.events.on(['app.record.edit.show','app.record.detail.show','kintone.app.record.get()','kintone.app,record.set()'
  ],function(event) {revisionCheck(event).then(function(revisionMatch) {if(!revisionMatch)location.reload();
    });
    
    const record = event.record;

表示はされるようになりましたが
リロードをしないとずっと編集中になってしまうとのことで以下のコードを入れたら
画面が一生リロード(びちびち)されてしまいます。
returnの前にあるからかと思いreturnを消しましたが変わらず…

 location.reload();

何か前後につけなければいけないコードでしょうか?
すみませんが教えていただけると幸いです。

@sakanako さん

まず、「‘kintone.app.record.get()’,‘kintone.app,record.set()’」といったイベントはなく…特にそちらにそのように入れていてもエラーは出ないですが…
あと、こちらの認識がずれていて、'app.record.detail.show’のイベントハンドラ内でkintone.app.record.get()は使用できない事忘れていたため、@sakanako さんがされたい事をしようと思うと別の方法が必要になるかと思われます。

やはり、されたい事をしようと思うと全体的にどのように動いているのか把握する必要があると思います。
@mura さんが貼ってくださっているデバックの仕方を参考にして一度動きを確認された方と思いました。

ちなみに恐らくされたい事のヒントとしてこのように以下書かせて頂きますね。
・レコード編集イベント(‘app.record.edit.show’)発火

・revisionCheck(event)で今開いているレコードのevent変数のリビジョンとREST APIで取得されてきた更新済みのリビジョンを見比べる → リビジョンがずれていればリロード

・編集中フィールドに値が入っているか(Number(0)はfalseになります。)→編集中のユーザidと今のログインユーザが正しいか?→同じではなければセッション履歴内の処理を一つ戻す。

・changeState(true)で編集中フィールドにREST APIでユーザidを更新。←ここで一緒に 誰フィールドにもREST APIで「〇〇さんが編集中です!」を更新してあげればいいかもしれません…

画面をリロード

と簡単に書くとこのように動いておりますので、デバッグツールで確認しながらしてみると恐らく私が簡単に説明したことも理解できるかなと思われますので、一度お試しください。
また、

location.reload();

もたくさん本コードの中に登場するかと思いますが、デバッグツールを使えばどこのlocation.reload();かということもわかりますので、そちらも併せて確認してみて不明であればまたお聞きくださいね!

2 Likes

Yuki_Minamitani様

丁寧なご回答ありがとうございます!
いまいろいろしてみていたら何も作用しなくなってしまいました 泣

ヒントをもとにやり直してみます!ありがとうございます

1 Like

@sakanako さん

いえいえ、そう言っていただけるとこちらとしてもうれしい限りです。
ちなみにあまり学習的にはよくないですが、以下に私が確認したコード貼らせていただきますので、
そちらで参考にしてみてくださいね!

(() => {

    "use strict";

    let revisionCheck = (event) => {
        return kintone.api(kintone.api.url('/k/v1/record', true), 'GET', {
            app: kintone.app.getId(),
            id: kintone.app.record.getId(),
        }).then((response) => {
            return event.record.$revision.value === response.record.$revision.value;
        });
    };

    let changeState = (editing) => {
        let result;
        switch (kintone.getLoginUser().id) {
            case '2':
                result = '佐藤さんが編集中!';
                break;
            case '3':
                result = '鈴木さんが編集中!';
                break;
            case '4':
                result = '高橋さんが編集中!';
                break;
            case '5':
                result = '小林さんが編集中!';
                break;
            case '6':
                result = '田中さんが編集中!';
                break;
            default:
                result = '編集OK!';
                break;
        }
        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
                },
                誰:{
                    value: editing ? result : '編集OK!'
                },
            }
        });
    }; 

    kintone.events.on(['app.record.detail.show',], (event) => {
        revisionCheck(event).then(function (revisionMatch) {
            if (!revisionMatch) location.reload();
        });
        return event;
    }); 
    
    kintone.events.on(['app.record.edit.show',], (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();
                });
            }
        });
        return event;
    }); 
    kintone.events.on(['app.record.edit.submit.success',], (event) =>{
        changeState(false);
        return event;
    });

    kintone.events.on(['app.record.detail.show',], (event) => {
        revisionCheck(event).then((revisionMatch) => {
            if (!revisionMatch) location.reload();
        });
        return event;
    }); 
    
    kintone.events.on(['app.record.edit.submit.success',], (event) =>  {
        changeState(false);
        return event;
    });

    
})();
3 Likes

Yuki_Minamitani様

ご回答ありがとうございます!
リロードもなくスムーズに動作して感動しました。。

スペシャルベストアンサーなのですが
勉強のために内容を紐解いてからまた質問させてください><

取り急ぎお礼まで。。ありがとうございます!

1 Like

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。