HandsonTableをハンズオンしてみる。 [プログラミング]
HTML5というかJavaScriptで、ブラウザ上でExcelのようなグリッドを実現するHandsonTable。他にもグリッドを実現するソフトはいくつかあるようなのだけれど、最初に使って問題なく使えたので、他のは使っていません。フリーで簡単な用途だけだったらこれでも良いかなと思いました。Pro版では色々機能が使えるようなので、本気で仕事に使うとかするときにも良いかもしれません。
そんなわけでHandsonTableをハンズオンするわけですが、最初ハンソンテーブルと勘違いして読んでいました。その後もハンソンなのにhansonじゃねぇのかよとか思っていましたが、hands-onなのね。そういうスペリングするのかと思ってしまった。
実際の動作サンプルはこっちを見てもらうことにして
https://miff.blog.so-net.ne.jp/2018-12-05-1
はまったところを中心に内容をレクチャーしていく。
ソースはこちら。
https://github.com/miffy/handsontable_sample/blob/master/README.md
このブログにソース埋められる方法があるみたいなんだけど、README.mdとかだとダメなんかな。ともあれ簡単に解説していく。
HTML部分はExcelのようなHandsonTableのグリッドと、そこから生成されるHTMLコードを格納するテキストエリアと、HTMLコードを生成するボタンになっています。それぞれIDが付けられていてJavaScriptでラベリングというか、それを目印に操作を行っていくわけです。
JavaScriptのここでHTMLのIDを取ってくる。操作的には一般的なものだと思います。オブジェクトかなんか得られるのかな?
ふつうだとHandsontableのオブジェクトを生成する際に、データを渡してグリッドの行と列の数を自動的に特定するのだけれど、今回は最初から何も入っていないものなので、startCols, startRowsで明示的に指定してあげる。
明示的に指定してあげるのは良いけど、幅も適当に指定されてしまうのでブログとかの限られた領域ではwidth, heightで制限してあげて、スクロールバーを出るようにしてあげる。セルに入れる文字数によって幅と高さが広がってしまうので書いてあげたほうがいい。
outsideClickDeselectsははまった。falseにしないとボタンを押すときに選択範囲が消えて、グリッド部分から情報が取って来られなくなる。これは何が悪いのか他に色々試してみてしまったけど、ただ単に外側選択の時に選択がなくならないような設定があったというオチでした。
というか、大体外側触ってもセルの選択をなくすとか不便すぎるからデフォルトで選択したままにして欲しいんですが…。これはわかんないとハマりやすい。そもそも、そういう設定があるのかどうかを調べようとするところまで行くのが大変。自分はブラウザのデバッガがエラーを吹いていたので気がついたけど、本家の通りにやっていない限りはハマること間違いなしだよな。他に問題があるかと思っちゃうもん。
のところですが、ここが本丸で、グリッドに入力して、HTMLテーブルにしたい部分を選択して、ボタンを押した時の挙動ですね。これも一般的な表記かと思います。
ここでHandsontableで選択したセルの情報を取ってきています。それを配列に詰める。うまいことに行列が配列の入れ子に分けて保存されているので、だらーっとセルの内容が入れられるってこともないです。そこのところの仕組みがどうなっているかはよくわからん。
コメントアウト部分はHTML形式で吐き出す前に、JSONで出していたんですよね。というか、本家がJSONで吐き出していたので単にその名残です。console.logの方はブラウザに吐き出して、output.valueはHTMLのテキストエリアに吐き出しているところです。JSONってJavaScriptの内部データを吐き出すフォーマットなんだなと何となく今更ながら感じている。
実際に内部データをHTMLテーブル形式に並べるところ。
配列が空のJSONを見ると、[[[]]]と三重構造になっているので、ループを回してデータ取るところも三重構造にしないとあかんかった。keyAとかBとかの名前には意味がありません。参考にして取ってきたところがそうしていただけで変えてないだけです。
本当は$keyAとか気持ち悪い変数名だったので、$は取りましたけどね。というか、以前のJavaScriptでは変数に$を付けることが普通だったようです。別に決まったノーテーションというわけではないのに、どうしてそういう書き方が一般的だったのか意味不明ですね。今では一般的ではないと思います。ごく初期の慣例的に行われていたことだったのかもしれません。
そしてセルが何も入っていないとnullが入ってきて、放っておくと"null"という文字が入ってしまうので、それを阻止しています。空白のところってのもあり得ないからどうせ後からでも入れるので、その時に削除してもらえばいいかなと思ったのですが、デバッグの時にあまりに鬱陶しかったのでnullが入らないようにしました。
見出しで一番上をthタグで入れればよかったんですが、面倒で入れていません。大した手間じゃないから入れればいいのにね。まぁコメントに入れろやと言われたら入れます。数行入れるだけなので時間はかからないでしょう。
あ、そうそう。JavaScriptって+=演算子使えないのな。Javaでは書けたんだったっけ? ググってみたらかけるみたい。プリミティブ型はもちろん、文字列型もいけるらしい。というか、+=演算子使えないとか書き方が冗長すぎて鬱陶しいんだが…。
最後は生成したHTMLソースをテキストエリアに吐き出してそれを選択してクリップボードにコピーすることをしています。どこぞで仮想的なテキストエリアを作って実際的にはコピーだけするという方法もあったのですが、別にテキストエリアを作らない意味もなかったのでそうしませんでした。というか、クリップボードにコピーされたことを示すダイアログなりアラートを出さないといけなかったし、そっちの方が面倒だったりしたのでやめました。
そんなわけで、こんな短いコードでExcelもマクロもなしで、HTMLでHTMLテーブルを生成することができました。これというのもHandsonTableのおかげですね。これを自分で作れとなると数年かかってしまいそうなのでCommunity Editionを提供してくれるのはありがたいことです。
自分もこういう有用なソフトを書ければいいのになと切に思います。OSSで食っていけたらいいのになとぼーっと考えることもあるのですが、それができるのは一部の優秀な人だけなんでしょうね。はやくゆうしゅうになりたーいぃ(妖怪人間のていでw)
そんなわけでHandsonTableをハンズオンするわけですが、最初ハンソンテーブルと勘違いして読んでいました。その後もハンソンなのにhansonじゃねぇのかよとか思っていましたが、hands-onなのね。そういうスペリングするのかと思ってしまった。
実際の動作サンプルはこっちを見てもらうことにして
https://miff.blog.so-net.ne.jp/2018-12-05-1
はまったところを中心に内容をレクチャーしていく。
ソースはこちら。
https://github.com/miffy/handsontable_sample/blob/master/README.md
このブログにソース埋められる方法があるみたいなんだけど、README.mdとかだとダメなんかな。ともあれ簡単に解説していく。
HTML部分はExcelのようなHandsonTableのグリッドと、そこから生成されるHTMLコードを格納するテキストエリアと、HTMLコードを生成するボタンになっています。それぞれIDが付けられていてJavaScriptでラベリングというか、それを目印に操作を行っていくわけです。
JavaScriptのここでHTMLのIDを取ってくる。操作的には一般的なものだと思います。オブジェクトかなんか得られるのかな?
var grid = document.getElementById('grid'); var output = document.getElementById('output'); var getButton = document.getElementById('getButton');
ふつうだとHandsontableのオブジェクトを生成する際に、データを渡してグリッドの行と列の数を自動的に特定するのだけれど、今回は最初から何も入っていないものなので、startCols, startRowsで明示的に指定してあげる。
var table = new Handsontable(grid, { startCols: 10, startRows: 20, width: 400, height: 400, outsideClickDeselects: false, selectionMode: 'range', });
明示的に指定してあげるのは良いけど、幅も適当に指定されてしまうのでブログとかの限られた領域ではwidth, heightで制限してあげて、スクロールバーを出るようにしてあげる。セルに入れる文字数によって幅と高さが広がってしまうので書いてあげたほうがいい。
outsideClickDeselectsははまった。falseにしないとボタンを押すときに選択範囲が消えて、グリッド部分から情報が取って来られなくなる。これは何が悪いのか他に色々試してみてしまったけど、ただ単に外側選択の時に選択がなくならないような設定があったというオチでした。
というか、大体外側触ってもセルの選択をなくすとか不便すぎるからデフォルトで選択したままにして欲しいんですが…。これはわかんないとハマりやすい。そもそも、そういう設定があるのかどうかを調べようとするところまで行くのが大変。自分はブラウザのデバッガがエラーを吹いていたので気がついたけど、本家の通りにやっていない限りはハマること間違いなしだよな。他に問題があるかと思っちゃうもん。
getButton.addEventListener('click', function(event) {
のところですが、ここが本丸で、グリッドに入力して、HTMLテーブルにしたい部分を選択して、ボタンを押した時の挙動ですね。これも一般的な表記かと思います。
var selected = table.getSelected(); var data = []; for (var i = 0; i < selected.length; i += 1) { var item = selected[i]; data.push(table.getData.apply(table, item));
ここでHandsontableで選択したセルの情報を取ってきています。それを配列に詰める。うまいことに行列が配列の入れ子に分けて保存されているので、だらーっとセルの内容が入れられるってこともないです。そこのところの仕組みがどうなっているかはよくわからん。
//console.log(JSON.stringify(data)); //output.value = JSON.stringify(data);
コメントアウト部分はHTML形式で吐き出す前に、JSONで出していたんですよね。というか、本家がJSONで吐き出していたので単にその名残です。console.logの方はブラウザに吐き出して、output.valueはHTMLのテキストエリアに吐き出しているところです。JSONってJavaScriptの内部データを吐き出すフォーマットなんだなと何となく今更ながら感じている。
実際に内部データをHTMLテーブル形式に並べるところ。
var htmlstr = "<table>\n"; for ( var keyA in data ) { for ( var keyB in data[keyA] ) { htmlstr = htmlstr + "<tr>\n"; for ( var keyC in data[keyA][keyB] ) { htmlstr = htmlstr + "<td>"; if(data[keyA][keyB][keyC]!=null){ htmlstr = htmlstr + data[keyA][keyB][keyC]; } htmlstr = htmlstr + "</td>\n"; } htmlstr = htmlstr + "</tr>\n" } } htmlstr = htmlstr + "</table>"
配列が空のJSONを見ると、[[[]]]と三重構造になっているので、ループを回してデータ取るところも三重構造にしないとあかんかった。keyAとかBとかの名前には意味がありません。参考にして取ってきたところがそうしていただけで変えてないだけです。
本当は$keyAとか気持ち悪い変数名だったので、$は取りましたけどね。というか、以前のJavaScriptでは変数に$を付けることが普通だったようです。別に決まったノーテーションというわけではないのに、どうしてそういう書き方が一般的だったのか意味不明ですね。今では一般的ではないと思います。ごく初期の慣例的に行われていたことだったのかもしれません。
そしてセルが何も入っていないとnullが入ってきて、放っておくと"null"という文字が入ってしまうので、それを阻止しています。空白のところってのもあり得ないからどうせ後からでも入れるので、その時に削除してもらえばいいかなと思ったのですが、デバッグの時にあまりに鬱陶しかったのでnullが入らないようにしました。
見出しで一番上をthタグで入れればよかったんですが、面倒で入れていません。大した手間じゃないから入れればいいのにね。まぁコメントに入れろやと言われたら入れます。数行入れるだけなので時間はかからないでしょう。
あ、そうそう。JavaScriptって+=演算子使えないのな。Javaでは書けたんだったっけ? ググってみたらかけるみたい。プリミティブ型はもちろん、文字列型もいけるらしい。というか、+=演算子使えないとか書き方が冗長すぎて鬱陶しいんだが…。
output.value = htmlstr; output.select(); var retVal = document.execCommand('copy');
最後は生成したHTMLソースをテキストエリアに吐き出してそれを選択してクリップボードにコピーすることをしています。どこぞで仮想的なテキストエリアを作って実際的にはコピーだけするという方法もあったのですが、別にテキストエリアを作らない意味もなかったのでそうしませんでした。というか、クリップボードにコピーされたことを示すダイアログなりアラートを出さないといけなかったし、そっちの方が面倒だったりしたのでやめました。
そんなわけで、こんな短いコードでExcelもマクロもなしで、HTMLでHTMLテーブルを生成することができました。これというのもHandsonTableのおかげですね。これを自分で作れとなると数年かかってしまいそうなのでCommunity Editionを提供してくれるのはありがたいことです。
自分もこういう有用なソフトを書ければいいのになと切に思います。OSSで食っていけたらいいのになとぼーっと考えることもあるのですが、それができるのは一部の優秀な人だけなんでしょうね。はやくゆうしゅうになりたーいぃ(妖怪人間のていでw)
タグ:JavaScript
コメント 0