さて、先日は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では当然使えませんので、やむなくです。

スクリーンショット_2015-03-19_19_05_01

 

スクリーンショット_2015-03-19_19_17_55

「Garoonシステム管理 – 各アプリケーションの管理 – ポータル – HTMLポートレット」で新規にポートレットを追加し、以下のソースコードを貼り付けます。

 

完成イメージ

ポートレットが作成できたら、ポータルに組み込んでみてください。次のように表示されます。

スクリーンショット_2015-03-19_18_48_55

 

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間の環境によっては利用できなくなるかもしれませんので、注意が必要そうです。

 

 


株式会社ジョイゾー