いまさらHTML5（datalist編）

##はじめに

[前回](http://qiita.com/tnakagawa/items/b4a4160f13fcbcf66f83)からの拡張を考えてみます。

以下の２点を実現するとします。
・inputからinputを置換
・履歴

※：本記事では部分的に記述します。

##inputからinputを置換

「誰？」inputを作成し、これを変更すると「件名」を変更してみます。

```html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>メール作成</title>
	<style>
		* {font-family: monospace}
	</style>
	<script>
		function init() {
			document.getElementById("who").addEventListener("input", changeSubject, true);
		}
		function changeSubject() {
			var who = document.getElementById("who").value;
			var subject = "○○さん、遅刻";
			if (who) {
				subject = who + "さん、遅刻";
			}
			document.getElementById("subject").value = subject;
		}
		window.onload = init;
	</script>
</head>
<body>
	<table>
		<tr><td>誰？</td><td><input id="who" list="wholist" type="text" value="" size="50" /></td></tr>
		<tr><td>件名</td><td><input id="subject" type="text" value="○○さん、遅刻" size="50" /></td></tr>
	</table>
</body>
</html>
```

HTHML5で追加？された、「input」イベントを拾い
「誰？」の値を加工して、「件名」に入れるサンプルです。

以前は、「keyup」などを拾っていましたが、わかりやすくなりましたねぇ。

##履歴

次に履歴を考えてみます。

コンボボックスを作らなければなりません。ということで、datalistを使います。

##datalist

[W3C](https://www.w3.org/TR/html5/forms.html#the-datalist-element)の仕様をみてます。

```text
The options IDL attribute must return an HTMLCollection rooted at the datalist node, whose filter matches option elements.
```

子要素には、「option」エレメントのみを見ると記述されています。

```html
<input name="color" list="colors">
<datalist id="colors">
	<option value="black">
	<option value="white">
	<option value="blue">
	<option value="red">
</datalist>
```

使い方はこんな感じとなります。

##実装

```html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>メール作成</title>
	<style>
		* {font-family: monospace}
	</style>
	<script>
		var HISTORY_MAX = 5;
		var hist = [];
		function init() {
			document.getElementById("createbtn").addEventListener("click", createEmail, true);
		}
		function createEmail() {
			var who = document.getElementById("who").value;
			if (who) {
				var tmp = [];
				tmp.push(who);
				for (var i = 0; i < hist.length; i++) {
					if (hist[i] !== who) {
						tmp.push(hist[i]);
					}
					if (tmp.length >= HISTORY_MAX) {
						break;
					}
				}
				hist = tmp;
				var element = document.getElementById("wholist");
				while (element.firstChild) { element.removeChild(element.firstChild); }
				for (var i = 0; i < hist.length; i++) {
					var option = document.createElement("option");
					option.setAttribute("value", hist[i]);
					element.appendChild(option);
				}
			}
			document.getElementById("who").value = null;
		}
		window.onload = init;
	</script>
</head>
<body>
	<table>
		<tr><td>誰？</td><td><input id="who" list="wholist" type="text" value="" size="50" />
		<datalist id="wholist"></datalist></td></tr>
		<tr><td colspan="2"<td><button id="createbtn">作成</button></td></tr>
	</table>
</body>
</html>
```

部分的に説明します。

```js
var who = document.getElementById("who").value;
if (who) {
	var tmp = [];
	tmp.push(who);
	for (var i = 0; i < hist.length; i++) {
		if (hist[i] !== who) {
			tmp.push(hist[i]);
		}
		if (tmp.length >= HISTORY_MAX) {
			break;
		}
	}
	hist = tmp;
```

履歴作成部分となります。
以下の三点が実装となりますが、もうちょいスマートなコードにならないものか悩み中です。
・直近のアイテムを履歴の先頭に置く
・重複のアイテムは履歴に含めない
・履歴の最大長を超えない

```js
var element = document.getElementById("wholist");
while (element.firstChild) { element.removeChild(element.firstChild); }
for (var i = 0; i < hist.length; i++) {
	var option = document.createElement("option");
	option.setAttribute("value", hist[i]);
	element.appendChild(option);
}
```
「datalist」タグ内部に「option」を入れかえる部分です。
JQueryとか使うともっとスマートになりそうですが・・・・


##さいごに

というわけで、履歴の作成は出来ました。
ところが、ローカルHTMLを閉じてしまうと、履歴も消えてしまいます。
次は、保存を考えてみたいと思います。

つづく