新規投稿
フォローする

ルックアップで添付ファイルフィールドをコピー

ルックアップの標準機能では、添付ファイルフィールドをコピーすることはできません。 JavaScriptカスタマイズにて、ルックアップ時に添付ファイルフィールドをコピーする方法を紹介します。

サンプル

フォーム設定

・アプリA(ルックアップコピー元)

・アプリB(ルックアップコピー先)

「ルックアップ」フィールドの設定の「ほかのフィールドのコピー」にて、「ルックアップ元アプリのレコード番号」を「ルックアップ先アプリのルックアップID」にコピーするよう設定します。

コード

js-sdkを利用しています。 アプリBで、下記「KintoneRestAPIClient.min.js」と「sample.js」を順に読み込みます。

・KintoneRestAPIClient.min.js

https://unpkg.com/@kintone/rest-api-client@1.1.0/umd/KintoneRestAPIClient.min.js

・sample.js

(function() {
  "use strict";
  var lookupField = 'ルックアップ';
  var lookupIdField = 'ルックアップID';
  var originAttachmentsField = '添付ファイル';
  var copyAttachmentsField = '添付ファイル';
  kintone.events.on([
    'app.record.detail.show',
    'app.record.create.show',
    'app.record.edit.show',
  ], function(event){
    kintone.app.record.setFieldShown(lookupIdField, false);
    event.record[copyAttachmentsField].disabled = true;
    return event;
  });
  kintone.events.on([
    'app.record.create.submit.success',
    'app.record.edit.submit.success',
  ], function(event){
    if(!event.record[lookupIdField].value) return;
    var client = new KintoneRestAPIClient();
    return client.record.getRecord({
      app: kintone.app.getLookupTargetAppId(lookupField),
      id: event.record[lookupIdField].value
    }).then(function(originRecord){
      return kintone.Promise.all(originRecord.record[originAttachmentsField].value.map(function(originFileInfomation){
        return client.file.downloadFile({
          fileKey: originFileInfomation.fileKey
        }).then(function(fileData){
          return {
            file: {
              name: originFileInfomation.name,
              data: new Blob([fileData], {type: originFileInfomation.contentType})
            }
          };
        });
      }));
    }).then(function(files){
      return kintone.Promise.all(files.map(function(files){
        return client.file.uploadFile(files);
      }));
    }).then(function(copyFileInfomations){
      return client.record.updateRecord({
        app: event.appId,
        id: event.recordId,
        record: {
          [copyAttachmentsField]: {
            value: copyFileInfomations
          }
        }
      });
    }).then(function (){
      return event;
    });
  });
})();
※レコード編集画面でも、レコードを保存するたびに添付ファイルをコピーし直します。
※ゲストスペース内のアプリを扱う場合は、「new KintoneRestAPIClient()」の引数で「guestSpaceId」を指定する必要があります。
https://github.com/kintone/js-sdk/tree/master/packages/rest-api-client#usage

添付ファイルのコピーは、APIを4回程叩く必要があり、案外大変ですね。

 

※コード修正しました.(2021/02/18)
※コード修正しました.(2021/04/09)

2

8件のコメント

Avatar
SpLn

お世話になります。kintone初心者です。

アプリBの「ルックアップ」「ルックアップID」「添付ファイル」を全てテーブルに入れ、アプリAの「添付ファイル」をコピーできるアプリの作成を試みています。

しかしながら、下記のエラーを解決できておりません。

本記事のソースコードのどこを変更すれば実現できるようになりますでしょうか。
まったくのど素人で恐縮なのですが、ご教授いただけましたら幸いです。

1
Avatar
江田篤史

SpLn様

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

下記のようなコードになります.

(function() {
  "use strict";
  var table = 'テーブル'; //サブテーブルのフィールドコード
  var lookupField = 'ルックアップ';
  var lookupIdField = 'ルックアップID';
  var originAttachmentsField = '添付ファイル';
  var copyAttachmentsField = '添付ファイル';
  kintone.events.on([
    'app.record.detail.show',
    'app.record.create.show',
    'app.record.edit.show',
  ], function(event){
    kintone.app.record.setFieldShown(lookupIdField, false);
    event.record[table].value.forEach(function(row){
      row.value[copyAttachmentsField].disabled = true;
    });
    return event;
  });
  kintone.events.on([
    'app.record.create.submit.success',
    'app.record.edit.submit.success',
  ], function(event){
    var client = new KintoneRestAPIClient();
    return kintone.Promise.all(event.record[table].value.map(function(row){
      if(!row.value[lookupIdField].value) return [];
      return client.record.getRecord({
        app: kintone.app.getLookupTargetAppId(lookupField),
        id: row.value[lookupIdField].value
      }).then(function(originRecord){
        return kintone.Promise.all(originRecord.record[originAttachmentsField].value.map(function(originFileInfomation){
          return client.file.downloadFile({
            fileKey: originFileInfomation.fileKey
          }).then(function(fileData){
            return {
              file: {
                name: originFileInfomation.name,
                data: new Blob([fileData], {type: originFileInfomation.contentType})
              }
            };
          });
        }));
      }).then(function(files){
        return kintone.Promise.all(files.map(function(files){
          return client.file.uploadFile(files);
        }));
      });
    })).then(function(copyFileInfomationsChunks){
      return client.record.updateRecord({
        app: event.appId,
        id: event.recordId,
        record: {
          [table]: {
            value: event.record[table].value.map(function(row, index){
              return {
                value: {
                  ...row.value,
                  [copyAttachmentsField]: {
                    value: copyFileInfomationsChunks[index]
                  }
                }
              }
            })
          }
        }
      });
    });
  });
})();
0
Avatar
辻川和伸

kintoneのアプリ間で添付ファイルコピーしたく、以下の投稿に従い設定しました。
https://developer.cybozu.io/hc/ja/community/posts/900001006786
ところがルックアップでレコード番号を入れてもサムネイル画像が表示されずコピーできません。カスタマイズ方法のどこに不備があるのか分かりません。アドバイスよろしくお願いします。なおhttps://unpkg.com/@kintone/rest-api-client@latest/umd/KintoneRestAPIClient.min.jsは、PC用のJavaScriptファイルurl欄とPC用のCSSファイルのurl欄両方に貼り付け保存の後、アプリを更新し、その後sample.jsをアップロードしアプリを更新しました。写真3枚を添付します。

 

辻川和伸により編集されました
0
Avatar
辻川和伸

江田篤史様、

江田様のsample.js(上のコード)を使いましたが、ルックアップでアプリAコピー元からアプリBコピー先に添付ファイルをコピーできませんでした。
試行錯誤の末、JSEdit for kintoneでsample.jsを見たところ21行目がエラー表示されていました。それで以下のように修正しました。

訂正前)var client = new KintoneRestAPIClient; 訂正後)var client = new KintoneRestAPIClient();

また、55行目の  });  もエラーになっていたので 55行目を削除しました。

この2ヵ所を修正したところ、アプリAコピー元から、アプリBコピー先に写真をコピーすることができました。

Javascriptの文法に詳しくないので、正確な処理だったのか確信は持てませんが、ご報告いたします。

この修正で問題ないでしょうか?

辻川

1
Avatar
江田篤史

辻川和伸さん

コメントありがとうございます。
仰る通り、コードにミスがありました。
申し訳ございません。

記事を修正したのでご確認いただければと思います。

0
Avatar
辻川和伸

江田様、

返信ありがとうございます。江田様の修正後のコードと、私のコードをdifffで比較したところ、

私のコードでは(JSEdit for kintoneにしたがい)、55行目(最後から2行目)の });を削除しましたが、

江田様の修正後のコードでは、52行目(最後から5行目)の })が削除されています。

文法的には、江田様の修正が正しいのですね。念のため再確認をお願いします。

辻川

 

0
Avatar
江田篤史

辻川和伸さん

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

2021/04/09現在の記事のコードが正しいです。
23行目のclient.record.getRecord()から始まるthen()チェーンつなげたいので、記事と同じ形が良いです。

JSEdit for kintoneでは、括弧の過不足のみで判断しているかと思います。
こちらでも動作はしますが、eventオブジェクトをreturnできないため、他のカスタマイズと競合する可能性があります。

0
Avatar
辻川和伸

江田様、

ご返信ありがとうございます。4/09現在の記事コードが正しいこと了解しました。

ルックアップで添付ファイルをアプリ間コピーできる今回のご投稿、現在、作成中のアプリで活用させていただきます。

添付ファイルコピーできることで、kintoneのルックアップがとても使い易いものになりました。
本当にありがとうございます。

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