はじめに
前回は、JSONファイルを読み込んだ結果をHandsontableで表示させた。今回は、Handsontableを入力フォームとして使って、JSONファイル内を検索して、結果を表示させてみた。
HTMLだけでやっているので、モックアップを作るときには便利そうなのでメモ。
やってること
(1) JSONファイルを読み込む
(2) JSONファイル内のテーブル一覧をコンボボックスに表示
(3) コンボボックスを変更した場合、そのテーブルに該当するカラム名を入力フォームに展開
(4) searchボタンを押すと、コンボボックスで選択されたテーブルを検索
(5) clearボタンを押すと、画面の初期状態に戻す
(6) csvボタンを押すと、csvをダウンロードする(前回と同じ機能)
環境
Windows 8.1(64bit)
Internet Explorer 11
用意したもの
- jquery-1.11.3.min.js
- handsontable.full.js
- handsontable.full.css
- jquery.handsontable.csv.js
JSONファイル(自前)
table.json
{
"tableA":[
{"Year": "2009", "Maserati": "0", "Mazda": "2941", "Mercedes": "4303", "Mini": "354", "Mitsubishi": "5814" },
{"Year": "2010", "Maserati": "3", "Mazda": "2905", "Mercedes": "2867", "Mini": "412", "Mitsubishi": "5284" },
{"Year": "2011", "Maserati": "4", "Mazda": "2517", "Mercedes": "4822", "Mini": "552", "Mitsubishi": "6127" },
{"Year": "2012", "Maserati": "2", "Mazda": "2422", "Mercedes": "5399", "Mini": "776", "Mitsubishi": "4151" }
],
"tableB":[
{"Name": "Maserati", "Since": "1914"},
{"Name": "Mazda", "Since": "1920"},
{"Name": "Mercedes", "Since": "1926"},
{"Name": "Mini", "Since": "1952"},
{"Name": "Mitsubishi", "Since": "1970"}
]
}
内容
(1) JSONファイルを読み込む
(2) JSONファイル内のテーブル一覧をコンボボックスに表示
$.getJSON("json/table.json", function(table) {
jsondata = table;
// コンボボックスに表示するテーブル名を取得
tableName = new Array();
var count = 0;
for(key in jsondata){
tableName[count] = key;
count++;
}
// コンボボックスにOPTIONを追加
for(var i = 0 ; i < tableName.length ; i++){
$('#selectTable').append($('<option>').html(tableName[i]).val(tableName[i]));
}
// csvボタンを非活性にする
$('#csvDownLoad').attr("disabled", "disabled");
});
(3) コンボボックスを変更した場合、そのテーブルに該当するカラム名を入力フォームに展開
// コンボボックスの値を変更した場合に動く
$('#selectTable').change(function(){
// コンボボックスの値が、"NA"でなければ、テーブルを展開
// コンボボックスの値が、"NA"の場合は、テーブルを削除
if( $('#selectTable').val() != "NA") {
// コンボボックスの値をキーにして、テーブルを取得
var obj = jsondata[$('#selectTable').val()];
// テーブルが持っている、カラム名を取得
// データ持っている、ありき。
var searchHeader = new Array();
var count = 0;
for(key in obj[0]){
searchHeader[count] = key;
count++;
}
// Handsontableに展開する配列を作成
// 中身は空文字にする。
var inputCell = new Array();
for(var i = 0; i < searchHeader.length; i++){
inputCell[i] = "";
}
var data = [inputCell];
// 表の定義
hot = $('#searchGrid').handsontable({ //以下はデータ指定と表示オプション
data: data, //さっき作ったdataを指定
minSpareRows: 0, //表の一番下にいくつ空行を表示するか
colHeaders: searchHeader, //カラムの名前を表示するかどうか colheader: true/false
//カラムの名前を任意の名前にする colheader: 配列
contextMenu: true
});
} else {
$('#searchGrid').handsontable("destroy");
}
});
(4) searchボタンを押すと、コンボボックスで選択されたテーブルを検索
// searchボタンが押されたら、検索して結果を表示
$('#search').click( function() {
// コンボボックスでテーブルを選択していること。
if( $('#selectTable').val() != "NA") {
// 現在のコンボボックスの選択内容から、テーブルを取得する
// コンボボックスの値をキーにして、テーブルを取得
var obj = jsondata[$('#selectTable').val()];
// searchGridから入力されているデータを取得する(配列)
var row = $('#searchGrid').handsontable('getDataAtRow',0);
// カラムを取得する
var searchData = new Array();
var count = 0;
for(key in obj[0]){
searchData[count] = key;
count++;
}
// 取得したデータを元に、テーブルを検索
var resultData = obj.filter(function(record) {
var flag = false;
for( var j = 0; j < row.length; j++ ){
if( row[j] != "" ) {
flag = true;
break;
}
}
// 検索条件が入力されていたら、JSONを検索
// 検索条件が未入力であれば、全てを表示する
if( flag ){
for( var colCn = 0; colCn < searchData.length; colCn++){
if( record[searchData[colCn]] === row[colCn] ){
return true;
}
}
} else {
return true;
}
});
// resultに展開する
if( resultData.length > 0 ){
if(hot2 != undefined){
try{
hot2.destroy();
} catch(e) {
}
}
resultData = resultData,
container2 = document.getElementById('result'), //後ほど表を展開する要素を指定
hot2;
hot2 = new Handsontable(container2, { //以下はデータ指定と表示オプション
data: resultData, //さっき作ったdataを指定
minSpareRows: 0, //表の一番下にいくつ空行を表示するか
colHeaders: searchData, //カラムの名前を表示するかどうか colheader: true/false
//カラムの名前を任意の名前にする colheader: 配列
rowHeaders: true,
contextMenu: true, //セルを右クリックしたときのメニューをすべて表示
columnSorting: true //カラムのヘッダーをクリックした際に昇順、再クリックで降順にソート
});
// csvボタンを活性にする
$('#csvDownLoad').removeAttr("disabled");
} else {
if(hot2 != undefined){
hot2.destroy();
hot2 = undefined;
}
// csvボタンを非活性にする
$('#csvDownLoad').attr("disabled", "disabled");
alert("検索結果がありません");
}
} else {
alert("テーブルを選択してください");
}
});
(5) clearボタンを押すと、画面の初期状態に戻す
// clearボタンが初期状態に戻す
$('#clear').click(function(){
if(hot2 != undefined){
hot2.destroy();
hot2 = undefined;
}
$('#selectTable').val("NA");
$('#searchGrid').handsontable("destroy");
// csvボタンを非活性にする
$('#csvDownLoad').attr("disabled", "disabled");
});
全文
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="Shift_JIS">
<title>handsontable_test</title>
<link rel="stylesheet" type="text/css" href='css/handsontable.full.css'>
<script src='js/jquery-1.11.3.min.js'></script>
<script src='js/handsontable.full.js'></script>
<script src='js/jquery.handsontable.csv.js'></script>
<script>
$(document).ready(function () {
var jsondata; //JSON
var tableName; //テーブル一覧
var hot2; //resultの表定義
// 画面読み込み時、table.jsonの内容を取得する
$.getJSON("json/table.json", function(table) {
jsondata = table;
// コンボボックスに表示するテーブル名を取得
tableName = new Array();
var count = 0;
for(key in jsondata){
tableName[count] = key;
count++;
}
// コンボボックスにOPTIONを追加
for(var i = 0 ; i < tableName.length ; i++){
$('#selectTable').append($('<option>').html(tableName[i]).val(tableName[i]));
}
// csvボタンを非活性にする
$('#csvDownLoad').attr("disabled", "disabled");
});
// コンボボックスの値を変更した場合に動く
$('#selectTable').change(function(){
// コンボボックスの値が、"NA"でなければ、テーブルを展開
// コンボボックスの値が、"NA"の場合は、テーブルを削除
if( $('#selectTable').val() != "NA") {
// コンボボックスの値をキーにして、テーブルを取得
var obj = jsondata[$('#selectTable').val()];
// テーブルが持っている、カラム名を取得
// データ持っている、ありき。
var searchHeader = new Array();
var count = 0;
for(key in obj[0]){
searchHeader[count] = key;
count++;
}
// Handsontableに展開する配列を作成
// 中身は空文字にする。
var inputCell = new Array();
for(var i = 0; i < searchHeader.length; i++){
inputCell[i] = "";
}
var data = [inputCell];
// 表の定義
hot = $('#searchGrid').handsontable({ //以下はデータ指定と表示オプション
data: data, //さっき作ったdataを指定
minSpareRows: 0, //表の一番下にいくつ空行を表示するか
colHeaders: searchHeader, //カラムの名前を表示するかどうか colheader: true/false
//カラムの名前を任意の名前にする colheader: 配列
contextMenu: true
});
} else {
$('#searchGrid').handsontable("destroy");
}
});
// searchボタンが押されたら、検索して結果を表示
$('#search').click( function() {
// コンボボックスでテーブルを選択していること。
if( $('#selectTable').val() != "NA") {
// 現在のコンボボックスの選択内容から、テーブルを取得する
// コンボボックスの値をキーにして、テーブルを取得
var obj = jsondata[$('#selectTable').val()];
// searchGridから入力されているデータを取得する(配列)
var row = $('#searchGrid').handsontable('getDataAtRow',0);
// カラムを取得する
var searchData = new Array();
var count = 0;
for(key in obj[0]){
searchData[count] = key;
count++;
}
// 取得したデータを元に、テーブルを検索
var resultData = obj.filter(function(record) {
var flag = false;
for( var j = 0; j < row.length; j++ ){
if( row[j] != "" ) {
flag = true;
break;
}
}
// 検索条件が入力されていたら、JSONを検索
// 検索条件が未入力であれば、全てを表示する
if( flag ){
for( var colCn = 0; colCn < searchData.length; colCn++){
if( record[searchData[colCn]] === row[colCn] ){
return true;
}
}
} else {
return true;
}
});
// resultに展開する
if( resultData.length > 0 ){
if(hot2 != undefined){
try{
hot2.destroy();
} catch(e) {
}
}
resultData = resultData,
container2 = document.getElementById('result'), //後ほど表を展開する要素を指定
hot2;
hot2 = new Handsontable(container2, { //以下はデータ指定と表示オプション
data: resultData, //さっき作ったdataを指定
minSpareRows: 0, //表の一番下にいくつ空行を表示するか
colHeaders: searchData, //カラムの名前を表示するかどうか colheader: true/false
//カラムの名前を任意の名前にする colheader: 配列
rowHeaders: true,
contextMenu: true, //セルを右クリックしたときのメニューをすべて表示
columnSorting: true //カラムのヘッダーをクリックした際に昇順、再クリックで降順にソート
});
// csvボタンを活性にする
$('#csvDownLoad').removeAttr("disabled");
} else {
if(hot2 != undefined){
hot2.destroy();
hot2 = undefined;
}
// csvボタンを非活性にする
$('#csvDownLoad').attr("disabled", "disabled");
alert("検索結果がありません");
}
} else {
alert("テーブルを選択してください");
}
});
// csvボタンがクリックされたら表の内容をCSV出力する
$('#csvDownLoad').click(function(){
var csv_string = handsontable2csv.string(hot2);
var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
var blob = new Blob([bom, csv_string], { type: 'text/csv'});
// IE独自関数
window.navigator.msSaveBlob(blob, "test.csv");
});
// clearボタンが初期状態に戻す
$('#clear').click(function(){
if(hot2 != undefined){
hot2.destroy();
hot2 = undefined;
}
$('#selectTable').val("NA");
$('#searchGrid').handsontable("destroy");
// csvボタンを非活性にする
$('#csvDownLoad').attr("disabled", "disabled");
});
// Handsontableのおまじない
//以下は基本的にいじらない
function bindDumpButton() {
Handsontable.Dom.addEvent(document.body, 'click', function (e) {
var element = e.target || e.srcElement;
if (element.nodeName == "BUTTON" && element.name == 'dump') {
var name = element.getAttribute('data-dump');
var instance = element.getAttribute('data-instance');
var hot = window[instance];
console.log('data of ' + name, hot.getData());
}
});
}
//関数実行
bindDumpButton();
});
</script>
</head>
<body>
<p>テーブル選択</p>
<select style="width:200px;" id="selectTable">
<option value="NA"></option>
</select>
<div id="searchGrid" class="handsontable"></div><br>
<input id="search" type="button" value="search"/>
<input id="clear" type="button" value="clear"/>
<hr>
<div id="result" class="handsontable"></div><br>
<input id="csvDownLoad" type="button" value="csv"/>
</body>
</html>
最後に
わかりにくい点、間違っている点、効率的に書ける箇所などあれば教えていただければ幸いです。