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


