備忘録的プログラミングリファレンス

datalist と JavaScript を使った入力候補

 <datalist><input> において入力候補の一覧を提供するためのタグエレメントです。予め <datalist> タグを使用して入力候補を web ページ内で編集しておく方法もありますがスマートではありません。
 入力候補は別ファイルやデータベースを利用したほうが利便性が上がります。しかし、そのためには JavaScript を使用して非同期通信<datalist> タグのための一覧データを読み込む必要があります。
 ここでは <datalist> と JavaScript による非同期通信を利用した入力候補の作成方法を解説します。

ページ内 Index

<datalist> について

 まずは <datalist> タグエレメントについて解説します。

 <datalist> タグは、<input> エレメントの入力候補リスト(a list of predefined options)が定義できます。

 <datalist><option> タグによって一覧の項目データを作成します。

 <datalist><input> エレメントは、datalist の id 名と<input>エレメントの list 属性名でバインドします。

<datalist> エレメン卜とのバインド
<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 ページにそのテキストを挿入しています。

 非同期通信のコードは以下の要素から成り立っています。

  1. 非同期通信のためのインスタンスを生成
  2. 通信が成功した場合の処理
  3. 通信設定と通信の実行

 流れが前後しているように感じますが、この3つの処理要素が必要になります。1番目は非同期通信のためのインスタンスを生成しているだけです。
 2番めに通信が成功した場合の処理を予め編集しておきます。そのあとに通信を実行します。

 xhr_rel.responseType = "document";xhr_rel.responseでファイルデータを取得する際に必要になります。
 自動で何のデータ化を識別されるようなら必要はありません。

作成手順

 ここでは、簡単に作成手順を解説します。<datalist> を外部ファイルとして作成しておき、非同期通信によってそれを読み込み、反映します。

 まずは <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> の定義例
<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 による非同期通信による作成例です。

動作の確認

cssあり/なし、scriptあり/なしを選択することができます。

別ページで開きます。

HTML

 

css

JavaScript

XML、JSON

 サーバーからレスポンスを XML や JSON データで受け取る場合には非同期通信の通信設定を XML や JSON 用に切り替えます。

 データベースを利用して一覧データを取得する方法には XML や JSON データに変換する方法もあります。

XML

 以下のように XML テキストは .responseXML として受け取るようにします。

responseXML
..
// 受信と処理
	xhr_rel.onreadystatechange = function() {
		if( xhr_rel.readyState === 4 && xhr_rel.status === 200) {
			console.log( xhr_rel.responseXML );
		}
	}
..

 もしも XML テキストファイルとして解釈されない場合は、以下のように MIME を text/xml として設定します。

XML ファイルして取得
..
xhr_rel.responseType = "document";
xhr_rel.overrideMimeType("text/xml");
..

 XML テキストのタグエレメントごとのデータは getElementsByTagName() メソッドでタグ名を指定し取得します。

JSON ファイルの設定
let obj_data = xhr_rel.responseXML.getElementsByTagName( 'data' );

 getElementsByTagName() メソッドは document または Element のメソッドです。返り値は HTMLCollection になります。

JSON

 JSON データは以下のように .responseType = "json" に設定して、.response で取得します。

JSON ファイルの設定
	// 受信と処理
		xhr_rel.onreadystatechange = function() {
			if( xhr_rel.readyState === 4 && xhr_rel.status === 200) {
				console.log( xhr_rel.response );
			}
		}
	..
	xhr_rel.responseType = "json";
	..

 JSON テキストはjsonタイプで読み込むことで自動でオブジェクト化されます。階層化されますのでルートから辿りながらデータを取得することもできます。

JSON データ
let obj_root = xhr_rel.response.root;