さて、先日はRaspberry Piからセンサーデータ(温度情報)をkintoneに連携してみましたが、このデータをさらにグループウェアに取り込んで、表示してみたいと思います。
同じサブドメイン内でkintoneのグラフをGaroonのポータルに貼り付ける方法はkintoneグラフのiframeを用いてGaroonのポータル方法がよく知られていますが、今回はレコードデータをkintoneの一覧のように表示する方法をご紹介したいと思います。
同じサブドメイン内ならクロスドメインになることもなく、kintone REST APIをGaroon側からコールできるようですが、Tips等で登場しても良さそうなトピックですが出てきていませんし、・・・同じcybozu.com上でもGaroonとkintone間の環境によっては利用できなくなるかもしれませんので、注意が必要そうです。(iframeの連携が出来る限りは大丈夫そうですが)
Garoon on cybozu.comのHTMLポートレット
手法としては、Garoon(クラウド版)の「HTMLポートレット」に以下のソースを書き込み、$.ajaxの非同期通信でkintoneのGETメソッドを実行し、取得したレコード情報をテーブルに収めています。ちなみに、$.ajaxの選択理由としては、kintone内のJavaScriptカスタマイズであればkintone.api()が使えますが、Garoonでは当然使えませんので、やむなくです。
「Garoonシステム管理 – 各アプリケーションの管理 – ポータル – HTMLポートレット」で新規にポートレットを追加し、以下のソースコードを貼り付けます。
完成イメージ
ポートレットが作成できたら、ポータルに組み込んでみてください。次のように表示されます。
HTMLポートレットに貼り付けるソース(HTML/JavaScript/CSS)
HTMLポートレットに貼り付けるソースは、
・中身のないtheadとtbodyのtableタグを記述するHTML
・$.ajax非同期通信でkintoneからデータを取得し、テーブルにDOMを追加するJavaScript
・テーブルの見た目を整えるCSS(こちらを参考にさせて頂きました)
で構成されています。
<table class="kintone-table"> <thead id="kintone-labels"> </thead> <tbody id="kintone-records"> </tbody> </table> <script type="text/javascript"> if(typeof jQuery == undefined){ // jQueryはGaroon内に読み込まれているものを使うが、使えなくなった時の注意喚起 alert("jQueryが読み込まれていません。"); } // prototype.jsと衝突するようなので、回避 jQuery.noConflict(); (function($) { // 定数群 var APP_ID = 721; // kintoneアプリID var TABLE_SIZE = 10; // kintoneレコードの直近10件を取得(queryでレコード番号による降順指定、そのままテーブルサイズ) var RECORD_NUMBER_FIELD = 'レコード番号' var FIELDS = {'レコード番号':'レコード番号', '作成日時':'作成日時', '気温':'tempC'}; // 表示したいフィールドを「フィールド名」:「フィールドコード」順で連想配列にする // kintoneリクエストURL var kintoneUrl = '/k/v1/records.json' + '?app=' + APP_ID; var query = 'order by ' + RECORD_NUMBER_FIELD + ' desc ' + ' limit ' + TABLE_SIZE; kintoneUrl += '&query=' + encodeURIComponent(query); // $.ajaxによる非同期リクエスト $.ajax({ beforeSend: function (request){ request.setRequestHeader( 'X-Requested-With', 'XMLHttpRequest'); }, url: kintoneUrl, dataType: 'json', async: true, success: function(response) { //console.log(response); // ヘッダ部分 var thead = $('#kintone-labels'); var tr = $('<tr>'); for (var key in FIELDS){ var th = $('<th>'); th.html(key); tr.append(th); } thead.append(tr); // データ部分 var tbody = $('#kintone-records'); var records = response.records; for (var i = 0, l = records.length; i < l; i++) { var tr = $('<tr>'); for (var key in FIELDS){ var td = $('<td>'); td.html(records[i][FIELDS[key]].value); tr.append(td); } tbody.append(tr); } }, error: function(response) { //console.log(response); if(response.responseJSON){ if(response.responseJSON.message){ alert('[kintone] ' + response.responseJSON.message); }else{ alert('[kintone] kintoneデータの取得に失敗しました'); } }else{ alert('[kintone] kintoneデータの取得に失敗しました'); } } }); })(jQuery); </script> <style type="text/css"> table.kintone-table { width: auto; border-spacing: 0; font-size:14px; } table.kintone-table th { color: #fff; padding: 8px 15px; background: #258; background:-moz-linear-gradient(rgba(34,85,136,0.7), rgba(34,85,136,0.9) 50%); background:-webkit-gradient(linear, 100% 0%, 100% 50%, from(rgba(34,85,136,0.7)), to(rgba(34,85,136,0.9))); font-weight: bold; border-left:1px solid #258; border-top:1px solid #258; border-bottom:1px solid #258; line-height: 120%; text-align: center; text-shadow:0 -1px 0 rgba(34,85,136,0.9); box-shadow: 0px 1px 1px rgba(255,255,255,0.3) inset; } table.kintone-table th:first-child { border-radius: 5px 0 0 0; } table.kintone-table th:last-child { border-radius:0 5px 0 0; border-right:1px solid #258; box-shadow: 2px 2px 1px rgba(0,0,0,0.1),0px 1px 1px rgba(255,255,255,0.3) inset; } table.kintone-table tr td { padding: 8px 15px; border-bottom: 1px solid #84b2e0; border-left: 1px solid #84b2e0; text-align: center; } table.kintone-table tr td:last-child { border-right: 1px solid #84b2e0; box-shadow: 2px 2px 1px rgba(0,0,0,0.1); } table.kintone-table tr { background: #fff; } table.kintone-table tr:nth-child(2n+1) { background: #f1f6fc; } table.kintone-table tr:last-child td { box-shadow: 2px 2px 1px rgba(0,0,0,0.1); } table.kintone-table tr:last-child td:first-child { border-radius: 0 0 0 5px; } table.kintone-table tr:last-child td:last-child { border-radius: 0 0 5px 0; } table.kintone-table tr:hover { background: #bbd4ee; cursor:pointer; } </style>
考察
$.ajax非同期通信によるkintoneへのリクエストですが、CSRFトークンを要しないGETメソッドならでは内容だと思います。POSTやPUTも一旦kintone側で kintone.getRequestToken() よりCSRFトークンを取得して埋め込む方法が考えられそうですが、CSRFトークンは有効期間が1日ですので直接取得できないこの環境では事実上使えません。また、繰り返しになりますが、同じcybozu.com上でもGaroonとkintone間の環境によっては利用できなくなるかもしれませんので、注意が必要そうです。