add_settings_field関数のパラメータに$idがありますが、
input要素のid属性と同じにする必要はあるのかないのか、
同じにするとしてもその理由は何?と、(非常に)気になったので色々調べてみました。
結論としては以下。
- 同じにする必要はない
- add_settings_field関数内で「'label_for'」を指定する場合には、同じにする必要あり
詳しくは、以下覚書を見てみてください。
Contents
"label_for"とadd_settings_field
add_settings_field関数内で、label for を使うかどうか設定ができますが、「label_for」とは、設定項目の項目名をクリックしたとき、入力ボックスやラジオボタンがクリックされたのと同じにする、といったHTMLの記述法の1つ。
その1: label for を使う
1 2 |
<label for="id_movie">映画が好き </label> <input type="checkbox" id="id_movie" name="movie"> |
項目名の「映画が好き」をクリックしても、ラジオボタンをクリックしても、どちらも同じ動作になると思います。
この「label for」を使う場合には、
input要素内の id属性と「label for」で指定するidは同じにする、
といった決まりがあります。
(同じidを設定して関連付けを行ってるんですね)
(ちなみにこの関連付けはブラウザがやってるのだ)
この label for を使う場合、
input要素内で指定している id属性と
add_settings_field関数内で指定する$idとは同じにする必要があります。
その2: label だけにしてみる
「label_for」を使わずに、単に「label」としてみると...
1 2 |
<label>映画が好き</label> <input type="checkbox" id="id_movie" name="movie"> |
「label」だけでは、「映画を好き」をクリックしてもなにも動作しません。
「項目名」をクリックしてもなにも動作しないほうが良い、という場合には、
単に labelタグを使っておけばよいですね。
この場合、input要素内で指定している id属性は
add_settings_fieldで指定する $id と同じ必要なし。
その3: label だけでも label for と同じにできる
ちょっと書き方を変えて、
<label>映画が好き<input xxxx></label>
と、全体を<label>~</label>で囲むと、「label_for」を使った場合と同じ動作にできますね。
1 |
<labe>映画が好き<input type="checkbox" id="id_movie" name="movie"></label> |
その1に同じく、項目名の「映画が好き」をクリックすると、
ラジオボタンをクリックしても、どちらも同じ動作になると思います。
この場合も、input要素内で指定している id属性は
add_settings_field内で指定する id と同じでなくてもOK。
つまり add_settings_field の $id の扱いは?
- add_settings_field関数の中で label_for の指定をしなければ、add_settings_field関数内で設定する $id は、input要素などの id属性と一致する必要はない
- label for を指定したい場合には、input要素などのid属性と一致させる
ということになりそうです。
add_settings_fieldで"label_for"を指定するには
add_settings_field関数で label_for を設定するには、以下のようにすればOK。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function test(){ add_settings_field( 'id_movie', // ① $id '映画が好き', // ② $title(項目名) 'callback_func', // ③ $callback(コールバック関数名) 'setting-slug', // ④ $page(ページのスラッグ) 'section_id', // ⑤ $section(表示するセクションのID) array( 'label_for' => 'id_movie' ) // ⑥ 'label_for'の指定。①のidを入れる ); } // コールバック関数 function callback_func(){ // input要素など html出力を書く echo '<input type="checkbox" id="id_movie" name="movie">'; } |
8行目に、lagel_forを使うんで idは「id_movie」を使ってね、と指定。
3行目の id を使い、
15行目 input要素内の id にも同じ値をセット。
このコードを実際に実行してみてHTMLがどうなっているか見てみると
以下のようになってます。
- ①:「label for」がついて、
id としてadd_settings_fieldで指定した $id (id_movie)がセットされている - ②:コールバック関数で記述した内容が表示されている
label for の id と input要素内の id属性が一致しているので、
「映画が好き」(項目名)をクリックしても動作する、ということになりますね。
ちなみに、label for は使わないよ、という場合では
第6引数(8行目)は省略してもOK。
実際以下のように先ほどのコードの8行目を削除して実行してみてみると...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function test(){ add_settings_field( 'id_movie', // ① $id '映画が好き', // ② $title(項目名) 'callback_func', // ③ $callback(コールバック関数名) 'setting-slug', // ④ $page(ページのスラッグ) 'section_id' // ⑤ $section(表示するセクションのID) ); } // コールバック関数 function callback_func(){ // input要素など html出力を書く echo '<input type="checkbox" id="id_movie" name="movie">'; } |
これを実行すると、HTMLは以下のようになりますね。
label for は付かず、①にみられるように
単に項目名だけがHTML内に埋め込まれただけ。
ちなみにテーブルの形になってますが、
これはSettings API(do_settings_sections)で自動でやってくれます。
全体像の中で id の位置づけを確認してみる
SettingAPIの1つ「add_settings_field」関数について、
関数リファレンスを見ると、idについては以下の説明になってます。
(必須) タグの 'id' 属性に使用する文字列。
まぁ何かの識別のためにやっぱりidは設定しなくちゃね、
なんて思いつつ inputタグのid属性もそろえていたわけです。
(label for の使い方も書かれてなかったのでその存在自体分からなかった)
1行テキスト入力やテキストエリアならそれでも特に問題がない。
困ったのが、複数の input要素を並べる必要のあるチェックボックスやラジオボタン。
1 2 3 |
<input type="radio" id="id_like" name="like" value="好き"> 好き <input type="radio" id="id_like" name="like" value="普通"> 普通 <input type="radio" id="id_like" name="like" value="嫌い"> 嫌い |
何も考えずに関数リファレンス通りにすると、
id属性にすべて同じ値(ここでは「id_like」)を設定することになる。
HTML的に(というかCSS的に)1つのページ内ではidは重複できない。
(唯一となる文字列でつける必要がある)
あれれ?これどうしたらいいの?と悩むこと丸二日(時間かけすぎ笑)。
もしかして関数リファレンスが間違っているのか
(いや公式ドキュメントだから間違っていたらすぐ訂正されるはず...)
何か見落としてないか
(と何度読み返してもらちが明かない)
ネットで調べても説明している人もいなさそうで(単に、id はそろえなくても動作する、ぐらいの説明はあり)、英語で検索して海外の人のページも参考にしたけど結局わからず。
その中で唯一 「add_settings_field の id について混乱した」と、私と同じ思いの方(同士だ!笑)のコメントをようやく発見できたのが、add_settings_fieldの関数リファレンスの本家の英語ページ。
id についての説明は日本語版の関数リファレンスに同じですが、下方にある「User Contributed Notes」(貢献したメモ)の中の no.1で質問のやり取りがありますね。
分かったのが以下ぐらい。
- add_settings_field でセットされた id はワードプレスの内部管理($wp_settings_fields)で使っているだけ
- ワードプレスはコールバック関数で書かれた HTMLは関知しない
(ので、id を合わせるのはちゃんとやってね) - label_for を使う場合には、ブラウザがどの input とラベル(項目名)がセットになるか理解できるように同じ id を使ってね
ここでようやく label for に関係している、というのが分かりました。(遅い!)
add_settings_field で設定する id はワードプレスが内部管理で使う、ワードプレスは実際のHTMLは関与しない、となると、結果として add_settings_field内で label_for を使うようにするかどうかで、input要素などの id と一致させるかどうかだけがポイント、ということになりそうです。
ここで改めて add_settings_field を含めた Settings API の全体像と、その中での add_settings_field の id の位置づけを簡単にイメージでまとめてみると、以下のような感じになるでしょうか。
- ①:input 要素を表示する設定ページがあり、
- ②:そのページに表示するセクションがあり、
- ③:そのセクションに含まれるフィールドがあり、
そのフィールドの中で、HTMLを表示する関数(コールバック関数)が指定され、 - ④:そのコールバック関数で実際に input要素などが表示され、
- ⑤:Submitボタンが押されると、ブラウザがフォームのデータを nameとvalue のセットで ⑥ options.php へ送り、
- ⑥:データを受け取った options.php は適切にそのデータを処理する
表面的な見方ですが、こうしてみると
③のフィール(add_settings_field)で設定する id (上の例では 'function_id')は、”label for” にしか使われてない。
input要素では、HTML的に id属性は必須ではないので、必要なければそもそも書く必要もない。(JavaScript や css で利用することを考えて何かしらつけておくのが良いですが)
つまり、add_settings_field関数で label for を使わなければ、add_settings_field関数で指定する id と、input要素などの id属性は、一致させる必要がない、ということになりそうです。
補足) label for の id と input要素の id属性さえ合えばいいのでは?
補足ですが、上の方で見た以下のコード。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function test(){ add_settings_field( 'id_movie', // ① $id '映画が好き', // ② $title(項目名) 'callback_func', // ③ $callback(コールバック関数名) 'setting-slug', // ④ $page(ページのスラッグ) 'section_id', // ⑤ $section(表示するセクションのID) array( 'label_for' => 'id_movie' ) // ⑥ 'label_for'の指定。①のidを入れる ); } // コールバック関数 function callback_func(){ // input要素など html出力を書く echo '<input type="checkbox" id="id_movie" name="movie">'; } |
label for を使う場合、input要素内のid属性と label for の id が同じであることがポイント。
さらに、add_settings_field の $id は、ワードプレスの内部管理で使うだけ、となると、上のコードの8行目と15行目で指定する id さえ同じであればよくて、3行目で指定する $id は特に気にしなくてよいようにも見えます。
試しに、8行目と15行目で指定するid を ” id_movie2 ” とかにして3行目の id とは異なるものにして実際動作させてみると、特に問題なく動いてそう。
つまりは、add_settings_field の $id はワードプレスの内部管理だけに使われるもの、というのが結論の中の結論になりそうです。