Handsontableを入力フォームとして使って、JSONファイルを検索して結果を表示する
オリジナル
Handsontableを入力フォームとして使って、JSONファイルを検索して結果を表示する - Qiita
はじめに
前回は、JSONファイルを読み込んだ結果をHandsontableで表示させた。今回は、Handsontableを入力フォームとして使って、JSONファイル内を検索して、結果を表示させてみた。 HTMLだけでやっているので、モックアップを作るときには便利そうなのでメモ。
やってること
(1) JSONファイルを読み込む (2) JSONファイル内のテーブル一覧をコンボボックスに表示 (3) コンボボックスを変更した場合、そのテーブルに該当するカラム名を入力フォームに展開 (4) searchボタンを押すと、コンボボックスで選択されたテーブルを検索 (5) clearボタンを押すと、画面の初期状態に戻す (6) csvボタンを押すと、csvをダウンロードする(前回と同じ機能)
環境
Windows 8.1(64bit) Internet Explorer 11
用意したもの
Handsontable * handsontable.full.js * handsontable.full.css
juantascon * jquery.handsontable.csv.js
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"); });
全文
<!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>
最後に
わかりにくい点、間違っている点、効率的に書ける箇所などあれば教えていただければ幸いです。