3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

日本語プログラミング言語「なでしこ」Advent Calendar 2024

Day 9

なでしこさんにグリッドが欲しい❗️ 後編 ~行選択・自動ソート・セル幅変更~

Last updated at Posted at 2024-12-09

 昨日に引き続き、なでしこ3のテーブル部品に、なでしこ1のグリッド部品で出来る機能を色々追加しようと頑張る話。
 編集機能については昨日の記事をご覧下さい。

行選択機能を追加

 v1のグリッドは、「行選択」がオンになっていると、クリックした行の色が変わり、どの行を選択しているのか見やすくなります。
 なでしこさんのテーブルでは、「DOM部品オプション」の「テーブル背景色」で[ヘッダ色,偶数行色,奇数行色]の配列を指定して、テーブル作成時「tr」の背景色にその色がスタイル設定されています。
 クリックした時にその行のtrの背景色を変更してやるだけで出来そうですね。

クリックした位置の色を変える

 クリックした位置と書いてきましたが、クリックだと押して離すがセットなので、色が変わるのはマウスを離した時。
 押した時すぐに色が変わってくれた方が気分がいいので、「マウス押した時」のイベントを使うことにします。
 マウスのイベントは、行(tr)に設定してもテーブルそのものに設定しても発生するのですが、どこに設定してもイベントが発生した時に対象に入るのはセル(td)です。
 セルの親部品(parentNode)であるtrが、色を変えるべきtrということになります。

テストデータ「名前,ふりがな,点数
太郎,たろう,55
花子,はなこ,100
一郎,いちろう,80」
CSV取得
テストテーブルテストデータテーブル作成

テストテーブルマウス押した時には:
    
もし対象.nodeName「TD」ならば:
        
クリック行対象.parentNode
        クリック行「背景色」「#CCF」DOMスタイル設定

 DOM部品はこのように親要素や子要素の参照がプロパティに入っているので、ずっと辿って行くことが出来るんですよ✨

前にクリックした行の色を戻す

 一回目はコレだけで良いのですが、また別の行をクリックした時には、前にクリックしていた行の色を元に戻してやらないと、どんどん選択行色が増えていってしまいますよね💦
 ということは前の位置を覚えておかなきゃならない。
 とりあえず、グローバルに「前クリックセル」変数を作っておき、行色変更が発生したらその時クリックしたセルの参照を入れておくことにします。
 そしてその行数が奇数か偶数かで、DOM部品オプションのテーブル背景色を参照して塗り分けます。

        もし前クリックセルでなければ:
            
変数 前クリック行前クリックセル.parentNode
            変数 前行数前クリック行.rowIndex
            変数 行色情報DOM部品オプション.テーブル背景色
            変数 前背景色行色情報[前行数%2+1]
            前クリック行「背景色」前背景色DOMスタイル設定

 「%」は割った余りを求める演算子です。
 行数を2で割った余りが0なら偶数、1なら奇数。
 テーブル背景色は、偶数行の色が[1]に、奇数行の色が[2]に入っているので+1してやれば取得できるって寸法です。

オブジェクトプロパティ構文

配列の中身は直接参照できないっぽい

 オブジェクトプロパティ構文、途中で内容が配列だったりするとうまく行きませんでした。
 配列の前で一旦変数に入れるか、オブジェクトプロパティ構文を使わず[" "]を使えば大丈夫デス。

前背景色DOM部品オプション.テーブル背景色[0]。   # できない
前背景色DOM部品オプション["テーブル背景色"][0]# できる
テーブル背景色DOM部品オプション["テーブル背景色"]
前背景色テーブル背景色[0]        # できる

テーブルのナゾ(?)

 実は、クリック行の背景色をオブジェクトプロパティ構文で指定してみようとしたら、出来ませんでした。

テストテーブルマウス押した時には:
    
もし対象.nodeName「TD」ならば:
        
クリック行対象.parentNode
        クリック行.背景色「#CCF」 # できない!?
        //クリック行の「背景色」に「#CCF」をDOMスタイル設定。 # できる

ちゅーとりあるを見ても、背景色の設定はこれであってるはずなのに、ナゼ~。

 parentNodeの参照だから? とか、イベントの中だから? とかとか色々なやむワケですけど、DOM部品作成でいっこいっこ作っていった場合には、イベントの中だろうがparentNodeだろうが、ちゃんと出来たんです。

#できる
A=「table」DOM部品作成
ADOM親部品設定
「tr」DOM部品作成
それ$背景色DOM部品オプション["テーブル背景色"][0]
それDOM親部品設定
「th」DOM部品作成
それテキスト設定
「th」DOM部品作成
それテキスト設定
ADOM親部品設定
「tr」DOM部品作成
それ$背景色DOM部品オプション["テーブル背景色"][2]
それDOM親部品設定
「td」DOM部品作成
それ「あいう」テキスト設定
「td」DOM部品作成
それ「えお」テキスト設定

Aクリックした時には
    対象表示
    対象.parentNode表示
    対象$背景色緑色# できる
    対象.parentNode$背景色水色# できる
ここまで

 長っ💦
 テーブル作成のありがたみを感じますねw

 でも、同じことがテーブル作成ではできないのねん。

#できない
A=「1,2
あいう,えお」
テーブル作成

Aクリックした時には
    対象表示
    対象$parentNode表示
    対象$背景色緑色# できない
    対象$parentNode$背景色水色# できない
ここまで

 ナゾだわ~。
 さっぱり分からにゃいのでもうフツーにDOMスタイル設定😅

行選択できました

 それはさておき、できました。
 こんな感じ?

テストデータ「名前,ふりがな,点数
太郎,たろう,55
花子,はなこ,100
一郎,いちろう,80」
CSV取得
テストテーブルテストデータテーブル作成

選択行色「#CCF」
前クリックセル
テストテーブルマウス押した時には:
    
もし対象.nodeName「TD」ならば:
        
変数 クリック行対象.parentNode
        もし前クリックセルでなければ:
            
変数 前行数前クリックセルセル行番号
            変数 前クリック行前クリックセル.parentNode
            変数 行色情報DOM部品オプション.テーブル背景色
            変数 前背景色行色情報[前行数%2+1]
            前クリック行「背景色」前背景色DOMスタイル設定
        クリック行「背景色」選択行色DOMスタイル設定
        前クリックセル対象

●(セルの)セル行番号
    セル.parentNode.rowIndex戻す
ここまで

行選択のサンプルです👇

 クリックしたらその行の色が変わります。そんだけ!

自動ソート機能を追加

 自動と言っても本当の自動ではなく、ヘッダ部分をクリックすることでソートが行われる機能です。

 なでしこさんには「表ソート」という命令があり、二次元配列の列番号を指定することで、その列をキーにソートしてくれます。
 クリックしたセルの列番号を取得して、元データを表ソートし、そのデータでテーブル更新すれば良いだけ!
 編集の時とは逆に、まずデータの方に変更を加え、テーブルに反映させる形です。
 同様にしてサーチ機能なども実装できるはずです(今回はやりません)

 注意点としては、テーブル作成は一番最初の行がタイトル行(ヘッダ)になっているので、それをソートに含めてはいけないので、データの0行目を一度切り取って待避し、ソート後また戻しています。

テストデータ「名前,ふりがな,点数
太郎,たろう,55
花子,はなこ,100
一郎,いちろう,80」
CSV取得
テストテーブルテストデータテーブル作成

昇順はい
テストテーブルクリックした時には
    もし対象.nodeName「TH」ならば:
        
ヘッダテストデータ0配列切り取り
        対象セル列番号
        テストデータ表ソート
        もし昇順はいでなければテストデータ配列逆順
        昇順=昇順*-1
        テストデータ0ヘッダ配列挿入
        テストテーブルテストデータテーブル更新
ここまで

●(セルの)セル列番号
    セル.cellIndex戻す
ここまで

 できました!

表ソートと表数値ソート

 表ソートは文字列順、表数値ソートは数値順ということなので、数値だけの列は表数値ソートになるようにしなきゃダメかな? と思ったのですが、あれれ~? 表ソートのままでも数値の列もいい感じにソートされてるっぽい?

 v1のグリッドでは「55,100,80」などを自動ソートすると、「100,55,80」とかになっちゃうんです。数字の大小ではなく文字として、1は5の前ということですよねー。
 v1にも表数値ソートはあるので、数値の列でソートしたい場合は自分で何とかする必要がありました。
 でも、なでしこ3の表ソートではちゃんと「55,80,100」になりますよ。
 とりあえずこのままでいいかも?

ソート記号をつける

 v1のグリッドでは、どの列でソート中なのか、昇順なのか降順なのかが分かるよう、ヘッダに「▲」「▼」の記号が付きます。
 なんかCSSで上下に三角の矢印出すなどもあったのですが、むじゅかしくてよく分かんなかったので、フツーに昇順降順で「▲」か「▼」の文字を表示させることにしとく。

テストテーブルクリックした時には
    # 三角のラベルをクリックした時も動くようにする
    もし(対象.nodeName「TH」)また(対象.nodeName「SPAN」)ならば:
        
セル対象
        もし(対象.nodeName「SPAN」)ならばセル対象.parentNode
        ソート列セルセル列番号
        ヘッダテストデータ0配列切り取り
        テストデータソート列表ソート
        もし昇順はいでなければテストデータ配列逆順
        昇順=昇順*-1
        テストデータ0ヘッダ配列挿入
        テストテーブルテストデータテーブル更新
        記号「▲」
        もし昇順=はいならば記号「▼」
        ソート列記号ソート記号追加
ここまで

●(列に記号の)ソート記号追加
    変数 全ヘッダテストテーブル「th」DOM子要素全取得
    母艦DOM親要素
    全ヘッダ反復:
      
対象DOM親部品設定
      もし対象キーならば:
            
記号ラベル作成
            それ{
                "margin-left":"0.5em",
                "vertical-align":"middle",
                "font-size":"0.7em",
                "色":灰色
            }DOMスタイル一括設定
    母艦DOM親部品設定
ここまで

 できました! いい感じ?

セル幅の変更

 v1のグリッドでは、ヘッダ部分をドラッグしてセル幅を変更できます。
 テーブル部品のセル幅は内容に応じて自動的に良きように調整されるので、あんまりいらないかもと思いましたが、勝手に調整されない設定にしたい場合もあるかもしれないし、何より出来るとかっこいいw

 CSSで出来そうかなと思って調べたら、resizeというスタイルがありました‼️
 マウスを動かしたイベントやら位置や移動量なんて一切考える必要なさそうです。
 値は、bothで縦横可変、horizontal幅だけ、vertical高さだけ。不可はnone
 今回はセルの幅だけ変えられたら良いので、全てのヘッダ(th)の「resize」に「horizontal」をDOMスタイル設定すれば良いはず。

変数 全ヘッダテストテーブル「th」DOM子要素全取得
全ヘッダ反復:
  
対象「resize」「horizontal」DOMスタイル設定

 でも出来ない!

 さらに調べると、overflowvisibleになっているとresizeが働かないということで、hiddenに設定。
 でもでも出来ない!!

 さらにさらに調べると、Chromeはこれだけで出来るのですが(できた!)Firefoxの場合は出来ず、thの中にdivを入れて、そのdivにこの設定を付けてやらなければいけないとのこと。にゃにぃ~💧

テストテーブル「名前,ふりがな,点数
太郎,たろう,55
花子,はなこ,100
一郎,いちろう,80」
テーブル作成

# ヘッダの設定
変数 全ヘッダテストテーブル「th」DOM子要素全取得
全ヘッダ反復:
    
# ヘッダのテキストを新しく作ったdivの中にうつす
    テキスト対象テキスト取得
    対象テキスト設定
    対象DOM親部品設定
    「div」DOM部品作成
    それテキストテキスト設定
    # リサイズの設定。horizontalが横幅。
    # overflowがvisibleになっているとresizeが効かない
    # white-space:nowrapで狭くした時に文字が折り返すのを止める。
    それ{
        "resize":"horizontal",
        "overflow":"hidden",
        "white-space":"nowrap"
    }DOMスタイル一括設定

 できました!
 でもthに余白がついているために、見た目がビミョーなことになっています💧

リサイズできるけど.jpg

 thの余白は0にして、セルの余白はdivの方に付ける必要がありそうです・・・が! 元々thに付いている余白のサイズは一体どうやって取得したらいいんだ。
 DOMスタイル取得では、要素自体にスタイルが設定されている場合しか取得できません。試しにやってみると、空が返ってきました。
 貯蔵庫のスタイルシートで0.4emが付いてることは分かってるんだけどさー。ソレを決め打ちするっていうのはアレですよね? ある種負けみたいなw
 調査のレイアウトで見れるんだから、なんかかんか取得する手立てがありそうなもんだ。

getComputedStyleを知る‼️

 WINDOWオブジェクトにgetComputedStyle()というメソッドがあって、引数にDOM要素を与えると、CSSプロパティ情報をオブジェクトとして取得することが出来るラシイ。
 早速やってみます!

WINDOW「getComputedStyle」対象JSメソッド実行
それ.padding表示

 6.4pxと出ました。合っています! すばらしい。
 しかもemで付けられていてもpxに換算されて出てくるようです。
 これをdivのほうに付けてやり、ヘッダの余白は0とすれば、ヘッダの枠とdivがピッタリ重なりいい感じ🎶
 ちなみにこれは「それ.余白」にはできませんでした。

 なお今回はスタイルの内容をそっくりdivに移すのが目的なので良いですが、単位付きでの取得となるので数値が欲しい場合は単位を削除する必要があります。
 またpaddingは上右下左をまとめて設定出来るヤツなので、設定によっては「1px 2px 4px 2px」などと取得されますので注意が必要です。

 おっと、もちろんwidthも取得出来ますよ。
 すごく狭くした時文字が折り返されてヘッダの高さが伸びてしまうのイヤンなので、

文字が縦になる.jpg

white-space:nowrapなど付けてみていましたが、むしろもうdivの最小サイズを親要素のヘッダの幅に設定してやればよいのでは?!

# ヘッダの設定
変数 全ヘッダテストテーブル「th」DOM子要素全取得
全ヘッダ反復:
    
# ヘッダの余白サイズを調べ、ヘッダの余白は0にする。
    WINDOW「getComputedStyle」対象JSメソッド実行
    余白サイズそれ.padding
    最小幅それ.width
    対象.余白0
    # ヘッダのテキストを新しく作ったdivの中にうつす
    テキスト対象テキスト取得
    対象テキスト設定
    対象DOM親部品設定
    「div」DOM部品作成
    それテキストテキスト設定
    # リサイズの設定。horizontalが横幅。
    # overflowがvisibleになっているとresizeが効かない
    # min-widthでヘッダの幅より小さくならないようにする。
    # ヘッダの余白をうつす
    それ{
        "resize":"horizontal",
        "overflow":"hidden",
        "min-width":最小幅,
        "余白":余白サイズ
    }DOMスタイル一括設定

 できました✨

続くかも知れないし続かないかも知れない

 ユキノはgetComputedStyleのじゅもんをおぼえた!

 これでグリッド部品の、あると良さそうな機能はだいたい出来たかなあと思います。
 他にまだナニカあるでしょうか。
 ワタクシ一回しかグリッド部品使ったことなかったものですから~😅

 今回はバラバラの状態でそれぞれお試ししましたが、全部おまとめしてグリッド部品のようにしたら良いのかなあとか、そーゆうのはよく出来たライブラリにおまかせして、テーブル部品に欲しい機能をチョコッと追加出来るようになっていると良いのかなぁとかとか色々考えるわけですが、知恵と時間が追い付かず文字数も結構なものになりましたので、一通りできたよ! というところでひとまず終了です。

 しかし、相変わらず書くこと無くてピンチなので、なんかかんか考えて続く可能性も無くはありません。
 アドベントカレンダー、後半はまだまだいっぱい空いています。
 ぜひぜひご参加下さいませ~🙇‍♀️

3
2
2

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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?