WijmoでExcelライクな画面を作成する方法

さて、今日のレシピは旬のWijmoとkintoneを使ったこの季節にピッタリの
「kintone一覧画面Excel風Wijmoがけ」をつくっていきまっしょう。

まず用意するのは

  • kintone
  • jQuery
  • Wijmo

です。
お好みでcssファイルを幾つか加えることで後味が良くなりますね。

scr00016
Grid表示には最高のWijmoに、さらに美味しい季節がやってきました。
http://wijmo.c1.grapecity.com/whats-new/

kintoneだけではどうしても料理しきれない一覧画面で悩んでいる方なら
きっと気に入っていただける組み合わせじゃないかと思います。
項目を増やすとドンドン増えていく列で、横スクロールが大変ですからね。

まずは下ごしらえから。

kintoneでアプリを作成します。
作成しておいたものがこちらです。
scr00006
作り置きのある方はそちらを使うとより味わい深い仕上がりになりますね。

jQueryとWijmoを読み込んだら
一覧にカスタムビューを追加します。HTMLは

<div id="wijmoGrid"></div>

これだけです。
「ページネーションを表示する」のチェックは入れておくといいですね。

さて作っていきましょう。

'use strict';
kintone.events.on('app.record.index.show', function(event){
  var records = event.records; //取得済みkintoneレコード
  var gridData = []; //表示データを格納する配列
  var row;//各行のデータを格納するオブジェクト

  //一番シンプルに
  if(records.length>0){
    for(var i=0; i<records.length; i++){
      row = {};
      for(var field in records[i]){
        row[field] = records[i][field].value;
      }
      gridData.push(row);
    }
  }
  var wijmoView = new wijmo.collections.CollectionView(gridData);
  var wijmoGrid = new wijmo.grid.FlexGrid('#wijmoGrid', {
    itemsSource: wijmoView //データをセット
  });
});

scr10001

取得しているレコードの内容が全てExcel風に表示されました。カンタンですね。

ただこれでは素材の味をそのまま、という感じですので
ひと工夫加えてみましょう。

'use strict';
var wijmoGrid;//wijmoオブジェクトを入れておきます
kintone.events.on('app.record.index.show', function(event){
  var records = event.records; //取得済みkintoneレコード
  var gridData = []; //表示データを格納する配列
  var row;//各行のデータを格納するオブジェクト

  //columnsを指定して表示フィールド、列の表示順をカスタム
  var columns = [
    { binding: '日付', header: '日付', dataType: 'Date', format: 'YYYY-MM-DD'},
    { binding: '顧客名', header: '顧客名', dataType: 'String'},
    { binding: '顧客住所', header: '顧客住所', dataType: 'String'},
    { binding: '顧客電話番号', header: '顧客電話番号', dataType: 'String'},
    { binding: '担当者名', header: '担当者名', dataType: 'String'},
    { binding: '担当者電話番号', header: '担当者電話番号', dataType: 'String'},
    { binding: '対応済', header: '対応済', dataType: 'Boolean'},
    { binding: '対応者', header: '対応者', dataType: 'String'}
  ];
  if(records.length>0){
    for(var i=0; i<records.length; i++){
      row = {};
      for(var ii=0; ii<columns.length; ii++){
        if(columns[ii].binding=='対応済' && columns[ii].dataType=='Boolean'){
          //Booleanタイプはチェックボックスで表示されるので値をtrue/falseに変換
          row[columns[ii].binding] = (records[i][columns[ii].binding].value=='済') ? true : false ;
        }else{
          row[columns[ii].binding] = records[i][columns[ii].binding].value;
        }
      }
      gridData.push(row);
    }
  }
  var wijmoItem = new wijmo.collections.CollectionView(gridData);//データをflexGrid用のオブジェクトに変換
  if(!wijmoGrid){//初期表示
    wijmoGrid = new wijmo.grid.FlexGrid('#wijmoGrid', {//表を生成
      autoGenerateColumns: false,
      columns: columns,
    });
  }
  wijmoGrid.itemsSource = wijmoItem;//データをセット
});

scr10003

new wijmo.grid.FlexGrid()

で生成するWijmoのオブジェクトは

<div id="wijmoGrid"></div>

にセットされますが、
同じ要素に new wijmo…をしようとするとエラーとなります。
ページ送り機能の際にエラーになるので
Wijmoのオブジェクトを使いまわせるようにしておきましょう。

ついでにcolumnsで各列のデータタイプを設定し、
「対応済」の列を「Boolean」タイプにしてチェックボックスにしています。

ここでワンポイント。

autoGenerateColumns: false

こちらは標準ではtrueとなっている設定値で
データの内容から自動的に表の列を生成してくれるとても便利な部分ですが、
自分の思い通りの味に仕上げるのが料理の醍醐味ですよね。

falseにすることで自動生成動作を止められます。
その上でcolumnsを自分で設定することで
自在に表の内容を操作できる、というわけです。

なのですが、

  wijmoGrid = new wijmo.grid.FlexGrid('#wijmoGrid', {//表を生成
    itemsSource : wijmoItem,//データをセット
    autoGenerateColumns: false,//自動列生成を停止
    columns: columns,
  });

としてしまうと、
データをセットした時点で自動生成がされてしまい、
自動生成の列+columnsで指定した列の両方が表示されてしまいます。

new wijmo…時にプロパティとしてitemSourceを渡す場合は

  wijmoGrid = new wijmo.grid.FlexGrid('#wijmoGrid', {//表を生成
    autoGenerateColumns: false,//自動列生成を停止 ※こっちが先
    itemsSource : wijmoItem,//データをセット ※こっちが後
    columns: columns
  });

という感じで、順番に気をつけないと美味しく仕上がりません。

  • 表を生成する
  • データをセットする

というのは
調理の手順を分けておいたほうがスムーズに作れますので
サンプルコードのようにしてあげたほうが良いかもしれませんね!

仕上げていきましょう。

'use strict';
var wijmoGrid;
kintone.events.on('app.record.index.show', function(event){
  var records = event.records; //取得済みkintoneレコード
  var gridData = []; //表示データを格納する配列
  var row;//各行のデータを格納するオブジェクト

  //そして新機能、ちょっと調整
  var monthlyColumns = [];//12月の日付column
  for(var i=1; i<=31; i++){
    monthlyColumns.push( { binding: '2016-12-'+('0'+String(i)).slice(-2), header: '12/'+i, dataType: 'Boolean', width:60} );
  }
  var columnLayout = [
      {
        header: '顧客', colspan: 2, cells: [
          { binding: '顧客名', header: '顧客', dataType: 'String'},
          { binding: '顧客電話番号', header: '電話', dataType: 'String'},
          { binding: '顧客住所', header: '住所', dataType: 'String'}
        ]
      },
      {
        header: '担当', colspan: 1, cells: [
          { binding: '担当者名', header: '担当者', dataType: 'String'},
          { binding: '担当者電話番号', header: '電話', dataType: 'String'}
        ]
      },
      {
        header: '対応', colspan: monthlyColumns.length, cells: monthlyColumns
      }
    ];
  if(records.length>0){
    for(var i=0; i<records.length; i++){
      row = {};
      for(var ii=0; ii<columnLayout.length; ii++){
        for(var iii=0; iii<columnLayout[ii].cells.length; iii++){
          if(records[i][columnLayout[ii].cells[iii].binding]===undefined) continue;
          if(columnLayout[ii].cells[iii].binding=='対応済' && columnLayout[ii].cells[iii].dataType=='Boolean'){
            //Booleanタイプはチェックボックスで表示されるので値をtrue/falseに変換
            row[columnLayout[ii].cells[iii].binding] = (records[i][columnLayout[ii].cells[iii].binding].value=='済') ? true : false ;
          }else{
            row[columnLayout[ii].cells[iii].binding] = records[i][columnLayout[ii].cells[iii].binding].value;
          }
        }
      }
      var history = records[i].対応履歴サブテーブル.value;
      for(var ii=0; ii<monthlyColumns.length; ii++){
        row[monthlyColumns[ii].binding] = false;
        if(history.length>0){
          for(var iii=0; iii<history.length; iii++){
            if(history[iii].value.日付.value == monthlyColumns[ii].binding) row[monthlyColumns[ii].binding] = true;
          }
        }
      }


      gridData.push(row);
    }
  }
  var wijmoItem = new wijmo.collections.CollectionView(gridData);//データをflexGrid用のオブジェクトに変換
  if(!wijmoGrid){//初期表示
    $('#wijmoGrid').width(1200);
    $('#wijmoGrid').height(420);
    wijmoGrid = new wijmo.grid.multirow.MultiRow('#wijmoGrid', {//表を生成
      autoGenerateColumns: false,//※こっち先
      layoutDefinition : columnLayout,
      frozenColumns : 3,
      frozenRows : 0
    });
  }
  wijmoGrid.itemsSource = wijmoItem;//データをセット ※こっち後

});

scr10004

Wijmoの新機能を少々振りかけて
「kintone一覧画面Excel風Wijmoがけ」の完成です。

みんなだいすきなExcel風のkintoneをじっくりと味わえますね。

いろいろできるWijmoのFlexGridに
MultiRowという機能が追加されました。
複数のセルをグループ化して何段かにまとめたものを、1行として扱える機能なのですが、
長大化してしまう一覧画面の1行、こんな形にコンパクトにできたら非常に見やすいですよね。
さらに、例えば1ヶ月分の30列程度を横ならびにさせたいときなどは
「行/列の固定」機能を使えばサンプルのように縦横自在に
指定行/列位置で固定させて、スクロールさせたい部分だけスクロールさせる、という使用が可能です。
サンプルでは

  frozenColumns : 3,

として、左の顧客・担当者情報(背景に色がある部分)の列を固定化、

  frozenRows : 0

として、最上部の1行を固定化、
上と左の情報を固定して、日付毎のチェックボックスを縦横自在にスクロールしながら確認できるという仕上がりです。

今回のレシピはかなりカンタンにまとめたので
もっと手を加えて自分なりのカスタマイズをしても広がりができそうですね!
サブテーブルを隠し味にするのも楽しそうです。

ぜひつくってみてください!

同じカテゴリーの記事