質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.54%

  • JavaScript

    19852questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HandsonTableの背景色変更が正常に動作しない

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 5,833

Otazoman

score 26

前提・実現したいこと

たびたびすいません。JavaScript初心者です。HandsonTableについて
質問です。ローカルストレージにデータを保存させるサンプルをHandsonTableで作成しています。フォントと背景色情報を保存させたいのですがどうもうまく動きません。かなり悩んでいますが妙案が浮かばないのでアドバイスをお願いできますでしょうか。

発生している問題・エラーメッセージ

初期に色を変更したものを保存するところまではうまく動きました。保存した色情報をロードした後に色を変更しようとしても初期保存した色情報が残ってしまっていて新しい色の情報が反映されません。

該当のソースコード

ひとまず該当のjsです。Chromeでしか動作させる予定はないのでChromeでテストしています。

// ローカルストレージに保存した値をテーブルに表示する
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) {
                    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
            _cellStyles.push(_createStyle(row, col, cellcolor, fontcolor));
            hot.updateSettings({
                cell: self.getStyles()
            });
            hot.render();
        };
        //選択範囲のセルに処理を行う。
        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
                }
            }
        };
    };
    //HandsonTable設定
    grid = document.getElementById("grid");
    var settings = {
        data: myData, //データ表示
        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, //検索有効
        cells:function(){SetProperty()} //保存している色を付ける
    };
    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: "色を変更"
                }
            }
        },
    });
// テーブルの内容をローカルストレージに保存する
function saveContent() {
    var content = hot.getData();
    var key = "gridData";
    var val = JSON.stringify(content);
    //データ情報
    localStorage.setItem(key, val);
    // セル情報
    var rows = hot.countRows(); //行数
    var cols = hot.countCols(); //列数
    var i = 0; //セル取得用
    var cellHeight; //行高
    var cellWidth; //列幅
    var styleColor; //文字色
    var bgColor; //背景色
    //コメント
    var comment;
    var commentsPlugin = hot.getPlugin('comments');
    //ローカルストレージ保存用JSON
    var property = [];
    property ="[";
    //プロパティ情報取得(背景色やセルサイズ等)
    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); //データ
            var data ={"Row":row,
                       "Col":col,
                       "fontColor":styleColor,
                       "BgColor":bgColor,
                       }
            //カンマの処理
            if (col == 0 && row == 0){
                property = property + JSON.stringify(data);
            }else{
                property = property +"," + JSON.stringify(data);
            }
            i = ++i;
        }
    }
    property =property + "]";
    var skey = "Setting";
    var sval = property;
    localStorage.setItem(skey, sval);
    alert("データを保存しました。");
    hot.render();
}
//プロパティ情報取得(背景色やセルサイズ等)
function SetProperty(){
    var key,value = [];
    var rows,cols;
    key = "Setting";
    value = localStorage.getItem(key);
    var property = JSON.parse(value);
    if( !property ){
        return;
    }
    var len = property.length;
    for(var i=0;i<len;i++){
        rows = property[i].Row;
        cols = property[i].Col;
    }
    var Arrayno =0;    //色格納JSONの配列番号取得用
    var font,background;
    for (var row = 0; row < rows + 1; row++) {
        for (var col = 0; col < cols + 1; col++) {
            font = property[Arrayno].fontColor;
            background = property[Arrayno].BgColor;
            $("td").eq(Arrayno).css("color",font);                 //文字色
            $("td").eq(Arrayno).css("backgroundColor",background); //背景色
            Arrayno = ++Arrayno;
        }
    }
}

試したこと

SetPropertyにて保存したJsonから色情報を取得し強制的にtdのCSSを書き替えているので、そこに問題があるのかと思っていますがどうすればいいか妙案がうかびません。特にConsoleにエラーも出ていません。色を変更するrendererの箇所も動いているようでした。新規の行が追加された際には色の変更はうまくできるようです。一度ローカルストレージに保存した後、色を変更するとうまく機能が動いてくれません。

補足情報(言語/FW/ツール等のバージョンなど)

handsontable/0.29.1
jquery/3.0.0

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

https://docs.handsontable.com/pro/3.0.0/Options.html#cells
cellsのところは上記の説明の通り、rowとcolが引数としてはいってきます。
また、cellPropertiesを返却値として引き渡すとその通りに設定されます。

また、以下を見ていただくとcellProperties.rendererにレンダラ定義を指定できます。
これを使用すればtd要素がそのままくるので、これに対してやりたい放題になります。
もちろん、row,col,prop(データ名)も来るので、やりたいことができると思います。
https://docs.handsontable.com/3.0.0/demo-conditional-formatting.html

handsontableをつかっていてrow,colをぐるぐる回してなんとかするのは、必要ないです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/02 16:05

    お礼が遅くなりまして申し訳ありません。
    ありがとうございます。今度試してみます。

    キャンセル

check解決した方法

0

色の保存の件については自己解決しました。
あまりよろしくない方法ですが、やりたいことは実現できました。

settingの箇所と変数を修正し

    var settings = {
        data: myData, //データ表示
        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, //検索有効
//        cells:function(){SetProperty()} //ここをコメントアウト
    };

    hot = new Handsontable(grid, settings);
    styles = new TableStyles(hot);      //varを外してスコープ拡大

プロパティ情報を設定する箇所で既に使用している関数を呼び出します。

//プロパティ情報設定(背景色やセルサイズ等)
function SetProperty(){
    var key,value = [];
    var rows,cols;
    key = "Setting";
    value = localStorage.getItem(key);
    var property = JSON.parse(value);
    if( !property ){
        return;
    }
    var len = property.length;
    for(var i=0;i<len;i++){
        rows = property[i].Row;
        cols = property[i].Col;
    }
    var Arrayno =0;                                                 //色格納JSONの配列番号取得用
    var font,background;
    for (var row = 0; row < rows + 1; row++) {
        for (var col = 0; col < cols + 1; col++) {
            font = property[Arrayno].fontColor;
            background = property[Arrayno].BgColor;
            styles.setCellsStyle(row, row, col, col, background ,font);  //ここを修正
            Arrayno = ++Arrayno;
        }
    }
}

何とか動くレベルですが、もっとエレガントな解決方法があれば
ご教示いただけると幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • JavaScript

    19852questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。