オートコンプリートは、ウェブユーザーなら誰でも知っているパターンです。 検索を行うと、検索エンジンは用語を提案します。 新しい電子メール メッセージを入力すると、メール クライアントが受信者を提案します。 しかし、このような機能は、ウェブ開発者が膨大な量のJavaScriptを使用しなければ利用できませんでした。 HTML5の新しい要素の一つである , は、このオートコンプリート機能をウェブ上でネイティブに提供します。 この記事では、データリストとは何か、どのような場合に使用するのが適切か、その限界と、データリストをサポートしていないブラウザへの対処法について説明します。

始める前に

HTML5を使わずにサイトにデータリストを作成したいとお考えですか? JotFormを使えば、コーディング不要で、カスタムドロップダウンメニューや複雑なダイナミックドロップダウンを素早く構築することができます。

データリストの作成

データリストがどのように機能するかを説明するために、従来のテキスト入力から始めましょう。</label>

  • <input type=”text” name=”team” id=”favorite_team”>
  • このフィールドでは、ユーザーにお気に入りのスポーツチームを入力してもらいます。 デフォルトでは、ユーザーにはフィールドを完成させるための追加のヘルプは与えられません。 しかし、データリストを使用すると、ユーザーがフィールドを入力するために選択できるオプションのリストを提供することができます。 そのためには、各提案に対して option 要素を持つデータリストを定義します。

    1. <datalist>
    2. <option></option>
    3. </option></option>
    4. <><>
    5. <option></option>
    6. <!- etc… ->
    7. </datalist>

    データリストを入力要素に結びつけるには、入力要素にlist属性を、データリストにid属性を与えて一致させます。

    1. <label for=”favorite_team”></label>
    2. <input type=”text” name=”team” id=”favorite_team” list=”team_list”>
    3. <datalist id=”team_list”>
    4. <option>Detroit Lions</option>
    5. <><>
    6. <></option>
    7. </option></option>
    8. <!- etc… ->
    9. </datalist>

    inputのlist属性とdatalistのid属性には、同じ値「team_list」が含まれていることに注目してください。

    以上です。 データリストを動作させるのに、JavaScriptは必要ありません。

    Datalist Display
    Figure 1. Datalistの表示(左上。 左上:Internet Explorer 10、右上:Yahoo! 左上:Internet Explorer 10、右上:Firefox 18、左下:Chrome 24 左上:Internet Explorer 10、右上:Firefox 18、左下:Chrome 24、右下:Opera 12。

    注意:Internet Explorer 10とOperaでは、ユーザーが候補を表示する前に文字を入力する必要がありませんが、FirefoxとChromeでは必要です。

    Option要素は、value属性を持つこともできます。 これは、ユーザーが特定のオプションに関連するコードを知らない可能性がある場合に便利です。 次のような米国の州の入力を考えてみましょう。 state input:

    1. <label for=”state”> State:</label>
    2. <input type=”text” name=”state” id=”state” list=”state_list”>
    3. <datalist id=”state_list”>
    4. <option value=”AL”>Alabama</option>
    5. <option value=”AK”>Alaska</option>
    6. <option value=”AZ”></option>
    7. <option value=”AR”>Arkansas</option>
    8. <!- etc ->
    9. </datalist>

    ここでは、ユーザーには完全な州名のリストが表示されますが、ユーザーが選択を行うと、テキスト入力には完全な名前ではなく州のコードが入力されます。 その例を図2に示します。

    対応する値を持つデータリスト・オプションの選択

    図2. 対応する値を持つデータリスト オプションの選択 (Firefox 18)

    オートコンプリート属性

    図1や図2のデータリストに見覚えがあるとしたら、それはブラウザには長い間オートコンプリートが実装されているからです。

    著者は autocomplete 属性を使用して、ブラウザがユーザーのデータを自動的に補完しようとするかどうかを制御できます。

    1. <form>
    2. <!-
    3. オートコンプリート属性が指定されていない場合は、親のform要素の値
    4. を継承します。 指定されていない場合、
    5. フォームのオートコンプリート属性のデフォルト値は「on」です。 この入力もその
    6. フォームも属性が指定されていないので、「on」の状態が使用されます。
    7. ->
    8. <input type=”text” name=”firstName”>
    9. <!-
    10. 「on」の状態は、ブラウザが将来の使用のために値を記憶したり、以前に記憶された値を示唆したりできることを示します。
    11. ->
    12. <input type=”text” name=”address” autocomplete=”on”>
    13. <!-
    14. 「off」の状態は、この入力に対して入力された値を保存することも、以前に入力された値を示唆することもないことをブラウザに伝えます。 これは、データが機密であったり、値が決して再利用されない場合に
    15. 使用されるべきです。
    16. ->
    17. <input type=”text” name=”secret” autocomplete=”off”>
    18. </form>

    では、オートコンプリート属性とデータリストの違いは何でしょうか。 オートコンプリート属性は、以前の入力に基づいてユーザーに補完のための選択肢を与えるかどうか、また、将来の補完のために入力された値を保存するかどうかをブラウザに指示します。

    注意点としては、オートコンプリート属性を「オフ」に設定すると、Opera でデータリストが表示されないことがあります。

    1. <!-
    2. オートコンプリート属性が “off” に設定されているため、このデータリストは Opera で表示されません。 他のすべてのサポートするブラウザでは表示されます。
    3. ->
    4. <input type=”text” list=”pets” autocomplete=”off”>
    5. <datalist id=”pets”>li
    6. <option>Cat</option>
    7. </option>Dog</option>
    8. <></option>
    9. </option></option>
    10. </datalist>

    その他の入力タイプ

    オートコンプリートは伝統的にテキスト入力に関連付けられていますが。 データリストは、HTML5 の新しい入力タイプの多くで使用することができます。 例えば、範囲入力タイプでは、スライダーのフォーム要素を作成することができます。

    たとえば、次の入力では、ユーザーに 5 ドルから 200 ドルの間で寄付をしてもらいます。

    1. <label for=”donation”>Donation Amount (USD)となります。</label>
    2. <input type=”range” name=”donation” id=”donation” list=”donation_list”
    3. step=”5″ min=”5″ max=”200″>
    4. <datalist id=”donation_list”>
    5. <option></option>
    6. <option></option>
    7. <option></option>
    8. <option></option>
    9. </datalist>

    図3と図4は、Chrome 24とInternet Explorer 10での範囲入力の表示を示しています。 での範囲入力の表示を示しています。

    データリストによる範囲入力
    図3. データリストを使った範囲入力 (Chrome 24)

    データリストを使った範囲入力

    図4. データリストによる範囲入力 (Internet Explorer 10)

    各ブラウザでは、提供されているデータリストの各オプションにチェックマークが表示されていることがわかります。

    残念ながら、現時点で範囲入力でデータリストをサポートしているブラウザは、Internet Explorer と Chrome だけです。

    Browser Support of Datalists on Form Input Types
    Figure 5. フォーム入力タイプにおけるデータリストのブラウザサポート

    データリストを使用する場合

    データリストには、ユーザーが提供された選択肢を選択することを要求するメカニズムが組み込まれていないため、任意の値を受け入れることができる入力に適しています。 先ほどのスポーツ チームの提供の例がここに当てはまります。 逆に、米国の州の例では、ユーザーが提供しなければならない有効な値のセットが限られているため、このテストに失敗しました。

    例外として、有効な選択項目が多数ある入力項目があります。

    Standard Country Drop-Down
    Figure 6.のような伝統的な国のドロップダウンリストを考えてみましょう。 標準的な国別ドロップダウン

    このリストは、探しているものを見つけるために何百もの選択肢の中から探すことをユーザーに強いることになり、ユーザーの妨げになります。 オートコンプリート機能は、ユーザーが 1 つまたは 2 つの文字を入力するだけで素早くリストをフィルタリングできるため、このユース ケースによく合います。

    以下に、国の選択をデータリストで実装する方法を示します。

    1. <label for=”country”>Country:</label>
    2. <input type=”text” id=”country” list=”country_list”>
    3. <datalist id=”country_list”>
    4. <option value=”AF”>Afghanistan</option>
    5. <option value=”AX”></option>
    6. < option value=”AL”></option>
    7. <option value=”DZ”></option>
    8. <!- more ->
    9. </datalist>

    図7は、ユーザーが「U」を入力した後に表示される内容です。

    A Datalist Approach to the Country Form Field
    Figure 7. A Datalist Approach to the Country Form Field

    Enforcing a Value

    データリストでは本来、オプションの選択を要求することはできませんが、それを可能にする検証を簡単に追加することができます。 たとえば、次のコードでは、HTML5 の制約検証 API を使用して、そのような検証を追加しています。

    1. //DOM 上で、リスト属性を介してデータリストにバインドされているすべての入力を検索します。
    2. var inputs = document.querySelectorAll(‘input’);
    3. for (var i = 0; i < inputs.length; i++) {
    4. // 入力の値が変わったら…
    5. inputs.addEventListener(‘change’, function() {
    6. var optionFound = false,
    7. datalist = this.list;
    8. // 入力の現在の値でオプションが存在するかどうかを判断します。
    9. for (var j = 0; j < datalist.options.length; j++) {
    10. if (this.value == datalist.options.value) {
    11. optionFound = true;
    12. break;
    13. }
    14. }
    15. // Validation API の setCustomValidity 関数を使用する
    16. // 値が datalist に存在しない場合、ユーザーにフィードバックを提供する
    17. if (optionFound) {
    18. this.
    19. this.setCustomValidity(“);
    20. } else {
    21. this.setCustomValidity(‘Please select a valid value.’);
    22. }
    23. };
    24. }

    制約検証 API は、データリストをサポートするすべてのブラウザーに実装されているため、データリストが動作すれば、検証も同様に動作するはずです。

    Constraint Validation API Error
    図 8. 制約検証APIのエラー (Internet Explorer 10)

    制約検証APIは、サーバーサイドの検証の必要性を排除するものではないことに注意してください。

    このアプローチは、最新のブラウザでは機能しますが、サポートのないブラウザを実行しているユーザーには使いにくいUIを提供します。 ユーザーは有効な値を選択しなければならないと言われますが、ブラウザがデータリストをサポートしていない場合は、選択肢が表示されません。 したがって、この方法を使用する場合は、すべてのブラウザで動作するUIを提供することが不可欠です。

    サポートしていないブラウザ

    この記事の執筆時点では、テキスト入力のためのデータリストは Internet Explorer 10、Firefox 4+、Chrome 20+、Opera でサポートされていますが、残念ながら多くのユーザーはサポートされていません。

    多くの HTML5 の新機能と同様に、ほとんどのユース ケースでは、データリストをサポートしていないブラウザで余分な作業を行う必要はありません。 デフォルトでは、提供されるオプションのリストは単なる提案です。したがって、サポートしていないブラウザを使用しているユーザーは、提案なしでテキスト フィールドに入力する必要があります。

    しかし、サポートしていないブラウザを実行しているユーザーに充実したエクスペリエンスを提供するために、いくつかのフォールバック オプションを使用することができます。

    代替 HTML コンテンツへのフォールバック

    Jeremy Keith 氏によって広められた 1 つのオプションは、datalist 要素をサポートしていないブラウザでも、ユーザーに子要素が表示されるという事実を利用することです。 以下は、国のデータリストの例を変更し、<select>を使用してフォールバックする方法を示しています:

    1. <label for=”country”>Country:</label>
    2. <datalist id=”country_list”>
    3. <select name=”country”>
    4. <option value=”AF”>Afghanistan</option>
    5. <option value=”AX”></option>
    6. <option value=”AL”></option>
    7. <option value=”DZ”></option>
    8. <option value=”AS”></option>
    9. <!- more ->
    10. </select>
    11. その他の場合は、指定してください。
    12. </datalist>
    13. <input type=”text” name=”country” id=”country” list=”country_list”>

    データリストをサポートしているブラウザのユーザーに表示されるUIは変わりません。 しかし、サポートしていないブラウザで作業しているユーザーには、国のオプションを含む select 要素と、任意の値を入力するために使用できるテキスト ボックスが表示されます。

    A Select Fallback for Datalists
    Figure 9: A Select Fallback for Datalists (Internet Explorer 9)

    Polyfilling

    select fallbackが提供しない機能の1つは、データリストがネイティブに提供するオートコンプリートの動作です。

    まず、ユーザーのブラウザーがデータリストをサポートしているかどうかを判断する必要があります。

    1. if (Modernizr.input.list) {
    2. //ブラウザは list 属性と datalists をサポートしています。
    3. } else {
    4. //ブラウザはリスト属性もデータリストもサポートしていません。
    5. }

    この方法を使えば、サポートしていないブラウザのユーザーのために、データリストの実装をポリフィルすることができます。 データリストにはいくつかのポリフィルが用意されていますが、私はjQuery UIのオートコンプリート・ウィジェットを使うのが好きです。 以下のコードは、ポリフィルの実装を示しています:

    1. var datalist,
    2. listAttribute,
    3. options = ;
    4. //ブラウザがリスト属性をサポートしていない場合…
    5. if (!Modernizr.input.list) {
    6. // list属性を持つ各テキスト入力について…
    7. $(‘input’).each(function() {
    8. // 入力のデータリストのIDを見つける
    9. // これを使って、入力に対応するデータリストを見つける
    10. listAttribute = $(this).attr(‘list’);
    11. datalist = $(‘#’ + listAttribute);
    12. // 入力に対応するdatalist要素がある場合…
    13. if (datalist.length > 0) {
    14. options = ;
    15. // オートコンプリートウィジェットに渡すオプションのリストを構築する。
    16. datalist.find(‘option’).each(function() {
    17. options.push({ label: this.innerHTML, value: this.value });
    18. });
    19. // 入力を jQuery UI オートコンプリート ウィジェットに変換します。
    20. $(this).autocomplete({ source: options });
    21. }
    22. });
    23. // すべてのデータリストをDOMから削除し、表示されないようにします。remove();
    24. }

    図10は、jQuery UIのオートコンプリート ポリフィルを使用したSafariでの国リストの例の表示を示しています。

    Country Datalist Polyfilled Using jQuery UI's Autocomplete Widget's Autocomplete Widget
    図10. jQuery UI のオートコンプリート ウィジェットを使用した国別データリストのポリフィル(Safari)

    デフォルトでは、jQuery UI のオートコンプリート ウィジェットはオプションの任意の場所の文字にマッチしますが、データリストは文字列の先頭のみにマッチすることにお気づきでしょうか。 ネイティブのデータリストとは異なり、オートコンプリート ウィジェットでは、これをカスタマイズして、好きなようにオプションをマッチさせることができます。

    次の例では、文字列の先頭でのみオプションを照合するオートコンプリート機能を構築する方法を示しています。

    1. <input type=”text” id=”autocomplete”>
    2. <script>
    3. var options = ;
    4. $(‘#autocomplete’).autocomplete({
    5. // reqには、テキスト入力にある値
    6. を含む “term “プロパティを持つオブジェクトが含まれます。
    7. source: function (req, responseFn) {
    8. // キー入力された用語から、「・」や「^」などのRegExpの意味を持つ文字をエスケープします
    9. var term = $.ui.autocomplete.escapeRegex(req.term),
    10. // 「^」は文字列の先頭にマッチする RegExp 文字です。
    11. // 「i」は RegExp に大文字小文字を区別しないマッチを指示します。
    12. matcher = new RegExp(‘^’ + term, ‘i’),
    13. // オプションをループして、RegExpにマッチしたものだけを選択します。
    14. matches = $.grep(options, function (item) {
    15. return matcher.test(item);
    16. });
    17. // マッチしたオプションを返します。
    18. responseFn(matches);
    19. }
    20. })。)
    21. </script>

    古いバージョンの Internet Explorer

    古いバージョンの Internet Explorer で datalist 要素のポリフィルを動作させるには、2 つの特別な手順を踏む必要があります。

    オプション要素

    1つ目は、Internet Explorer バージョン 9 以前のバージョンでは、option 要素が select 要素の直接の子であることが必要です。 そうでない場合、これらのバージョンでは認識されず、ポリフィルでは表示されません。

    幸い、これは簡単に回避できます。

    幸い、これは簡単に回避できます。条件付きコメントを使用することで、これらのバージョンのInternet Explorerでのみ使用可能なオプションの周りにselect要素を配置することができます。

    1. <datalist>
    2. <><select><<>
    3. <></option>
    4. </option>Banana</option>
    5. <option>Cherry</option>
    6. <!- etc ->
    7. <><select><<>
    8. </datalist>

    Internet Explorer バージョン 9 以前のバージョンでは、オプションを適切に検出するようになりました。 Internet Explorer 10では条件付きコメントがパーサーから削除されたため、Internet Explorer 10は影響を受けません。

    HTML5 Shiv

    Internet Explorer バージョン 8 以前では、未知の要素は子を含むことができません。 そのため、データリストの option 要素が select 要素の中にあっても、認識されません。

    幸いなことに、この問題にも簡単な修正方法があります。 人気のある HTML5 Shiv ライブラリは、Internet Explorer 6-8 にとって未知の要素が子を持つことを可能にします。 この shiv は Modernizr にデフォルトで含まれています。ダウンロードを設定するときに、「html5shiv」チェック ボックスが選択されていることを確認してください。

    Datalists の限界

    Datalists はテキスト入力に候補を追加するのに最適ですが、多くの最新の Web アプリケーションが必要とするカスタマイズ機能が不足しています。

    • CSS を使用して表示やオプションの表示を変更する
    • リストの位置を制御する
    • ブラウザがユーザーに結果を表示する前に入力される文字数を制御する。
    • 一致したとみなされるものを制御する(大文字と小文字の区別、文字列の先頭と任意の場所での一致など)
    • 入力をサーバー側のデータソースに結び付ける

    つまり、これらの機能が必要な場合は、より堅牢なオートコンプリート ソリューションを検討する必要があります。 jQuery UI のオートコンプリート ウィジェットは、これらすべての機能を備えています。 また、オートコンプリート ウィジェットは、ポリフィルを使用せずに Internet Explorer 7 までのすべてのブラウザをサポートしています。 オートコンプリート ウィジェットの詳細については、デモや API ドキュメントをご覧ください。

    オートコンプリート ウィジェットはテキスト ベースの入力のみを処理するため、範囲や色などの特殊な入力タイプには対応できません。

    まとめ

    Datalist は、入力候補をユーザーに表示するための迅速でネイティブな手段です。

    機能的なデータリストをすべてのユーザーに提供したい場合は、サポートを検出し、サポートがないブラウザに対して機能をポリフィルすることができます。 より堅牢なオートコンプリート ソリューションが必要な場合は、jQuery UI のオートコンプリート ウィジェットを利用するとよいでしょう。

    コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です