はじめに

私たちを取り巻くWeb技術は、もはや社会的なインフラとしてめまぐるしく進化しています。HTMLやCSSはもちろんのこと、JavaScriptやライブラリ、フレームワークなど、それぞれがニーズにキャッチアップする形で、機能強化を繰り返しています。その中でも、Web技術の中核に位置するにもかかわらず、意外と見過ごされがちなのがHTMLの進化です。本連載は、このHTMLと関連するJavaScript APIにフォーカスして、その新機能を手軽に試していただこうというものです。理解も利用もたやすいHTMLなので、ライトな気持ちで「こんなことができるようになったのか」を感じていただきます。

[NOTE]サンプルについて
本記事の配布サンプルは、以下のURLから入手できます。新機能を試していくので、ブラウザは最新である方がよいでしょう。本記事のサンプルは、執筆時点で最新のGoogle Chromeで動作することを確認しています。
https://github.com/wateryinhare62/mynavi_html

連載第4回の目的

この回では、input要素で入力方法を拡張できるdatalistを試します。単純に項目を選べるほか、特定の日付や色などを選べる例を紹介します。

datalistとは

datalistとは、input要素に入力できる値のリストを作成する要素および機能です。datalistを使うと、ユーザーが入力すべき値をあらかじめ用意しておき、その中から選択したり、入力時の補助に使うといった操作が可能になります。
ユーザーに選択させるといった目的で使える要素にはselectがありますが、selectは文字通り選択だけが可能な要素です(このためinput要素ではなくselect要素として独立しています)。datalistを使うと、input要素の本来の機能(入力させる)を損なわずに、選択可能なリストを与えることができます。
datalistはブラウザ間の互換性としてはLimited availabilityとなっており(意味については第2回を参照)、現時点でFirefoxブラウザで一部の機能がサポートされていないほか、細かな動作がブラウザによって異なります。以降は、Google Chromeにおける解説およびスクリーンショットとなっています。

テキスト入力とdatalist

datalistの基本的な使い方として、テキスト入力ボックス(input type="text")とdatalistを組み合わせた例を紹介します。input要素にlist属性を付与して、対応するdatalistを指定します(リスト1)。

[NOTE]適用されるinput要素
ここではtype="text"である場合の例を示していますが、同じくテキストを入力できるsearch、url、tel、email、numberの各typeにおいても同様に適用可能です。

リスト1:basic.html

<label for="noodle-soup">お好きなスープを選んでください:</label>
<input type="text" list="noodle-soup-list" id="noodle-soup" name="noodle-soup">
<datalist id="noodle-soup-list">
    <option value="しょうゆ">
    <option value="みそ">
    <option value="塩">
    <option value="豚骨">
    <option value="ソース">
</datalist>

HTMLをブラウザに読み込ませると、図1上のようにいつものテキスト入力ボックスが表示されます。マウスポインタを入力ボックスに乗せると右端に「▼」が表示されるので、これをクリックすると図1中のようにdatalist要素で指定したリストが表示されます。いずれかを選択すれば、図1下のようにその内容が入力ボックスに反映されます。

  • 図1:テキスト入力とdatalist

    図1:テキスト入力とdatalist

このようにinput要素にdatalistを対応付けるには、input要素のlist属性にdatalistのid属性を指定するだけです。ブラウザがdatalistをサポートしない場合には、単にlist属性が無視されるので、通常のテキスト入力ボックスとして働きます。
datalist要素には、select要素のようにリストとしたい項目をoption要素で並べます。リストとして表示したい項目は、option要素のコンテンツかvalue属性で指定します。

[NOTE]各ブラウザのdatalistへの対応状況
datalistはさほど新しい機能ではありませんが、前述したようにブラウザによっては最新バージョンでも一部の機能がサポートされていなかったり、細かな動作が異なっていたりします。特にoption要素のルールがやや複雑なので、実際の動きを確かめながら使うことをおすすめします。

・サポートされない入力type
FirefoxとSafariでは、date, timeなどカレンダー入力のdatalistがサポートされません。datalistは無視され、通常のDateピッカーなどが使われます。

・外観の差異
Firefoxでは、選択できる項目があることを示す「▼」などは表示されません。Safariでは、マウスポインタをホバーさせずとも、最初から「▼」に相当するアイコンが表示されます。

・option要素のコンテンツと属性
option要素では、コンテンツかvalue属性、label属性で表示する内容を指定できますが、実際にどれが表示されるかはブラウザ依存です。また、後述するラベル付きの項目表示においても振る舞いが異なってきます。
ChromeとEdge、Safariでは、コンテンツでもvalue属性でもlabel属性でもリストに現れます。複数に異なる内容が指定された場合は、value属性、コンテンツ、label属性の順で使われます。
Firefoxでは、複数に異なる内容が指定された場合は、label属性、コンテンツ、value属性の順で使われます。ラベル付きの項目表示はサポートされません。
本記事では、どのブラウザでも問題ないと思われるvalue属性を優先して設定しています。この場合、option要素のコンテンツを省略できるので、閉じタグの記述は不要すなわち空要素とできます。
なお、option要素のvalue属性は、本来はフォーム送信時のselect要素の値として使われるものですが、datalistで使う場合には入力ボックスに設定すべき内容として扱われます。

入力サジェストとしてのdatalist

テキスト入力ボックスにすでに入力された内容がある場合、それはdatalistのリストを絞り込む働きがあります。ですので、datalistによるリストは、入力候補を常に全て表示するのではなく、すでに入力された値と部分一致するものだけが表示されます(リスト2)。

リスト2:suggest.html

<label for="home-area">お住まいの地域を選んでください:</label>
<input type="text" list="home-area-list" id="home-area" name="home-area">
<datalist id="home-area-list">
    <option value="東京都世田谷区">
    <option value="東京都目黒区">
    <option value="神奈川県川崎市宮前区">
    <option value="神奈川県川崎市高津区">
    <option value="神奈川県横浜市青葉区">
    <option value="神奈川県横浜市都筑区">
</datalist>

ページを表示させると、テキスト入力ボックスに何もない状態なので、クリックで全てのリストが表示されます(図2上)。ここで、「神奈川県」と入力すると、リストが「神奈川県~」で始まるものだけになります(図2下)。

  • 図2:入力サジェストとしてのdatalist

    図2:入力サジェストとしてのdatalist

この特性は、サンプルのような数個のリストではあまり効果を感じないかもしれませんが、100を越えるような大量のリストがある場合には便利です。このように、テキスト入力におけるdatalistは、選択させるというよりはあくまでも入力を補完するという位置付けといえそうです。
なお、リスト以外のもの(例えば「東京都」「神奈川県」など)を入力すると、それも合わせて次回からリストに表示されるようになります(図3)。datalistとブラウザのオートコンプリート機能が合わさったものといえます。

  • 図3:datalistとオートコンプリート機能

    図3:datalistとオートコンプリート機能

オートコンプリート機能で表示される項目は、[×]をクリックすることで削除できます。

ラベル付きのテキスト入力

option要素にはlabel属性を指定できます。label属性をoption要素に使うと、リストにちょっとした説明を加えることができます(リスト3)。説明は項目より少し小さなフォントで表示されます(フォントやサイズはブラウザ依存です)。

リスト3:label.html

<label for="noodle-soup">お好きなスープを選んでください:</label>
<input type="text" list="noodle-soup-list" id="noodle-soup" name="noodle-soup">
<datalist id="noodle-soup-list">
    <option value="しょうゆ" label="何といっても基本はしょうゆ味です。">
    <option value="みそ" label="寒い季節にはやっぱり味噌味ですね。">
    <option value="塩" label="あっさりした塩味も人気です。">
    <option value="豚骨" label="ガツンとしたパンチが欲しければ豚骨で。">
    <option value="ソース" label="千葉県の一部地域で人気だそうです。">
</datalist>

ページを表示させて「▼」をクリックすると、各項目の下に説明も表示されます(図4)。

  • 図4:ラベル付きのテキスト入力

    図4:ラベル付きのテキスト入力

label属性を指定するときにはvalue属性あるいはコンテンツが必須です。それらが省略された場合には、項目自体が表示されません。なお、value属性とコンテンツが指定されていているときにlabel属性を省略すると、コンテンツがlabel属性ど同等に扱われます。

[NOTE]パスワード入力とdatalist
<input type="password">要素についてもdatalistは対応しています。ただし、仕様としては定められているものの、セキュリティ上の理由で実装に至っているブラウザはありません。

カレンダー入力とdatalist

datalistが本領を発揮するのは、ここで示すカレンダー入力など、手入力が面倒なものです。もちろん、input要素だけでもDateピッカーやTimeピッカーなどが備わっており、それを使えば日付と時刻の入力は選択するだけで済みます。しかしながら、特定の日時だけを選択させるという用途には向きません。datalistを使うと、3時間おきの時刻を選択させたり、今後1ヶ月間の日曜日などを選択させることができます。

[NOTE]適用されるinput要素
ここではtypeがdate、time、datetime-localである場合の例を示していますが、同じくカレンダー情報を入力できるmonth、weekの各typeにおいても適用可能です。

基本的な使い方

リスト4は、1ヶ月間の日曜日を選択させる例です。配布サンプルには時刻、日付と時刻を選択させる例も含まれているので、具体的なマークアップについてはそちらを参照してください。スクリーンショットはそれらを含めたものとなっています。

リスト4:datetime.html

<label for="date-list">希望の日付を選んでください:</label>
<input type="date" list="date-list" name="date-list">
<datalist id="date-list">
    <option value="2025-09-07">
    <option value="2025-09-14">
    <option value="2025-09-21">
    <option value="2025-09-28">
</datalist>

ページを表示させると、まずは日付入力ボックス、時刻入力ボックス、日付時刻入力ボックスが表示されます(図5)。

  • 図5:カレンダー入力とdatalist

    図5:カレンダー入力とdatalist

日付入力ボックス右端のカレンダーアイコンをクリックすると、datalistで指定した日付と[その他...]が表示されます(図6上)。日付を選択すればその日付が入力され、[その他...]を選択すると通常のDateピッカーが表示されます(図6下)。

  • 図6:日付の選択

    図6:日付の選択

option要素における日付は、「YYYY-MM-DD」をはじめとする日付文字列形式で指定します。
時刻と日付時刻についても同様なので、内容は配布サンプルを参照してください(図7)。なお、時刻は「HH:MM:SS.ms」をはじめとする時刻文字列形式で指定(ミリセカンド、秒は省略可)、日付と時刻は区切りとして「T」を入れたローカル日時文字列で指定します。

  • 図7:時刻と、日付時刻の選択

    図7:時刻と、日付時刻の選択

動的なdatalistの作成

上記の例では、選択できる日付や時刻は固定でしたが、本来は現在日時を基点にリストを生成すべきです。ここでは、JavaScriptを使って今日を含まない直近の日曜日4日分でdatalistを生成してみます。時刻だけの場合や日付と時刻の場合も同様にできるでしょう。HTMLは、リスト5のようにシンプルになります。id属性を残して、datalist要素のコンテンツは空となります。また、JavaScriptファイルを読み込むためのscript要素を最後に追加します。

リスト5:date_dynamic.html

<label for="date-list">希望の日付を選んでください:</label>
<input type="date" list="date-list" name="date-list">

<datalist id="date-list">
</datalist>

<script src="date_dynamic.js"></script>

JavaScriptコードはリスト6のようになります。

リスト6:date_dynamic.html

const datalist = document.getElementById('date-list');
const today = new Date();
const sundays = [];
// (1)直近の日曜日を求める
let date = new Date(today);
date.setDate(date.getDate() + ((7 - date.getDay()) % 7 || 7));

// (2)直近の日曜日から4回分の日曜日の配列を作成する
for (let i = 0; i < 4; i++) {
    sundays.push(new Date(date));
    date.setDate(date.getDate() + 7);
}

// (3)配列をoption要素としてdatalistに反映する
sundays.forEach(sunday => {
    const option = document.createElement('option');
    option.value = sunday.toISOString().slice(0, 10);
    datalist.appendChild(option);
});

(1)は直近の日曜日を求めているので、演算がやや複雑です。ポイントはgetDayメソッドを使って今日の曜日を求めて、日曜日までの日数を計算している点です。今日が日曜日なら日数が0になるので、この場合は日数を7にします。
(2)は、求められた直近の日曜日から4回分、次の日曜日を求めながら配列を作成しています。
最後に(3)で、日曜日の配列をもとにdatalist要素へoption要素を追加しています。
ページを表示させて日付入力ボックス右端のカレンダーアイコンをクリックすると、自動生成された日付と[その他...]が表示されます(図8)。

  • 図8:動的なdatalistの作成

    図8:動的なdatalistの作成

Date.toISOStringメソッドを使って日付文字列を求めているので、年月日の区切りが「/」となっていますが日付文字列形式としては正しいので、選択結果がきちんと認識されます。

範囲入力とdatalist

<input type="range">要素にもdatalistを使えます。この場合、範囲コントロールの下に目盛りという形でdatalistのリストが反映されます。リスト7は、100%までの進捗を、0、25、50、75、100の目盛りから選択できるようにする例です。

リスト7:range.html

<label for="tick">進捗度を選択してください:</label>
<input type="range" list="tick-marks" min="0" max="100" id="tick" name="tick">
<datalist id="tick-marks">
    <option value="0">
    <option value="25">
    <option value="50">
    <option value="75">
    <option value="100">
</datalist>

ページを表示させると、datalistで指定した値に、目盛りが表示されます(図9)。

  • 図9:範囲の選択

    図9:範囲の選択

カラー入力とdatalist

カラー入力も、datalistが生きる入力要素と言えます。標準のColorピッカーで直接RGBカラーを選ばせるのは選択肢が膨大になり、選ぶ方にとっても負担になるものです。あらかじめ対象の色が決まっていれば、それを選択させた方が選ぶ方の負担は少なくて済むでしょう。
リスト8は、赤(#ff0000)、緑(#00ff00)、青(#0000ff)、黄(#ffff00)の4色を直接選択可能にして、その他の色はColorピッカーで選択する例です。

リスト8:color.html

<label for="color">お好きな色を選択してください:</label>
<input type="color" list="color-list" id="color" name="color">
<datalist id="color-list">
    <option value="#ff0000">
    <option value="#00ff00">
    <option value="#0000ff">
    <option value="#ffff00">
</datalist>

ページを表示させると、datalistで指定した色と[その他...]が表示されます(図10上)。[その他...]を選択すると、標準のColorピッカーによるカラーの選択となります(図10下)。

  • 図10:カラーの選択

    図10:カラーの選択

option要素におけるカラーの指定は、CSSで使う6桁の16進数表現を使用できます。#ff0などの3桁の16進数表現、「yellow」などの色名は使えないので注意してください。

まとめ

datalistはいかがでしたでしょうか。datalist要素により、テキスト入力ボックスのユーザビリティを簡単に高めることができるのをお伝えできたのではないかと思います。次回は、HTMLから簡単に利用できるインタラクションであるポップオーバーを紹介します。

WINGSプロジェクト 山内直(著) 山田 祥寛(監修)
有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。現在も執筆メンバーを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。
RSS
X:@WingsPro_info(公式)@WingsPro_info/wings(メンバーリスト)
Facebook

<著者について>
WINGSプロジェクト所属のテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。