カスタマイズビューを利用して複数の添付ファイルを表示したい

「第7回 カスタマイズビューを利用してみよう」を参考にしてカスタマイズビューを作成しました。

https://cybozudev.zendesk.com/hc/ja/articles/202905604-%E7%AC%AC7%E5%9B%9E-%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86

とても簡単に一覧表を作成することが出来ました。
・・・が、添付ファイルのところで悩んでいます。

「文字列項目」や「Webサイトのアドレス項目」は下記の書き方で表示されたのですが、添付ファイルについては書き方が全く分かりません。
(文字列)
cell1.innerHTML = record.氏名.value;
cell2.innerHTML = record.内容.value;
(Webサイト)
var tmpB = document.createElement(‘a’);
tmpB.href = record.参考URL.value;
tmpB.innerHTML = record.参考URL.value;
cell3.appendChild(tmpB);

フィールドコード名は「添付ファイル」です。
上記と同じ書き方だと「[object Object],[object Object]」と表示されます。
当たり前ですが・・・
cell4.innerHTML = record.添付ファイル.value;
添付ファイルは、複数の場合もあるので複数表示もご教示頂ければ幸いです。

他の添付ファイルの表示方法も読んだのですが、出来ればこのページの書き方が一番分かりやすいので
追記で表示出来れば、大変ありがたいです。

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

KUNIさん

 

> 上記と同じ書き方だと「[object Object],[object Object]」と表示されます。

 

添付ファイルフィールドの構造の中身がどんなものか、 ドキュメント や Tips 等でも確認された上で、こちら

 

「レコードに登録された添付ファイルをカスタマイズビューに表示してみよう( https://cybozudev.zendesk.com/hc/ja/articles/203126440 )」%E3%80%8D)

 

を参考にされると良いと思います。

 

cell4.innerHTML ='<a><img src="'+ image +'" width="10%" height="10%" /></a>'

 

のような感じで良いかと。

 

複数レコード、複数添付ファイルの処理にあたり非同期処理に注意が必要かというと、特に処理手順序を制御する必要もなく非同期のまま処理してしまってもいいと思います。

早速のお返事ありがとうございます。

正直なところ、「レコードに登録された添付ファイルをカスタマイズビューに表示してみよう」を何回も読んでみましたが

まったく分かりませんでした。

cell4.innerHTML = '<a><img src="' + image + ``'" width="10%" height="10%" /></a>'

の「image」部分に添付ファイルの項目をセットするのだと思いますが、

添付ファイル項目「record.添付ファイル.value;」をどのようにセットするのかが分かりません。

単純にセットしただけでは、表示されませんでした。

下記の部分のどこかに「record.添付ファイル.value;」をセットすれば良いのでしょうか?

-----------------------------------------------------------

var apiurl = '/k/v1/file.json?fileKey=' + filekey;

var xhr = new XMLHttpRequest();xhr.open('GET', apiurl, true);xhr.setRequestHeader('X-Requested-With' , 'XMLHttpRequest'); //これが無いとIE,FFがNGxhr.responseType = "blob";var blob = xhr.responseType;var blob = xhr.response;var url = window.URL || window.webkitURL;var image = url.createObjectURL(blob);

cell4.innerHTML = '<a><img src="' + image + '" width="10%" height="10%" /></a>'

----------------------------------------------------------

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

まず、大切なのは添付ファイルの取扱についてはfileKeyを使います。ファイルダウンロード のドキュメントに記載があります。

 

> 添付ファイルフィールドの構造の中身がどんなものか、 ドキュメント や Tips 等でも確認された上で、こちら

 

を確認頂くと、添付ファイルフィールド、つまり仰っている

 

> 添付ファイル項目「record.添付ファイル.value;」をどのようにセットするのかが分かりません。

> 下記の部分のどこかに「record.添付ファイル.value;」をセットすれば良いのでしょうか?

 

の record.添付ファイル.value の構造とその中にfileKeyが含まれていることがわかる思います。そして、この辺( 1 ,  2 )を見るとわかりますが、そこから得たfileKeyを使って添付ファイルをダウンロードすることになります。ブレークポイントはったり、console.log() で実際の中身を確認してみることをおすすめします。「レコードに登録された添付ファイルをカスタマイズビューに表示してみよう( https://cybozudev.zendesk.com/hc/ja/articles/203126440 )」%E3%80%8D) で出てきているfileKeyがいきなりポンと出てきたいるのは、例えば fileKey = record.添付ファイル.value[0].fileKey が前提であることによります。デモ環境アプリ があるようなので、開発ツールからソースコードを見るのも有用です。

 

添付ファイルの取扱は決して簡単ではありませんが Tips を成功させると、今回の内容もクリアできるようになると思います。

ご回答ありがとうございます。自分なりに頑張ってみました。

まだ添付ファイルが表示されません。もう少しだと思うのですが・・・

以下、ソースです。どの辺を注目すれば良いでしょうか?


(function () {
    “use strict”;
    kintone.events.on(‘app.record.index.show’, function (event){
        if (event.viewName != ‘テストシート’) {
            return;
        }

        var records = event.records;
        if (!records || !records.length) {
            document.getElementById(‘my-customized-view’).innerHTML = ‘表示するレコードがありません’;
            return;
        }

        var recUrl = location.protocol + ‘//’ + location.hostname + ‘/k/’ + kintone.app.getId() + ‘/show#record=’;
        var myRecordSpace = document.getElementById(‘my-tbody’);
        myRecordSpace.innerHTML = ‘’;

        for (var i = 0; i < records.length; i++) {
            var record = records[i];
            var row = myRecordSpace.insertRow(myRecordSpace.rows.length);
            var cell1  = row.insertCell(0);
            var cell2  = row.insertCell(1);
            var cell3  = row.insertCell(2);
            var cell4  = row.insertCell(3);
            var cell5  = row.insertCell(4);
            var cell6  = row.insertCell(5);
            var cell7  = row.insertCell(6);
            var cell8  = row.insertCell(7);
            var cell9  = row.insertCell(8);
            var cell10 = row.insertCell(9);
            var cell11 = row.insertCell(10);

            var tmpA = document.createElement(‘a’);
            tmpA.href = recUrl + record.レコード番号.value;
            tmpA.innerHTML = record.x1.value;
            cell1.appendChild(tmpA);

            cell2.innerHTML  = record.x2.value;
            cell3.innerHTML  = record.x3.value;
            cell4.innerHTML  = record.x4.value;
            cell5.innerHTML  = record.x5.value;
            cell6.innerHTML  = record.x6.value;
            cell7.innerHTML  = record.x7.value;
            cell8.innerHTML  = record.x8.value;
           
            //fileKeyの取得
            var filekey = record.添付ファイル.value[0].fileKey;
            var url = ‘https://xxxx-xxxx.cybozu.com/k/v1/file.json?fileKey=’ + filekey;
            var xhr = new XMLHttpRequest();
            xhr.open(‘GET’, url);
            xhr.setRequestHeader(‘X-Requested-With’ , ‘XMLHttpRequest’);
            xhr.responseType = “blob”;
            xhr.onload = function() {
                if (xhr.status === 200) {
                    //blobからURL生成
                    var blob = new Blob([xhr.response]);
                    var url = window.URL || window.webkitURL;
                    var image = url.createObjectURL(blob);
                    cell9.innerHTML = image
                } else {
                    // error
                    console.log(xhr.responseText);
                }
            };
            xhr.send();

            var tmpB = document.createElement(‘a’);
            tmpB.href = record.参考URL.value;
            tmpB.innerHTML = record.参考URL.value;
            cell10.appendChild(tmpB);
            
        }
    });
})();

KUNIさん

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

サイボウズスタートアップスの武井です。

 

画像表示については下記のようにすることで表示することが可能です。

(ソースは簡素化しております。)

 

(function () {
“use strict”;
kintone.events.on(‘app.record.index.show’, function (event){
if (event.viewName != ‘テストシート’) {
return;
}

var records = event.records;
if (!records || !records.length) {
document.getElementById(‘my-customized-view’).innerHTML = ‘表示するレコードがありません’;
return;
}

var recUrl = location.protocol + ‘//’ + location.hostname + ‘/k/’ + kintone.app.getId() + ‘/show#record=’;
var myRecordSpace = document.getElementById(‘my-tbody’);
myRecordSpace.innerHTML = ‘’;

for (var i = 0; i < records.length; i++) {
var record = records[i];
var row = myRecordSpace.insertRow(myRecordSpace.rows.length);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);

var tmpA = document.createElement(‘a’);
tmpA.href = recUrl + record.レコード番号.value;
tmpA.innerHTML = record.レコード番号.value;
cell1.appendChild(tmpA);

//fileKeyの取得
var filekey = record.添付ファイル.value[0].fileKey;
var url = ‘https://xxx.cybozu.com/k/v1/file.json?fileKey=’ + filekey;
var xhr = new XMLHttpRequest();
xhr.open(‘GET’, url);
xhr.setRequestHeader(‘X-Requested-With’ , ‘XMLHttpRequest’);
xhr.responseType = “blob”;
xhr.onreadystatechange = function (event) {
if ((xhr.readyState == 4) && (xhr.status == 200)) {
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function (event) {
cell2.innerHTML= ("<img src = " + reader.result + “>”);
};
}
}
xhr.send();

}
});
})();

 

以上を適用すると以下のようになります。

 

ただし、このソースですと、複数レコードの場合に齟齬が生じてしまいます。

どのようにお使いになられるか存じませんので、ここから先はKUNIさんに合わせてカスタマイズということになりますが、

基本的には、

  • reader.resultの部分を変数に保存
  • 添付ファイルセルにIDを付与
  • reader.resultがすべて読み込まれた段階でIDをキーとして上記reader.result変数をimg srcに挿入

といった形になるかと存じます。

 

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

サイボウズスタートアップス 武井様

 

具体的なソースありがとうございます。

「//fileKeyの取得」以下を適用(コピー)させて頂いたのですが、表示されませんでした。

念のため、すべての内容をコピーして実行させました。

レコード番号は表示されるのですが、添付ファイルは表示されませんでした。

ちなみに以下の1行を加えて表示させたら、ファイルキーはちゃんと取得していました。

cell3.innerHTML = record.添付ファイル.value[0].fileKey;

 

また、添付ファイル項目の画像はデータによって、2~3枚の場合もあり複数の画像を表示させたいと考えています。

その場合は、どのような設定にすれば良いかご教授頂ければ幸いです。

 

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

 

KUNIさん

ご連絡ありがとうございます。

 

>「//fileKeyの取得」以下を適用(コピー)させて頂いたのですが、表示されませんでした。

 

恐らく私の検証環境とKUNIさんの環境(フィールドコード等)が異なることが原因と思われますが、

念のためコンソールにて、エラーがないかご確認いただき、blobデータ(reader.result)が取得できているかご確認ください。

そのblobをimg srcに挿入して表示します。

あとは「どう入れるか」の入れ方の問題となります。

入れ方は上記回答などの方法となるかと存じます。

 

>また、添付ファイル項目の画像はデータによって、2~3枚の場合もあり複数の画像を表示させたいと考えています。 

ベストプラクティスではないかもしれませんが、

レコードの中に複数画像が存在するかをチェックし、

その画像のlengthの分だけ先に読み込み、画像を挿入し、

また次のレコードの画像挿入処理に移る、という風にされるとよろしいのではないでしょうか。

 

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

ご連絡ありがとうございます。

 

画像の表示ですが、以下に表現方法を変えましたら表示されました。

cell2.innerHTML = ‘<img src="’ + reader.result + ‘" width=“100” height=“100”>’

・・・しかし表示されたのが最終行のみでした。

レコード番号は、10行分表示されるのですが、画像は10行目のみしか表示されません。

どこを確認すれば良いでしょうか。

 

また、レコードの中に複数画像が存在するかを確認する方法ですが、参考になるページとかございますか?

・・・少し前進できたような気がします。

 

KUNIさん

 

ご連絡ありがとうございます。

>レコード番号は、10行分表示されるのですが、画像は10行目のみしか表示されません。

>どこを確認すれば良いでしょうか。

私の最初の回答をご確認ください。 

 

>また、レコードの中に複数画像が存在するかを確認する方法ですが、参考になるページとかございますか?

eventから取れるのであればeventでもよろしいかと思います。

他アプリから取るなどであればこちらをご参考ください。

 

       "添付ファイル": {
            "type":"FILE",
            "value": [
                {
                    "contentType":"image/png",
                    "fileKey":"20140216085901A05579B4196F4968AE26262EE889BD58086",
                    "name":"2014-01-30_No-0001.png",
                    "size":"30536"
                }
            ]
        }

 

ファイルの数は、上記のvalueのlengthで判断できます。

 

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

 

ご連絡ありがとうございます。

 

この1週間、色々参考にしながらロジックを変更してみましたが、添付ファイルの表示が出来ませんでした。

最後の行にしか添付ファイルが表示されず、全体の表示もレスポンスが悪く表示(10件程度)まで時間が掛かってしまいました。

 

当初の目標は、一覧表示で添付ファイルを表示(複数あれば複数表示)する事でしたが力不足でした。

 

参考にさせて頂いた記事自体は理解できたのですが、組み合わせでなかなか思うような結果が得られませんでした。

もう少し勉強してから、再チャレンジしたいと思います。

KUNIさん

お世話になっております。サイボウズスタートアップスの武井です。

私の方でも調査したところ、以前ご提案させていただいたコードの、レスポンスの部分がうまく動作しませんね。

詳細は不明です。(別のアプリでは動作したので、他の部分が関与しているのか?)

 

一旦、ご要望である複数ファイル表示/複数レコード表示は下記で実現できました。

(色々雑です。適宜整形が必要かと。/弥縫策です。恐らくベストプラクティスではありません。)

 

(function () {
"use strict";
kintone.events.on('app.record.index.show', function (event) {
if (event.viewName != 'テストシート') {
return;
}

var records = event.records;
if (!records || !records.length) {
document.getElementById('my-customized-view').innerHTML = '表示するレコードがありません';
return;
}

var recUrl = location.protocol + '//' + location.hostname + '/k/' + kintone.app.getId() + '/show#record=';
var myRecordSpace = document.getElementById('my-tbody');
myRecordSpace.innerHTML = '';

for (var i = 0; i < records.length; i++) {
var record = records[i];
var row = myRecordSpace.insertRow(myRecordSpace.rows.length);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);

var tmpA = document.createElement('a');
tmpA.href = recUrl + record.レコード番号.value;
tmpA.innerHTML = record.レコード番号.value;
cell1.appendChild(tmpA);

for (var j = 0; j < record.添付ファイル.value.length; j++) {
//fileKeyの取得
var filekey = record.添付ファイル.value[j].fileKey;
var url = '/k/v1/file.json?fileKey=' + filekey;
if (j > 0) {
var cell3 = row.insertCell(1);
cell3.setAttribute("id", 'cellId' + record.添付ファイル.value[j].size);
} else {
cell2.setAttribute("id", 'cellId' + record.添付ファイル.value[j].size);
}
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onreadystatechange = function (ev) {
var blob = this.response;
if (blob) {
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function (e) {
document.getElementById("cellId" + blob.size).innerHTML = "<img src = " + reader.result + ">";
};
};
};
xhr.send();
}
}

});
})();

ご連絡ありがとうございます。

 

頂きました内容を反映させ、無事表示することができました。

そこで添付ファイルも複数ある場合、列項目を増やして対応させたのですが

1つの項目に複数の添付ファイルを表示(縦に)させることは技術的に可能なのでしょうか。

HTMLだと単純に改行コード(BR)を挿入すれば表示できると試みたのですが上手くいきませんでした。

データによっては、添付ファイルの数が3~5程度ある場合があります。

 

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

KUNIさん

 

以下の通り、DOMで再現できた以上はできるはずです。

 

方法としては、

現状、複数添付ファイルがある場合にセルをインサートしているところを書き換える必要がありそうです。

改行自体はbrタグを追加する方法で問題ないと思います。

ご連絡ありがとうございます。

 

「DOM」と記載がありますが、参考になるURLはありますでしょうか。

ちなみに現在のコードは下記のとおりです。

            for (var j = 0; j < record.添付ファイル.value.length; j++) {
            // fileKeyの取得
            var filekey = record.添付ファイル.value[j].fileKey;
            var url = location.protocol + '//' + location.hostname + '/k/v1/file.json?fileKey=' + filekey;
            if (j > 2) {
            } else if (j == 2) {
                cell13.setAttribute("id", 'cellId' + record.添付ファイル.value[j].size);
            } else if (j == 1) {
                cell12.setAttribute("id", 'cellId' + record.添付ファイル.value[j].size);
            } else {
                cell11.setAttribute("id", 'cellId' + record.添付ファイル.value[j].size);
            }
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            xhr.responseType = "blob";
            xhr.setRequestHeader('X-Requested-With' , 'XMLHttpRequest');
            xhr.onreadystatechange = function (ev) {
            //if ((xhr.readyState == 4) && (xhr.status == 200)) {
                var blob = this.response;
                if (blob) {
                    var reader = new FileReader();
                    reader.readAsDataURL(blob);
                    reader.onload = function (e) {
                        document.getElementById("cellId" + blob.size).innerHTML = "<a href = " + reader.result + " target = '_blank'><img src = " + reader.result + " height = 80 ></a>";
                    };
                };
            };
            xhr.send();

 

また、<br>の挿入タイミングは、下記の前後に入れれば良いのでしょうか。

cellxx.setAttribute("id", 'cellId' + record.添付ファイル.value[j].size);

 

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

KUNIさん

 

DOMについては、Google検索のトップで申し訳ございませんが、

こちらがわかりやすいと思います。

 

また、<br>の挿入タイミングは、下記の前後に入れれば良いのでしょうか。

cellxx.setAttribute("id", 'cellId' + record.添付ファイル.value[j].size);

 

このタイミングですと、

まだ添付ファイルダウンロードのリクエストが返却されておらず、

imgタグができていないと思われる

(概ねidのset→ダウンロードリクエスト→ダウンロード→img生成の順)

ので、難しいと思います。

 

imgタグ生成時に、「あるレコード」の「●番目の画像だ」ということをうまく指定し、その後方にbrタグをアペンドするか、

各プログラムのフローを変更し、うまく流れの中でimg生成→<br>→img生成となるようにするしかない気がします。

 

中々骨が折れそうですが、頑張ってください!!

完成したら是非方法を教えてくださいね!

ご連絡ありがとうございます。

下記が全体のロジックになります(ここまでアドバイスありがとうございます。)

(function () {
    "use strict";
    kintone.events.on('app.record.index.show', function (event){
        if (event.viewName != 'テストシート') {
            return;
        }

        var records = event.records;
        if (!records || !records.length) {
            document.getElementById('my-customized-view').innerHTML = '表示するレコードがありません';
            return;
        }

        var recUrl = location.protocol + '//' + location.hostname + '/k/' + kintone.app.getId() + '/show#record=';
        var myRecordSpace = document.getElementById('my-tbody');
        myRecordSpace.innerHTML = '';

        for (var i = 0; i < records.length; i++) {
            var record = records[i];
            var row = myRecordSpace.insertRow(myRecordSpace.rows.length);
            var cell1  = row.insertCell(0);
            var cell2  = row.insertCell(1);
            var cell3  = row.insertCell(2);
            var cell4  = row.insertCell(3);
            var cell5  = row.insertCell(4);
            var cell6  = row.insertCell(5);
            var cell7  = row.insertCell(6);
            var cell8  = row.insertCell(7);
            var cell9  = row.insertCell(8);
            var cell10 = row.insertCell(9);
            var cell11 = row.insertCell(10);
            var cell12 = row.insertCell(11);
            var cell13 = row.insertCell(12);

            // 日付データを取得
            var date = record.活動日.value;
            var mydate = moment(date).format('MM-DD');

            // リンク先レコード番号
            var tmpA = document.createElement('a');
            tmpA.href = recUrl + record.レコード番号.value;
            tmpA.target = "_blank";
            tmpA.innerHTML = '<div align="center">' + '■' + '</div>';
            cell1.appendChild(tmpA);

            cell2.innerHTML  = '<div align="center">' + mydate; + '</div>';
            cell3.innerHTML  = '<div align="center">' + record.所属部.value; + '</div>';
            cell4.innerHTML  = '<div align="center">' + record.所属課.value; + '</div>';
            cell5.innerHTML  = '<div align="center">' + record.氏名.value; + '</div>';
            cell6.innerHTML  = record.訪問先.value;
            cell7.innerHTML  = record.訪問店.value;
            cell8.innerHTML  = record.面談相手.value;
            cell9.innerHTML  = record.内容.value;

            // 参考URL
            var tmpB = document.createElement('a');
            tmpB.href = record.参考URL.value;
            tmpB.target = "_blank";
            tmpB.innerHTML = '<div style = "width:120px">' + record.参考URL.value; + '</div>';
            cell10.appendChild(tmpB);

            for (var j = 0; j < record.添付ファイル.value.length; j++) {
            // fileKeyの取得
            var filekey = record.添付ファイル.value[j].fileKey;
            var url = location.protocol + '//' + location.hostname + '/k/v1/file.json?fileKey=' + filekey;
            if (j > 2) {
            } else if (j == 2) {
                cell13.setAttribute("id", 'cellId' + record.添付ファイル.value[j].size);
            } else if (j == 1) {
                cell12.setAttribute("id", 'cellId' + record.添付ファイル.value[j].size);
            } else {
                cell11.setAttribute("id", 'cellId' + record.添付ファイル.value[j].size);
            }
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            xhr.setRequestHeader('X-Requested-With' , 'XMLHttpRequest');
            xhr.responseType = "blob";
            xhr.onreadystatechange = function (ev) {
                var blob = this.response;
                if (blob) {
                    var reader = new FileReader();
                    reader.readAsDataURL(blob);
                    reader.onload = function (e) {
                        document.getElementById("cellId" + blob.size).innerHTML = "<a href = " + reader.result + " target = '_blank'><img src = " + reader.result + " width= 80 height = 80 ></a>";
                    };
                }
            };
            xhr.send();
        }
        }
    });
})();

この表示で以下で困っています。

①同一セル内で画像を複数表示したい。

現在は別々の列で表示される。

②画像以外のファイル(PDFやExcel)の場合は、ファイル名(xxx.xls)で表示させたい。

③画像表示が「クローム」の場合正しく表示されるが「IE」の場合、表示が「□に×」になる。

 

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