新規投稿
フォローする

レコード一時保存機能で「うっかりページ閉じ」対策

kintoneのレコード編集中なのにブラウザを閉じてしまったり、ページ遷移をしてしまったり…。 そんなうっかりミスに備え、Web Storage APIを使ったレコード一時保存のサンプルを紹介します。

サンプル

一定時間ごとに、レコードを一時保存します。 submitせずにページを閉じた場合、次回編集時に一時保存した情報を用いるかconfirm表示します。

※confirmの見た目はブラウザに依存します。
※添付ファイルフィールドの値は一時保存されません。
※LocalStorageの容量制限を超えるレコードは扱えません。
https://www.html5rocks.com/ja/tutorials/offline/quota-research/

コード

下記「sample.js」を読み込みます。 kintoneの全体JSとして読み込んでも動作します。

・sample.js

(function () {
  "use strict";
  var storageName;
  var timer;
  kintone.events.on([
    'app.record.create.show',
    'app.record.edit.show',
  ], function (event) {
    storageName = kintone.app.getId() + '-' + kintone.app.record.getId();
    var tempRecord = JSON.parse(localStorage.getItem(storageName) || '[]');
    if (tempRecord.created) {
      if (confirm('一時保存されたデータがあります。補完しますか?\n保存日時: ' + new Date(tempRecord.created) + '\n保存内容: ' + JSON.stringify(tempRecord.record))) {
        event.record = tempRecord.record;
      }
    }
    timer = setInterval(function () {
      localStorage.setItem(storageName, JSON.stringify({
        created: new Date(),
        record: kintone.app.record.get().record
      }, function (key, value) {
        return typeof value === 'undefined' ? null : value;
      }));
    }, 3000); //一時保存の頻度(ミリ秒)
    return event;
  });
  kintone.events.on([
    'app.record.create.submit.success',
    'app.record.edit.submit.success',
  ], function (event) {
    clearInterval(timer);
    localStorage.removeItem(storageName);
  });
  kintone.events.on([
    'app.record.detail.show'
  ], function (event) {
    clearInterval(timer);
  });
})();

・今回はsetIntervalを用いて「一定時間ごと」に一時保存していますが、「フィールド値変更時イベント」で一時保存することも可能です。
※ただし、フィールド値変更時イベントは、文字列 (複数行)など一部フィールドタイプには対応していません。

kintone.api(kintone.api.url('/k/v1/app/form/fields', true), 'GET', {
  app: kintone.app.getId(),
}).then(function(response){
  kintone.events.on(Object.keys(response.properties).reduce(function(fields, field){
    return fields.concat(field, Object.keys(response.properties[field].fields || []));
  }, []).reduce(function(events, field){
    return events.concat([
      'app.record.create.change.' + field,
      'app.record.edit.change.' + field
    ]);
  }, []), function(event){
    localStorage.setItem(storageName, JSON.stringify({
      created: new Date(),
      record: event.record
    }, function(key, value){
      return typeof value === 'undefined' ? null : value;
    }));
  });
});
0

6件のコメント

Avatar
青山昌司

江田様

 

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

とても便利に使わせていただいております。

質問ですが一次保存したあと、再編集で表示させた後に保存をしても、

編集画面を開くたびに「補完しますか?」と聞かれるのですが、

わかりますでしょうか?

一次保存を繰り返している間はエラーは出ませんが

一次保存をキャンセルするとエラーも出てしまします。

 

何卒ご教示賜りますよう、よろしくお願いいたします。

 

 

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

青山昌司により編集されました
0
Avatar
江田篤史

青山昌司様

お世話になっております。
ご指摘ありがとうございます。

バグが発生するのは、どのようなページ遷移をした場合でしょうか?
よろしければ、以下のような形で教えていただけると大変助かります。

(例)
1.レコード詳細画面
↓ (レコードを編集する)
2.レコード編集画面
↓ (キャンセル)
3.レコード詳細画面
↓ (レコードを編集する)
4.レコード編集画面
↓ (保存)
5.レコード詳細画面
↓ (レコードを編集する)
6.レコード編集画面 ←バグ発生

お手数ですがよろしくお願いいたします。

0
Avatar
青山昌司

江田さま

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

エラーのパターンがなかなか絞れません。

インストールしていた他のjsファイルはアプリから一度削除しています。

 

1.レコード詳細画面

↓ (レコードを編集する)←エラー発生することがある①

2.ポップアップ表示

↓ (補完しますか?OK)

3.レコード編集画面

↓ (保存)

4.レコード詳細画面 ←エラー発生することがある②

 

エラー①

エラーはなく動く事もあるのですが、この作業を何度か繰り返すと下記が出る場合があります。

 

エラー②

エラー①同様にエラーが出ない事もあるのですが、この作業を何度か繰り返すと

が出たりします。出たり出なかったりです。

 

 

補完後に再編集すると再び補完しますか?と聞かれるのですが何か関係がありますでしょうか?

保存日時は違うようです。

 

0
Avatar
江田篤史

青山昌司様

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

・「一次保存したあと、再編集で表示させた後に保存をしても、編集画面を開くたびに「補完しますか?」と聞かれる」
一時保存の頻度を、1秒以下に設定していますか?
もしその場合でしたら、'app.record.****.submit.success'から'app.record.detail.show'に遷移する間に再び一時保存されてしまっていたのだと思います。
記事のコードを修正したので、お手数ですが再度設定していただければと思います。

・コンソールに表示されるエラーについて
何度か試したのですが、私の環境では再現ができませんでした…。
もしまた詳しいことが分かれば教えていただきたいです。

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

0
Avatar
青山昌司

江田さま

 

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

ご返信ありがとうございます。

 

秒数の件初期の3秒でしたが運用を踏まえ30秒へ変更しました。

その後「補完しますか?」を繰り返すことはなさそうです。

コンソールエラーはこちら側の問題という事で

再度いろいろ確認してみます。

ありがとうございます。

1
Avatar
kintone

江田篤史様

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

上記のコードをmobileでも使用したいのですが可能でしょうか?

可能であればmobile用のJavascriptを教えていただきたいです。

何卒よろしくお願い致します。

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