HandsonTableのサンプル改良

前回はHandsonTableで色々と実験してみて色々と宿題が残ってました。
その改良を色々と試みてきたわけですがなかなかうまくいかない・・・。
宿題の解決についてはひとまずはできたものもあります。
まだまだ先は長いなぁ。EXCELがいかに偉大かが身にしみました。
それと質問サイトのご回答のおかげで何とかここまでこぎつけたこと非常に感謝します。
やはり英語やプログラムの地力が不足していることを痛感させられます。
頑張らねば。

◆残課題リスト
 ・検索にヒットしたレコードのみをレコード表示する。
 ・検索条件クリアしたらそのデータを再表示する。
 ・検索ヘッダー領域を固定する。
   →何とか今回実現、最後の検索ヘッダーがサイズ依存なので少しあれですが

 ・着色した色データを保存する。
 ・列の枠サイズを取得して保存する。
 ・行のサイズを取得して保存する。
   →取りあえず値を取得するところまでは何とかできた。後はこれをどうやって
    JSON化してうまくローカルストレージに保存するか。んでどうやって
   呼出し時に効率的に反映するか。

 ・コメントの内容を取得して保存する。
  →色々と調べてみたけれどもメソッド自体が動かないのでどうしようもない。


●HTML
<!DOCTYPE html>
<html>
<head>
<title>Handsontable - サンプル</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handsontable/0.29.1/handsontable.full.min.js"></script>
<script src="sample06.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/handsontable/0.29.1/handsontable.full.min.css">
<link rel="stylesheet" href="sample06.css">
</head>
<body>
<header>
    <nav id = "fixed-navi">
        <ul>
     <li>
  <h3>HandsontableDemoPage</h3>
     </li>
     <li>
                <input id="searchField" type="text" placeholder="文字列を入力してください。">
         <div id="resultCount">検索結果:</div>
            </li>
            <li>
                <label>セルの色:<input id="cellColorPicker" type="color" name = "cell" ></label>
                <label>文字の色:<input id="fontColorPicker" type="color" name = "font" ></label>
     </li>
     <li>
                <input id="saveButton" type="button" value="保存する">
         <input id="clearButton" type="button" value="クリア">
            </li>
         </ul>
    </nav>
</header>
<main id = "content">
            <div id="grid"></div>
</main>
<footer id ="footer">
  <input id="delData" type="button" value="ローカルストレージ内削除">
         <input id="testButton" type="button" value="テスト">
</footer>
</body>
</html>

●JavaScript

/*refer
  http://my-waking-dream.blogspot.jp/2013/12/live-search-filter-for-jquery.html
  http://ja.stackoverflow.com/questions/20343/handson-table%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88%E3%81%AE%E9%96%8B%E7%99%BA
  http://qiita.com/do_m_gatoru/items/b0f8d1d18b7037e5cba2
  http://stackoverflow.com/questions/28309993/anyway-to-filter-rows-with-handsontable
  http://jsfiddle.net/awyjnbj6/
  http://stackoverflow.com/questions/40552974/handsontable-header-search-input-text-is-cleared-intermittently-on-scroll
  http://stackoverflow.com/questions/33173850/how-do-i-format-the-column-headers-in-handsontable
  https://teratail.com/questions/36228
  http://qiita.com/PianoScoreJP/items/be721f1b06745c2bbc39
  http://qiita.com/opengl-8080/items/9d25e106ff48b66cb908
  http://docs.handsontable.com/0.18.0/CommentEditor.html
  https://docs.handsontable.com/0.29.2/Comments.html
  
*/


//グローバル変数(HadsonTable用)
var grid, hot ,myData ,resultRow; //, mode, beforeBackgroundColor, beforeStyleColor ;

//ボタン設定
$(loaded);

function loaded() {
    if (window.localStorage) {
        showContent();
        // ボタンをクリックしたときに実行するイベントを設定する
        //ローカルストレージ内データ削除ボタン挙動

        $("#delData").click(
            function() {
                var myRet = confirm("PC内の投稿情報を全削除します。よろしいですか?");
                if (myRet) {
                    localStorage.clear();
                    clearContent();
                }
            });
        //保存ボタン挙動
        $("#saveButton").click(
            function() {
                saveContent();
            });
        //クリアボタン挙動
        $("#clearButton").click(
            function() {
                var myRet = confirm("全てのセルの内容をクリアします。よろしいですか?");
                if (myRet) {
                    clearContent();
                }
            });

//****************************************************
        //TEST
        $("#testButton").click(
            function() {

  getCellstyle(hot);

            });
//****************************************************

    } else {
        alert("本アプリ未対応のブラウザです。対応ブラウザをご利用ください。");
    }
}

// ローカルストレージに保存した値をテーブルに表示する
function showContent() {
    var key, value = [];

    key = "gridData";
    value = localStorage.getItem(key);

    if (value === "undefined") {
        myData = [
            ["", "", "", ""]
        ];
    } else {
        myData = JSON.parse(value);
    }

//セルの色変更
    var TableStyles = function(hot) {
        var self = this;
        var _cellStyles = [];
        var _createStyle = function(row, col, cellcolor ,fontcolor) {
            var style = {
                row: row,
                col: col,
                renderer: function(instance, td, row, col, prop, value, cellProperties) {
                    Handsontable.renderers.TextRenderer.apply(this, arguments);
                      td.style.color = fontcolor;
                      td.style.backgroundColor = cellcolor;
         },
            };
            return style;
        };

        self.getStyles = function() {
            return _cellStyles;
        };

        //セルのスタイル設定
        self.setCellStyle = function(row, col, cellcolor ,fontcolor, updateTable) {
            if (_cellStyles.length == 0) {
                _cellStyles.push(_createStyle(row, col, cellcolor ,fontcolor));
            } else {
                    _cellStyles.push(_createStyle(row, col, cellcolor ,fontcolor));
            }

      if (updateTable != false) {
                hot.updateSettings({
                    cell: self.getStyles()
                });
                hot.render();
            };
        };

        //選択範囲のセルに処理を行う。配列値が0開始なのでループ終了条件に+1している。
        self.setCellsStyle = function(startrow, endrow, startcol, endcol, cellcolor ,fontcolor) {
            for (var row = startrow; row < endrow + 1; row++) {
                for (var col = startcol; col < endcol + 1; col++) {
                    self.setCellStyle(row, col, cellcolor ,fontcolor, false);
                    hot.updateSettings({
                        cell: self.getStyles()
                    });
                }
            }
            hot.render();
        };
    };


    //HandsonTable設定
    grid = document.getElementById("grid");
    var settings = {
        data: myData, //データ表示
//        width: 500, //全体の横枠指定
        height: 500, //全体の高さ指定
        autoColumnSize: true, //カラム自動調整
        startRows: 10, //初期表示行数
        startCols: 5, //初期表示列数
        autoRowSize: true, //行高さ自動調整
        autoColumnSize: true, //列幅自動調整
        rowHeaders: true, //行ヘッダー
        colHeaders: true, //列ヘッダー
        columnSorting: true, //ソート
        sortIndicator: true, //ソートの矢印
        minSpareRows: 1, //1行だけの空白セル
        fillHandle: true, //possible values: true, false, "horizontal", "vertical" フィル有効
        manualColumnMove: true, //ドラッグで移動(列)
        manualColumnResize: true, //ドラッグでサイズ調整(列) 
        manualRowMove: true, //ドラッグで移動(行)
        manualRowResize: true, //ドラッグでサイズ調整(行)
        comments: true, //コメント(右クリックメニュー)
        mergeCells: true, //セル結合(右クリックメニュー)
        customBorders: true, //罫線(右クリックメニュー)
        renderAllRows: true,
        search: true  //検索有効
    };

    hot = new Handsontable(grid, settings);
    var styles = new TableStyles(hot);

    //右クリックメニュー
    hot.updateSettings({
        contextMenu: {
            //独自メニュー実装
            callback: function(key, cell, e) {
                var sel = hot.getSelected();
                var startRow = sel[0]; //開始行
                var startCol = sel[1]; //開始列
                var endRow = sel[2]; //終了行
                var endCol = sel[3]; //終了列
  var cellColor = document.getElementById("cellColorPicker").value;
  var fontColor = document.getElementById("fontColorPicker").value;

                // 独自メニューのクリック判定
                switch (key) {
                    case 'setColor':
   //色設定
                 styles.setCellsStyle(startRow, endRow, startCol, endCol, cellColor , fontColor);
                        break;
                }
            },

            //メニュー
            items: {
                row_above: {
                    name: '上に行を挿入'
                },
                row_below: {
                    name: '下に行を挿入'
                },
                col_left: {
                    name: '左に列を挿入'
                },
                col_right: {
                    name: '右に列を挿入'
                },
                remove_row: {
                    name: '選択行を削除',
                    disabled: function() {
                        return $("#grid").handsontable('countRows') <= 2;
                    }
                },
                remove_col: {
                    name: '選択列を削除',
                    disabled: function() {
                        return $("#grid").handsontable('countCols') <= 1;
                    }
                },
                'setColor': {
                    name: "色を変更"
                },
                undo: {
                    name: '元に戻す'
                },
                redo: {
                    name: 'やり直す'
                },
                make_read_only: {
                    name: 'セルを読取専用にする'
                },
                mergeCells: {
                name: function() {
                    var sel = this.getSelected();
                    var info = this.mergeCells.mergedCellInfoCollection.getInfo(sel[0], sel[1]);
                    if (info) {
                        return '結合を解除';
                    } else {
                        return 'セルを結合';
                    }
    }
                },
                alignment: {
                    name: '文字位置指定'
                },
                borders: {
                    name: '枠線'
                },
                commentsAddEdit: {
                    name: 'コメントの挿入'
                },
                commentsRemove: {
                    name: 'コメントの削除'
                }
            }
        },
    });

    //検索結果合致の処理
    var searchField = document.getElementById("searchField");
    var resultCount = document.getElementById("resultCount");

    Handsontable.Dom.addEvent(searchField, 'keyup', function(event) {
 filter(('' + this.value).toLowerCase());
 resultRow = hot.countRows()-1;   //0で開始なので-1が必要
        resultCount.innerText = "検索結果:" + resultRow.toString() + "件";
    });

}

// テーブルの内容をローカルストレージに保存する
function saveContent() {
    var content = hot.getData();
    var key = "gridData";
    var val = JSON.stringify(content);
    localStorage.setItem(key, val);
    alert("データを保存しました。");
    hot.render();
}

//テーブルの内容をクリアする
function clearContent() {
    hot.clear();
}

//検索結果フィルタ
function filter(search) {
    var 
    row, r_len,
    data = myData, // Keeping the integretity of the original data
    array = [];
    for (row = 0, r_len = data.length; row < r_len; row++) {
        for(col = 0, c_len = data[row].length; col < c_len; col++) {
            if(('' + data[row][col]).toLowerCase().indexOf(search) > -1) {
                array.push(data[row]);
                break;
            }
        }
    }
    hot.loadData(array);
}

//セルのプロパティ類の取得(文字色やセル背景色等)
function getCellstyle(hot){
    var rows = hot.countRows();  //行数
    var cols = hot.countCols();  //列数
    var i=0;  //セル取得用
    var cellHeight; //行高
    var cellWidth; //列幅
    var styleColor; //文字色
    var bgColor; //背景色
    var value;  //該当セルのデータ用
    //コメント
    var comment; 
    var commentsPlugin = hot.getPlugin('comments');

    //プロパティ情報取得(背景色やセルサイズ等)
    for (var row = 0; row < rows-1; row++) {
                for (var col = 0; col < cols; col++) {
  cellHeight=hot.getRowHeight(row); //高さ
  cellWidth = hot.getColWidth(col); //幅
                styleColor=$("td").eq(i).css("color"); //文字色
                bgColor=$("td").eq(i).css("backgroundColor"); //背景色
                value = hot.getDataAtCell(row,col);  //データ
  comment = commentsPlugin.getCommentAtCell(row, col); //コメント(未実装の模様)
  //DEBUG
  console.log("This:R="+ row + ",C=" + col);
  console.log("Height:"+ cellHeight + ",Width:" + cellWidth);
                console.log("FC:" + i +";"+styleColor +",BG:" + i +";"+bgColor);
  console.log("Value:"+value + ",Com:"+comment);
  i=++i;
                }
            }
}

●CSS

body {
    margin: 0;
    padding: 10vh 0;
}

/* ヘッダ領域 */
header {
    width: 100%;
    height: 10vh;
    overflow: hidden;
    position: fixed;
    top: 0px;
    left: 0;
    z-index: 200;
}

/* メインカラム */
#main {
    display: block; /*IE対応*/
    margin-top: 120px;
    padding-top: 120px;
    z-index: 150; 
    overflow: hidden;
    */
}

/* フッター */
footer {
    width: 100%;
    overflow: hidden;
    position: fixed;
    bottom: 2%;
    left: 0;
}



/*ナビメニュー*/
#fixed-navi{
/* background:blue; */
 width:100%;
        height:10%;
}
ul{
 overflow:hidden;
 list-style:none;
}
li{
 float:left;
 width:25%;
}

li h3{
 display: table-cell;
 text-align: center;
 vertical-align: middle;
}

◆更なる検討
 ・着色した色データを保存する。
 ・列の枠サイズを取得して保存する。
 ・行のサイズを取得して保存する。
   保存周りの検討が必要、今のままだとセルにそれぞれ値を持たせた
  JSONを作って都度みたいな感じになりそうだけどもう少しいい手がないか・・・・

 ・コメントの内容を取得して保存する。
  これバージョンアップで実現できるかも分らんし、何とかできるか継続的に調査は
  必要だなぁと。

ひとまずはHandsonTableシリーズは今回でひと段落ということで
また気が向いたら書きます。

コメント

このブログの人気の投稿

証券外務員1種勉強(計算式暗記用メモ)

EXCELのVBAからOutlookの会議依頼してみる