やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

vue3でラジオボタングループのコンポーネントをつくるときの考察2(HTML)

 グループにまとめるときの話。

 前回↓のつづき。

ラジオボタン

 以下のようなラジオボタンがあったとする。

あなたの性別は?

⦿ 男
❍ 女
<input type="radio" id="sex_m" name="sex" value="m">
<label             for="sex_m"></label>
<input type="radio" id="sex_f" name="sex" value="f">
<label             for="sex_f"></label>

<label>の中に<input>を入れる

 <label>の中に<input>を入れてしまうと表示の順が逆になってしまう。for属性が省略できてよかったのだが、残念。

男 ⦿
女 ❍
<label><input type="radio" id="sex_m"></label>
<label><input type="radio" id="sex_f"></label>

<fieldset>で囲む

 ふつう<input><fieldset>で囲む。

<fieldset>
  <input type="radio" id="sex_m" name="sex" value="m">
  <label             for="sex_m"></label>
  <input type="radio" id="sex_f" name="sex" value="f">
  <label             for="sex_f"></label>
</fieldset>

name属性は省略できなかった

 <fieldset>name属性で、<input>name属性を省略できないかと思ったが、できなかった。以下は2つのラジオボタンが同時に選択できてしまう。

<fieldset name="sex">
  <input type="radio" id="sex_m" value="m">
  <label             for="sex_m"></label>
  <input type="radio" id="sex_f" value="f">
  <label             for="sex_f"></label>
</fieldset>

グループ化するにはnameを同じにする  おなじグループにしたいラジオボタンは、name属性におなじ値をつけねばならない。これが面倒くさい。グループ化しているんだから、その中のどれかひとつを選ぶべきだと察して欲しかった。ラジオボタンは「どれかひとつ」を選ぶUIなのだから。なのに、<fieldset>で囲ってもnameをおなじにしないとダメ。

 なんて面倒なんだ。こんなもの毎回書きたくない! Vueでコンポーネントにするときは、こういうところを省略できるようにしたい。

 nameはグループ化する属性である。そもそも、nameという属性名からその役割がわかりにくい。その<input>タグ固有の名前をつけるための属性かと思ってしまう。しかしてnameの役割は、ラジオボタンのグループ化であった。

 グループ名は別のグループと異なる値であるべき。そんな名前を毎回考えねばならない。面倒くさすぎて死にそう。もうHTMLやめるわ。W3Cいらんわ。

 改善するにはどうしたらいい? 考えてみる。

 ある<fieldset>内に入ったラジオボタン内のうちどれか1つだけを選ぶという動作をデフォルトにして欲しかった。nameでグループ化せずにすむ。一意な名前を考えずに済む。離れたところにあるラジオボタンをおなじグループにできない問題がある。しかしそのときはfor属性で紐付けるようにすればいい。基本的にそんなトリッキーな見せ方はしないのだから。

 もっといえば以下のようにして欲しかった。なんだよ<input>って。違うUIなのに共用するなよ。中には<textarea>,<select>,<button>という共用しないUIまであるし。統一性がなさすぎてクソ。

 <input>type属性値にいたっては以下21種もある。多すぎィ! しかも同系統にバリデーションがついただけの類似版が多い。大グループを別のタグにして、あとは属性で設定するようにしたほうがわかりやすいだろ。やっぱクソだわ。

  • hidden
  • button
    • submit
    • reset
    • image
  • checkbox
    • radio
  • text
    • search
    • tel
    • url
    • email
    • password
  • file
  • datetime
    • date
    • month
    • week
    • time
    • datetime-local
  • color

 というかラジオボタン<select>の一種では? 以下のようにすればよかったのに。

<select type="list|combobox|check|radio|togglebutton">

 でも異なるUIをtypeで指定するのは<input>と同じでわかりにくい。もうそのものズバリなタグを作って欲しい。以下のように。

<radio id="sex">
  <option label="男" value="m">
  <option label="女" value="f">
</radio>

<radio for="sex">
  <option label="レズビアン" value="l">
  <option label="ゲイ" value="g">
  <option label="バイセクシャル" value="b">
  <option label="トランスジェンダー" value="t">
</radio>

 というか、無名の要素って書けないの? いちいちoptionウザいんだよ。option以外は入れないんだからわかるわボケ。

<radio id="sex">
  </ label="男" value="m">
  </ label="女" value="f">
</radio>

<radio for="sex">
  </ label="レズビアン" value="l">
  </ label="ゲイ" value="g">
  </ label="バイセクシャル" value="b">
  </ label="トランスジェンダー" value="t">
</radio>

 属性名もウザい。どうせ同じものしか使わないのなら、最初に定義して省略すればいい。

<radio id="sex">
  <template label="{type:String,required:true,validation(v)=>{return true;}}" value="{type:String,required:true,validation(v)=>{return true;}}">
    "男","m"
    "女","f"
  </template>
</radio>

 <radio>の項目って他にどんな属性がありうる? titleとか? <img>を入れるかもしれない。それも全部文字列にして入れたらいいやん。

 とにかく第一引数は表示用タグ。第二引数は内部値。それだけあれば十分だろ。

<radio id="sex">
    "男","m"
    "女","f"
  </template>
</radio>
<radio id="sex">
    "<img src="m.png"></img>","m"
    "<img src="f.png"></img>","f"
  </template>
</radio>

 もうHTMLじゃない。XMLでもない。マークアップ言語ですらない。別ファイルにしちゃえ。

<radio id="sex" from="radio-sex.csv"></radio>

radio-sex.csv

男,m
女,f

 もうHTMLやめよう。以下でいい。わかるべ? タグとか面倒くさいんだわ。

radio id=sex
  男,m
  女,f

 idタグも省略できるだろ。

radio sex
  男,m
  女,f

<ul>で囲む

<ul>
  <li>
    <input type="radio" id="sex_m" name="sex" value="m">
    <label             for="sex_m"></label>
  </li>
  <li>
    <input type="radio" id="sex_f" name="sex" value="f">
    <label             for="sex_f"></label>
  </li>
</ul>

 グループ化の意味としては、この2階層がしっくりくる。これを最終形にしよう。

要素がムダに多い  ラジオボタン1つ作るのに<input>,<label>で1セットというのが冗長だろ。むしろどちらか一方しかないラジオボタンなんて存在するの? ないよね? だったら最初から1セットにしろよ。<option>使えばいいやん。やっぱHTMLってクソだわ。

<radio>
  <option value="m"></option>
  <option value="f"></option>
</radio>

対象環境