背景
Pug(旧称Jade)で checked などの真偽型属性を条件に応じて付与したりしなかったりしたい場合、どうすれば良いのか。従業員に質問されて、たしかにちょっとわかりにくいかなと思ったので、今後同じところで迷う人のために書いておく。
前提
HTML5では checked 属性のような真偽型の属性に対して許容されている値は空文字から属性値と同じ値(大文字小文字は区別しない)のいずれかのみである(W3C)。またそれ以外の文字列("false"など)が指定された場合は不正値として空文字と同じように処理される。
したがって実際のブラウザの挙動では以下はいずれもチェック状態となる。
<!-- 以下は正しい -->
<input type="checkbox" value="1" checked>
<input type="checkbox" value="1" checked="">
<input type="checkbox" value="1" checked="checked">
<!-- 以下は不正だがチェック状態として処理される -->
<input type="checkbox" value="1" checked="false">
<input type="checkbox" value="1" checked="0">
<input type="checkbox" value="1" checked="null">
Pug で属性の存在自体を条件により切り替えるには?
上記のことから、変数の値を書き換えても属性が存在するだけで必ず真偽型の属性は真扱いとなってしまうので、チェック/非チェックを条件に応じて切り替えたい場合、属性の存在自体を出し分ける必要がある。これは簡単で、属性値として true / false を与えてしまえば良い。引用符では囲まない。
//- 真
input(type='checkbox' checked=true)
// → <input type="checkbox" checked>
//- 偽
input(type='checkbox' checked=false)
// → <input type="checkbox">
したがって特定の条件を満たすときのみ checked 属性を付与したいのであれば以下のように書く。
//- 5番目にチェックつける
//- checked=(i === 4) のカッコはなくてもOKだが、あったほうが見やすいと思うので付与している
- for (var i = 0; i < 10; i++)
input(type='checkbox' checked=(i === 4))
上記は selected や disabled 属性などでも同様である。
余談1 文字列型属性の場合
三項式を使う。
- for (var i = 0; i < 10; i++)
input(type='checkbox' value=(i == 4) ? "yes" : "no")
余談2 Qiita 投稿について
Qiita は未だにシンタックスハイライトの設定で "pug" ではなく "jade" を指定する必要があるらしい。
しかも上の条件式のところシンタックスハイライトがおかしくなっている……。