検索フィールド(その1)。
Safariでご覧になっている方は既にお気づきかと思いますが、このBlogのテンプレートはSafariのRSSリーダーっぽい見た目にしてあります。
小学生の頃ちょっと流行ってた、お年玉付きハガキのウラ面にオモテ面よろしく郵便番号枠やら切手やら宛名やらをそっくりそのまま描いた「両面オモテ面年賀状」(あまりに精密に描きすぎてウラ面の切手(=ニセモノ)部分に消印が押されて届いたって逸話アリ)みたいなノリかどうかは知りませんが、Safariユーザーがちょっとニヤっとするようなのを狙ってたり。
その関係で、右上にある検索欄は<input type="search">を用いています。最近流行ってるってわけでもないですが、ウチのリンクにあるMac系の情報サイトなんかでも最近こぞって採用しているようです。てゆーかapple.comでも積極的に使われてますね。
これはSafariで見ると角丸で左側に虫眼鏡のアイコンが付いたフィールドになり、一目見て検索フィールドだと解かるだけでなく、以前検索した履歴をプルダウンメニューで選択できちゃったりして非常に秀逸。
単に検索窓として優秀なだけでなく、ちょっと応用すればいろいろ使えそうで、複雑になりがちなフォーム部分の省スペース化とユーザビリティの向上に繋がりそう。
惜しむべくはこれがSafari独自の機能であるということ。(X)HTMLの仕様では定義されていないのでこれを用いるとvalidにならないし(別にvalidじゃなくていいじゃんって話はおいといて)、当然ほかのブラウザでは解釈されず、単なるテキストフィールドになってしまいます。
そこで、Web標準の技術で他のブラウザでもこいつと同等の機能が提供できないか考えてみようと思います。まあ検索フィールドにおいて過去の検索履歴を再度参照するようなシチュエーションがどれだけあるかってのは正直微妙なところなので、ちょっと汎用性も考慮して「以前入力した履歴をプルダウンメニューから選択して再度入力できるテキストフィールド」というのを目指してみます。これなら需要ありそうですよね。
長くなりそうなので数回に分けて書く予定。
一番簡単なのはテキストフィールドの下にselect要素を用意して、二つに同じname属性を指定しちゃうこと。プルダウンメニューと聞いてぱっと思いつくのはselect要素ですね。
サンプル1。
もちろん複数の要素に対して同じnameを設定するってのは反則です。また実用上の問題としても、同じname属性が設定されたform構成要素が2つ以上ある場合、最後に送信されたデータ以外すべて無効になる(環境によって違うかも?)ようなので、片方をあらかじめ無効(disabled="disabled")にしておく必要があります。
サンプルではラジオボタンを用いて二者択一にするついでにフォーカスとかいろいろ工夫して一定のユーザビリティを確保してありますが、スペースが余計に必要だったり複雑だったりするうえ前述のような問題もあるのであんまりスマートな方法ではないですね。
select要素のonChangeイベントを使ってテキストフィールドの内容を書き替えるってのはどうでしょうか。
サンプル2。
ラジオボタンは削れましたがスペース的にはサンプル1とたいしてかわりません。ていうか履歴を選択したあと同じ値の入ったテキストフィールドとselect要素が並んでるのはいかにも無駄って感じがしてマヌケですね。
じゃあ"display"を操作して隠したりしてみたらどうか。
サンプル3。
基本的にはサンプル2と同じですがselect要素を非表示にして、別のところをクリックして表示させるようにしたものです。この際にテキストフィールドを非表示にすることであたかも切り替わるような雰囲気に。select要素を操作すると自動的にテキストフィールドに戻るように仕掛けてあります。
これはこれで使えそうですが、クリックして切り替えてからまたクリックしてメニュー出さなきゃいけないあたりが使いにくい。また、一度プルダウンメニューを表示させてしまうと選択するまでテキストフィールドに戻れないため、別に何らかの戻る手段を用意しないとダメです。
あとサンプル2とサンプル3はselect要素を単にプルダウンメニューのUIとして使用しているわけですが、当然select要素もフォームエレメントのひとつなので、form内に含まれているとsubmit時に値を送信してしまう可能性があります。そうなるとサーバプログラム側(データを受け取る側)での処理が必要になってきちゃいそう。もちろんHTMLの組み方次第で解決する方法もありそうですが。
そんな感じで、一見近道そうなselect要素をプルダウンメニューとして用いる方法は、いろんな面であんまりよろしくないような気がしてきました。さあどうしよう。
つづく。