datalist と JavaScript を使った入力候補
<datalist> は <input> エレメントに対して入力候補の一覧を提供するためのタグです。入力候補を <datalist> タグに直接記述することも可能ですが、外部ファイルやデータベースから読み込む方が利便性が向上します。
しかし、外部ファイルやデータベースから読み込む方法は、JavaScript を使用して非同期通信
を行い、 <datalist> タグに動的にデータを設定する必要があります。
ここでは、<datalist> タグと JavaScript による非同期通信
を組み合わせた、動的な入力候補の作成方法について解説します。
ページ内 Index
<datalist> について
まずは <datalist> タグエレメントについて解説します。
<datalist> タグは、<input> エレメントの入力候補リスト(a list of predefined options)が定義できます。
<datalist> は <option> タグによって一覧の項目データを作成します。
<datalist> と <input> エレメントは、datalist の id 名と<input>エレメントの list 属性名でバインドします。
<input list="test"> <datalist id="test"> <option value="tokyo">東京</option> <option value="nagoya">名古屋</option> <option value="kyoto">京都</option> <option value="osaka">大阪</option> <option value="fukuoka">福岡</option> </datalist>
<option>で一覧の表示を編集することができます。
この <datalist> の <option> データを JavaScript ので非同期通信
によって外部ファイルまたはデータベースから読み込むようにします。
非同期通信
次に JavaScript による非同期通信
について解説します。
非同期通信とは、非同期処理
のひとつで web ページの遷移がなくてもサーバーと通信を行いページ内の一部を変更することを可能にする手法です。ページのリロードを行わなくても一部を更新することができます。
通信方法は web ページと同じ HTTP 接続で web サーバーと通信を行います。web サーバーには URL でリクエストします。
以下は非同期通信
のコード例です。
// 非同期通信 function import_Datalist( id_insert_element, url_fl ){ // 非同期通信のためのインスタンスの生成 const xhr_rel = new XMLHttpRequest(); // 受信と処理 xhr_rel.onreadystatechange = function() { if( xhr_rel.readyState === 4 && xhr_rel.status === 200) { document.getElementById( id_insert_element ).innerHTML = xhr_rel.response.body.innerHTML; } } // 通信を開始 xhr_rel.open('get', url_fl); xhr_rel.responseType = "document"; xhr_rel.send(); return( xhr_rel ); }
この例は単純に外部の HTML テキストファイルを読み込んで、web ページにそのテキストを挿入しています。
非同期通信
のコードは以下の要素から成り立っています。
- 非同期通信のためのインスタンスを生成
- 通信が成功した場合の処理
- 通信設定と通信の実行
流れが前後しているように感じますが、この3つの処理要素が必要になります。1番目は非同期通信のためのインスタンスを生成しているだけです。
2番めに通信が成功した場合の処理を予め編集しておきます。そのあとに通信を実行します。
xhr_rel.responseType = "document";
はxhr_rel.response
でファイルデータを取得する際に必要になります。
自動で何のデータ化を識別されるようなら必要はありません。
作成手順
ここでは、簡単に作成手順を解説します。<datalist> を外部ファイルとして作成しておき、非同期通信によってそれを読み込み、反映します。
まずは <datalist> を作成します。
<datalist id="test">
<option value="tokyo">東京</option>
<option value="nagoya">名古屋</option>
<option value="kyoto">京都</option>
<option value="osaka">大阪</option>
<option value="fukuoka">福岡</option>
</datalist>
以上の内容でtest_datalist.html
として保存します。
上記の JavaScript のコードを <input> エレメントの onforcus イベントの発生時に実行します。
<input type="text" name="example_00" list="test" onfocus="import_Datalist( 'example_list_00', 'test_datalist.html' )" />
onfocus イベントによって呼び出されるメソッドは上記の非同期通信
を参考にしてください。
非同期通信によって読み込んだ HTML テキストはid='example_list_00'
エレメントに挿入されます。
挿入された HTML テキストは即時にオブジェクト化されるようです。上記の <input> エレメントの list="test" と <datalist> の id="test" によって自動でバインドされ一覧として表示されます。
Example
実際の <datalist> タグと JavaScript による非同期通信による作成例です。
XML、JSON
サーバーからレスポンスを XML や JSON データで受け取る場合には非同期通信の通信設定を XML や JSON 用に切り替えます。
データベースを利用して一覧データを取得する方法には XML や JSON データに変換する方法もあります。
XML
以下のように XML テキストは .responseXML として受け取るようにします。
..
// 受信と処理
xhr_rel.onreadystatechange = function() {
if( xhr_rel.readyState === 4 && xhr_rel.status === 200) {
console.log( xhr_rel.responseXML );
}
}
..
もしも XML テキストファイルとして解釈されない場合は、以下のように MIME を text/xml として設定します。
.. xhr_rel.responseType = "document"; xhr_rel.overrideMimeType("text/xml"); ..
XML テキストのタグエレメントごとのデータは getElementsByTagName() メソッドでタグ名を指定し取得します。
let obj_data = xhr_rel.responseXML.getElementsByTagName( 'data' );
getElementsByTagName() メソッドは document または Element のメソッドです。返り値は HTMLCollection になります。
JSON
JSON データは以下のように .responseType = "json" に設定して、.response で取得します。
// 受信と処理 xhr_rel.onreadystatechange = function() { if( xhr_rel.readyState === 4 && xhr_rel.status === 200) { console.log( xhr_rel.response ); } } .. xhr_rel.responseType = "json"; ..
JSON テキストはjson
タイプで読み込むことで自動でオブジェクト化されます。階層化されますのでルートから辿りながらデータを取得することもできます。
let obj_root = xhr_rel.response.root;