3
1

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 25

なでしこさんにグリッドが欲しい❗️ 完結編 ~プラグインにするよ!~

Posted at

 この記事は、先の二記事を読んでいる前提で書かれています。

行を追加出来るようにする

 ワタクシうっかりしておりましたが、前編の編集できるテーブルには必要な機能がもう一つありました。
 ユーザーがデータを追加していける機能です。

 v1のグリッドでは必ず最終行に空行が付いてきて、それを利用して新しいデータを追加していくことになっていました。
 と言っても行の追加自体は自分で行う必要があって、たしか最後の空行に文字入力した状態で、

テストグリッドのアイテムはテストグリッドのアイテム

 みたいにすると、また空行が付いた状態に更新されるんだったかな?

 それならもう、いっそ好きに一行追加できるの方が良さそうじゃないですか?
 普通に考えると、データの表行数の位置に空のデータを入れてテーブルセル変更してやるだけで良さそうなんですが・・・

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

テストテーブル[テストデータ表行数,0][[,,]]テーブルセル変更

値のない行は細くなる.jpg

 こんな風に細くなっちゃうのねん💧
 文字が入ってないからね、フォントサイズ分ね(line-heightもかな?)
 この細い状態でもちゃんと文字入力は出来るし、一箇所でも文字が入ればそれに合わせてセルの高さが調整されて揃うので問題ないのですが、やっぱりそんなのかっちょわるいですよね~?! 察して最初から揃えといておくれよ~w

 ここで早速前回覚えた新しいじゅもーん!
 ユキノは getComputedStyle をとなえた!!

WINDOW「getComputedStyle」テストテーブル["rows"][1]["cells"][0]JSメソッド実行
セル高さそれ.height
セル高さ表示

 0行目はヘッダ(タイトル行)なので、実際のデータは1行目から。
 1行目は絶対あるハズなので、その0列目、一番最初のセルの高さを調べてみます。
 24pxと出ました。
 合っています!
 CSSから設定されたフォントサイズや行高さの反映されたセルの高さがバッチリ取得出来ました!
それを、追加された最終行のセルに設定してやれば良いハズ。

 どうせなら簡単に[行,列]で指定して簡単にセルが取得できるといいかな?
 また、空行を追加するのも、ちゃんとデータの列数分セルを追加できるように直して・・・
 こんな感じ?

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

# 末尾に空行を追加
空行空配列
テストデータ表列数空行配列追加。。。
テストテーブル[テストデータ表行数,0][空行]テーブルセル変更

# 最初のセルからセルの高さを取得
WINDOW「getComputedStyle」(テストテーブルから[1,0]テーブルセル取得)JSメソッド実行
セル高さそれ.height//セル高さを表示。

# それを追加された行の0列目のセルに反映
テストテーブルから[テストデータ表行数,0]テーブルセル取得
それ「高さ」セル高さDOMスタイル設定

# [行,列]でセルの要素を取得する
●(テーブルから行列の)テーブルセル取得
    変数 [,]行列
    テーブル["rows"][]["cells"][]戻す
ここまで

一行追加.jpg

 見事サイズの揃った空行が出来ました🎶

編集できるようにする

 でもこれはまだ、ただの空行を追加しただけです。
 追加した行にも編集出来る設定を付けられるようにする必要があります。
 前編の編集出来るテーブルの中心、セルを編集可能にする部分を反復の中に直接書いていましたが、関数にして外へ出し、行追加部分からも呼び出せるようにします。

 そして! ワタクシこれまたうっかりしておりましたが~。
 すでにデータが入ってる部分も、編集で一行全て空にしてしまったら同様に細くなっちゃうんですよね~。
 セル高さの設定は、行追加部分から編集可能設定部分へ移し、全てのセルに行高さを設定しちゃうことにしちゃいます。

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

テストテーブルテストデータテーブル作成
テストテーブルテーブル編集可能

確認ボタン「データ確認」ボタン作成
確認ボタンクリックした時には
    テストデータJSONエンコードして表示
ここまで
追加ボタン「一行追加」ボタン作成
追加ボタンクリックした時には
    テストテーブルテーブル行追加
ここまで

●(テーブルの)テーブル編集可能
    変数 全セルテーブル「td」DOM子要素全取得
    全セル反復テーブル対象編集可能セル設定。。。

    
# セル内の改行入力を禁止する。
    テーブルキー押した時には:
        
もし押されたキー「Enter」ならば:
            
対象イベントDOMイベント処理停止
ここまで

●(テーブルに)テーブル行追加
    空行空配列追加行テストデータ表行数
    テストデータ表列数空行配列追加。。。
    
テーブル[テストデータ表行数,0][空行]テーブルセル変更
    # 追加された行の全セルに編集可能設定を付ける
    テストデータ[追加行]空配列
    テストデータ表列数
        テストデータ[追加行][回数-1]
        テーブルから[追加行,回数-1]テーブルセル取得
        テーブルそれ編集可能セル設定
    ここまで
ここまで

●(テーブルのセルに)編集可能セル設定
    # 最初のセルからセルの高さを取得
    WINDOW「getComputedStyle」(テーブルから[1,0]テーブルセル取得)JSメソッド実行
    セル高さそれ.height//セル高さを表示。
    セル「高さ」セル高さDOMスタイル設定
    セル.contentEditabletrue# 編集可能にする
    セル「blur」DOMイベント発火した時には:
        
もし対象.nodeName「TD」ならば:
            
# 改行を含むコピペ対策
            テキスト対象.textContent
            対象テキストテキスト設定
            # テーブル数値右寄せ
            もしDOM部品オプション.「テーブル数値右寄せ」trueならば
                テキスト数列か判定
                もしそれtrueならば
                    対象「行揃え」「右」DOMスタイル設定
                違えば
                    対象「行揃え」「左」DOMスタイル設定
                ここまで
            ここまで
            # セルの内容をデータに反映
            対象セル行番号
            対象セル列番号
            もし(テストデータ表行数)ならばテストデータ[]空配列
            テストデータ[][]テキスト
ここまで

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

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

●(テーブルから行列の)テーブルセル取得
    変数 [,]行列
    テーブル["rows"][]["cells"][]戻す
ここまで
 できました!

機能を複数付けたい

 これまではとりあえず簡単にやってみるため、機能をそれぞれ別々に作ってきましたが、複数の機能を同時に使いたいことありますよね、当然。
 それぞれを関数化して試してみたところ、うまく行かない部分や、v1のグリッドと動作を合わせるかどうか考えたい部分も出てきました。

編集と行選択

 v1のグリッドでは、この二つは両立しません。
 行選択がオンでも、編集をオンにすると、行選択は無効になります。
 でも別に、あえて無効にすることは無いんじゃない?

 こちらの行選択はtrに色を付けてるだけなので機能が干渉することはないし、編集中の行が分かりやすくなる。
 不要なら行選択を付けなきゃいいだけの話なのでこのままにしておく。

セル幅変更と自動ソート

 自動ソートすると変更したセル幅が元に戻っちゃう! ということが発覚💦
 セル幅を変えようとするとヘッダ部分を触ることになるので自動ソートも勝手に行われてしまうため実質セル幅変更が出来ない。
 自動ソートを、表ソート後テーブル更新することにしていたので、セル幅のみならず色々な設定がまるっと全部書き換えられてしまうのでした
 テーブルセル変更を使ってセル部分だけを更新するように修正。

 また、ソート記号は、セル幅変更が先に設定されている場合はthではなくリサイズ用のdivの方に付けなければ変なことになる。

 セル幅を変えようとすると自動ソートも勝手に行われてしまう件は、v1のグリッドもそうなので、とりあえずよしとすることに(え)

行選択と自動ソート

 自動ソートすると選択状態が消えちゃう問題は👆で自動ソートをテーブルセル変更にしたことで解消。

 行選択中に自動ソートが行われても選択行は変わりません。
 セルの内容が変わっても、一行目なら一行目、三行目なら三行目が選択されたまんま。
 気持ちとしては、選択行は選択していたデータにくっついて移動して欲しい感がないですか?
 でも、これも、v1のグリッドと同じなのでとりあえずそのまま(ええっ)

編集とセル幅変更

 編集で元のセル幅よりも長くなった場合、リサイズを付けたdivとthの幅が合わなくなっちゃう。
 長いデータが入った時、セル幅をデータより狭く出来ない。
 セルのoverflowhiddenにしたり、white-spacenowrapにしたり、text-overflowellipsisにしてみたりなどなどするが、出来ない!
 調べると、divの場合はこれでできるんだけど、テーブルセル内ではもうひとつ、max-widthを付ける必要があるそうです!
 でも、これはこれで問題があって、セル幅の自動調整が効かなくなってしまうのです。
 自動調整はして欲しいけど、リサイズで小さくも出来るようにしたいんですよよよ~。

 苦肉の策として、フォーカスが当たったらmax-widthnoneにしてセル幅の自動調整を有効にし、外れたらmax-widthを0にしてセル幅変更を有効にすることに・・・
 結構いい感じ? なのですが、狭くしてある長い文字列の入ったセルにフォーカスを当てると、セル幅がびよよんっと元に戻っちゃうんですよね~。
 フォーカスを当てるってコトは、中身を見たいか編集したいかなんだから、い、いいよね?💧

自動ソート

 数値の場合の自動ソートが、なぜか後編で作ったサンプルの場合と違うんです!
 数値なのになぜか表数値ソートを使わなくてもいい感じにソートされていたのですが、今はv1同様100が55や80よりも小さいと判定されている。
 なでしこさんのバージョンを揃えてみてもやっぱり結果が異なるので何故なのかサッパリ分からん💧
 もっとも現状が正しい状態のような気はするので、やっぱりそのうち数値は表数値ソートを使えるようにしたい。
 でももう時間が無いのと、これがv1と同じ状態というわけで、とりあえずはこのまま~😅

プラグインにする

 折角なのでプラグインにすることに!

変数をテーブルに持たせる

 テーブルを二つ以上作った場合、「昇順」や「前クリックセル」などの変数が共用になってしまいおかしなコトになっちゃう。
 色の違うテーブルを作ろうものなら、行選択や行追加でDOM部品オプションのテーブル背景色を参照しているため、最後に作ったテーブルの色が反映されちゃう。
 また、これまではとりあえずのお試しだったので、編集や自動ソートでは直接テストデータを編集したり表ソートしたりしているけど、もちろんそんなわけにはいきません。
 個々の設定をそれぞれのテーブルDOMそのものに持たせる必要があります。

データ属性設定とポケット設定

 なでしこさんの新機能の一つです✨
 ポケットについては22日目に、クジラ飛行机氏自ら解説して下さっていますので、是非お読み下さい~。

 ポケットはユーザーが使いたいコトもあるかもしれないから空けておくことにして、データ属性を使います。

👉なでしこ3 マニュアル > plugin_browser/データ属性設定

 好きに名前を付けられていくつも設定出来るのが良い所ですよ。

テーブル「昇順」はいデータ属性設定

 などと設定しておけば、

昇順テーブル「昇順」データ属性取得

 と、取得して、後のコードは今まで通りで出来ます🎶

 
 テーブル背景色は、配列です。
 説明によると、『DOMの制約で基本的に文字列しか設定できません。辞書型や配列型を設定したい場合には「ポケット設定」を使うと良いでしょう』とあるのですが、「JSONエンコード」すればOKです。

テーブル背景色DOM部品オプション.テーブル背景色
テーブル背景色テーブル背景色JSONエンコード
テーブル「背景色」テーブル背景色データ属性設定

 取り出す時はもちろん「JSONデコード」忘れず。

行色情報テーブル「背景色」データ属性取得してJSONデコード

 ポケットも、ユーザーが一手間掛けなくても良いよう、内部でエンコードとデコードを行ってくれているものと思う。

 
 問題は「前クリックセル」。
 さすがにDOMの参照は入れられないしどうすっかなーと思って、直接プロパティに設定してみるとゆう暴挙!

 しかもナゼか、

テーブル.前クリックセル対象

 と、直接代入し、

テーブル「前クリックセル」DOM属性取得

 と、「DOM属性取得」で取得しないとうまく行かないんだよね~(?)
 ・・・とりま、これでうまく動いたからヨシ!🙏

できました

 他にも色々紆余曲折がありましたが!
 取り上げるほどの内容でもない&時間が無いので、はしょって完成です🤣

つかいかた

①取り込みます

『貯蔵庫:tablePlus.nako3』取り込む

 省略記法が便利すぎる🎶

②普通にテーブル作成します

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

③テーブル拡張設定

テストテーブルテーブル拡張設定

 こんだけ!

 

!『貯蔵庫:tablePlus.nako3』を取り込む。
テストテーブル=「名前,ふりがな,点数
太郎,たろう,55
花子,はなこ,100
一郎,いちろう,80」のテーブル作成。
テストテーブルにテーブル拡張設定。

 👇コピペして試してね。

オプション

 デフォルトは全部入りです。

テーブル拡張オプション{
    "選択行色":"#CCCCFF",
    "編集":オン,
    "行選択":オン,
    "自動ソート":オン,
    "セル幅変更":オン
}

 テーブル拡張設定命令のに、テーブル拡張オプションを設定することで、選択して機能を付けたり、行選択の選択行色を変更することができます。

拡張命令

 テーブル拡張設定していないと使えない命令です。

●(テーブルに)テーブル行追加

 テーブルの末尾に全て空セルの行を、一行追加します。
 「編集」で使います。
 (空の行を追加するというのは編集以外ではあまり必要ないと思って、
セル高さの設定が行われないです)

●(テーブルの)テーブルアイテム取得

 編集や自動ソートで変更されたテーブルのデータを取得します。

●(テーブルの)テーブル背景色取得

 テーブルの背景色配列を取得します。
 DOM部品オプションのテーブル背景色と同じ形式なのでDOM部品オプションに設定を戻すのにも使えます。

その他の命令

 テーブル拡張設定していない通常のテーブルにも使えます✨

●(テーブルの行列を色に)セル文字色変更

 テーブル部品、DOM部品オプションで背景色の設定は出来るけど、文字色の設定は出来ないんだよね。
 thの文字色は白色だけど、背景色を薄い色合いにしたい可能性は無いのかい? というわけで作ってみた。

●(テーブルの行列を色に)セル背景色変更

 セルに自由に色を付けたい要望は結構v1のグリッドでも繰り返しあったので作ってみました。

 しかーし!
 これがまた自動ソートすると、データは動いてもセルの位置は変わらないので、データと色がずれちゃうよね😭
 そのうち自動ソートの方法を見直したい。

●(テーブルから行列の)テーブルセル取得

 [行,列]を指定して、td要素が取得できます。

●(テーブルから行の)テーブル行取得

 列を指定してtr要素が取得できます。

おわります

 今年もギリでなんとか間に合い、今年もアドベントカレンダー、全て埋めることが出来ました。
 なんと今回は参加者10人と過去最高の記録でした!
 本当にありがとうございました✨

3
1
1

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?