5
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Handsontableを入力フォームとして使って、JSONファイルを検索して結果を表示する

Last updated at Posted at 2015-11-21

はじめに

前回は、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

  • jquery-1.11.3.min.js

Handsontable

  • handsontable.full.js
  • handsontable.full.css

juantascon

  • 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>

最後に

わかりにくい点、間違っている点、効率的に書ける箇所などあれば教えていただければ幸いです。

5
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?