2008年12月27日土曜日

今さらながら入力補完JavaScript(8)

【段取り】
(4)テキストボックスに入力された文字列にマッチする補完候補をリスト表示する。

【詳細】
今は変数に入った値全部を表示していますが、これを入力された文字列にマッチするものだけ表示するようにします。

今まで便宜的にfocusで候補リストを表示していましたが、ここを全て書き換えて(うわああぁぁぁ!)、キーボードから文字列が入力されたタイミングで候補リストを出力するように変更します。

【結論】
ダメですね。onkeypressイベントでテキストボックスの値を見ても、最後に入力された文字列が入らない。
かなり直感に反する動きになっています。文字を入力した後、右矢印キーなど無害なキーを押さないと、入力した文字を使ってくれません。

余裕があったらキーイベントに依存するのではなく、suggest.jsみたいにtimerで定期的に検索する形に変えてみたいと思います。

ソースを見ていただければバレバレですが、もう付け刃に付け刃してって感じで大変でした。やっぱりJavaScriptはツラい・・・

ディレクトリ構造は変更なしです。
WebContent
- js/prototype.js
- js/my.js
- a.html
- my.css

■my.js
// 外出しです。
var div1 = null;
var cursor_pos = -1;
var element_len = 0;

Event.observe(window, 'load', function(event) {
// イベントを登録します。
var keyevent = 'keydown';
if (window.opera || (navigator.userAgent.indexOf('Gecko') <= 0
&& navigator.userAgent.indexOf('KHTML') == -1)) {
keyevent = 'keypress';
}
Event.observe($('hoge'), keyevent, function(event) {
if (event.keyCode == Event.KEY_DOWN) {
if (element_len < cursor_pos) {
cursor_pos++;
}
var hogeTmp = $('div1'+cursor_pos);
initiateListColors();
hogeTmp.style.backgroundColor = '#00FF00';
} else /* elseをつけましたよ */
if (event.keyCode == Event.KEY_UP) {
if (cursor_pos > 0) {
cursor_pos--;
}
var hogeTmp = $('div1'+cursor_pos);
initiateListColors();
hogeTmp.style.backgroundColor = '#00FF00';
} else
if (event.keyCode == Event.KEY_TAB
|| event.keyCode == Event.KEY_RETURN) {
if (cursor_pos >= 0) {
var hogeTmp = $('div1'+cursor_pos);
$('hoge').value = hogeTmp.innerHTML;
}
$('candidate').style.visibility = "hidden";
} else {
// クリアします
$('candidate').innerHTML = "";
$('candidate').style.visibility = "visible";
cursor_pos = -1;

var i;
var size = -1; // <- 当たり前ですが重要です。
var rObj = new RegExp($('hoge').value);
for (i = 0; i < week.length; i++) {
// 入力された文字が一致していた候補を表示します。
var tmpSearch = week[i];
if (tmpSearch.match(rObj) != null) {
size++; // <- iではなくてsizeをincreしながら使います
// 文字列がマッチしていたらappendします。
var tmpId = 'div1'+size;
div1 = new Element('div', {'id' : tmpId });
div1.innerHTML = week[i];
div1.style.backgroundColor = "#FF0000";
div1.style.width = "100px";
$('candidate').appendChild(div1);
Event.observe(tmpId, 'mouseover', function(event) {
this.style.backgroundColor = "#00FF00";
});
Event.observe(tmpId, 'mouseout', function(event) {
this.style.backgroundColor = "#FF0000";
});
Event.observe(tmpId, 'mousedown', function(event) {
$('hoge').value = this.innerHTML;
$('candidate').style.visibility = "hidden";
});
}
}
element_len = size;
}
});
// onBlur イベントを登録します。
Event.observe('hoge', 'blur', function(event) {
if (div1) {
// div1がnullでない場合はhiddenにします。
$('candidate').style.visibility = "hidden";
// ポジションを初期化します。
cursor_pos = -1;
}
});
});

function initiateListColors() {
var tmpElems = $('candidate').childElements();
for (var j = 0; j < tmpElems.length; j++) {
tmpElems[j].style.backgroundColor = "#FF0000";
}
}

■a.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<script type="text/css" src="my.css"></script>
<!-- 変数をmy.jsより先に読み込む必要があります。 -->
<script type="text/javascript">
var week = new Array("hokkaido","aomori","akita",
"yamagata","miyagi","niigata","fukushima",
"ikkei", "komori", "higata");
</script>
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/my.js"></script>
<title>Ajax tutorial - a</title>
</head>
<body>
<input type="text" id="hoge" name="hoge" />
<div id="candidate"></div>
</body>
</html>

■my.css

@CHARSET "UTF-8";
/* CSSは表示と関係ありません */
#div1 {
visibility:hidden;
}

.

今さらながら入力補完JavaScript(7)

【段取り】
(3)補完候補の選択確認

【詳細】
生成したDIV要素をキーボード/マウスで選択できるようにします。
次に選択された文字列をテキストボックスに入れ込みます。

TAB、ENTERが押された場合、その時に選択されていた値をテキストボックスに入力し、リストを消去します。すんなり行きました(なんだか動きに違和感があるような気もしますが気にしないことにします)。

ディレクトリ構造は変更なしです。
WebContent
- js/prototype.js
- js/my.js
- a.html
- my.css

■my.js
// 外出しです。
var div1 = null;
var cursor_pos = -1;
var element_len = 0;

Event.observe(window, 'load', function(event) {
// イベントを登録します。
var keyevent = 'keydown';
if (window.opera || (navigator.userAgent.indexOf('Gecko') >= 0
&& navigator.userAgent.indexOf('KHTML') == -1)) {
keyevent = 'keypress';
}
Event.observe($('hoge'), keyevent, function(event) {
if(div1) {
if (event.keyCode == Event.KEY_DOWN) {
if ((element_len - 1) > cursor_pos) {
cursor_pos++;
}
var hogeTmp = $('div1'+cursor_pos);
initiateListColors();
hogeTmp.style.backgroundColor = '#00FF00';
}
if (event.keyCode == Event.KEY_UP) {
if (cursor_pos > 0) {
cursor_pos--;
}
var hogeTmp = $('div1'+cursor_pos);
initiateListColors();
hogeTmp.style.backgroundColor = '#00FF00';
}
if (event.keyCode == Event.KEY_TAB
|| event.keyCode == Event.KEY_RETURN) {
var hogeTmp = $('div1'+cursor_pos);
$('hoge').value = hogeTmp.innerHTML;
$('candidate').style.visibility = "hidden";
}
}
});
// onFocus イベントを登録します。
Event.observe($('hoge'), 'focus', function(event) {
if (div1) {
// div1*がnullでなければcandidateをvisibleにします。
$('candidate').style.visibility = "visible";
} else {
// nullの場合はエレメントを作成して<div id="candidate"></div>に
// appendします。
var i;
for (i = 0; i < week.length; i++) {
var tmpId = 'div1'+i;
div1 = new Element('div', {'id' : tmpId });
div1.innerHTML = week[i];
div1.style.backgroundColor = "#FF0000";
div1.style.width = "100px";
$('candidate').appendChild(div1);
Event.observe(tmpId, 'mouseover', function(event) {
this.style.backgroundColor = "#00FF00";
});
Event.observe(tmpId, 'mouseout', function(event) {
this.style.backgroundColor = "#FF0000";
});
Event.observe(tmpId, 'mousedown', function(event) {
$('hoge').value = this.innerHTML;
$('candidate').style.visibility = "hidden";
});
}
element_len = i;
}
});
// onBlur イベントを登録します。
Event.observe('hoge', 'blur', function(event) {
if (div1) {
// div1がnullでない場合はhiddenにします。
$('candidate').style.visibility = "hidden";
// ポジションを初期化します。
cursor_pos = -1;
}
});
});

function initiateListColors() {
// .style.backgroundColor = "#FF0000";
for (k = 0; k < element_len; k++) {
$('div1'+k).style.backgroundColor = "#FF0000";
}
}

■a.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<script type="text/css" src="my.css"></script>
<!-- 変数をmy.jsより先に読み込む必要があります。 -->
<script type="text/javascript">
var week = new Array("日","月","火","水","木","金","土");
</script>
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/my.js"></script>
<title>Ajax tutorial - a</title>
</head>
<body>
<input type="text" id="hoge" name="hoge" />
<div id="candidate" />
</body>
</html>

■my.css
<pre>@CHARSET "UTF-8";
/* CSSは表示と関係ありません */
#div1 {
visibility:hidden;
}

.

今さらながら入力補完JavaScript(6)

【段取り】
(3)補完候補の選択確認

【詳細】
生成したDIV要素をキーボード/マウスで選択できるようにします。
次に選択された文字列をテキストボックスに入れ込みます。

次はキーボードです。結構苦労しました。

ポイントは以下の通りです。
1)キーボードイベントは仕様として決まっていないようで、suggest.js を参考に以下のような条件分けをしています。
var keyevent = 'keydown';
if (window.opera || (navigator.userAgent.indexOf('Gecko') >= 0
&& navigator.userAgent.indexOf('KHTML') == -1)) {
keyevent = 'keypress';
}
Event.observe($('hoge'), keyevent, function(event) {

他は行き当たりばったりの力ずくな実装になっています。なりふり構わずなところを暖かく見守って頂きたい。

ディレクトリ構造は変更なしです。
WebContent
- js/prototype.js
- js/my.js
- a.html
- my.css

■my.js
// 外出しです。
var div1 = null;
var cursor_pos = -1;
var element_len = 0;

Event.observe(window, 'load', function(event) {
// イベントを登録します。
var keyevent = 'keydown';
if (window.opera || (navigator.userAgent.indexOf('Gecko') >= 0
&& navigator.userAgent.indexOf('KHTML') == -1)) {
keyevent = 'keypress';
}
Event.observe($('hoge'), keyevent, function(event) {
if(div1) {
if (event.keyCode == Event.KEY_DOWN) {
if ((element_len - 1) > cursor_pos) {
cursor_pos++;
}
var hogeTmp = $('div1'+cursor_pos);
initiateListColors();
hogeTmp.style.backgroundColor = '#00FF00';
}
if (event.keyCode == Event.KEY_UP) {
if (cursor_pos > 0) {
cursor_pos--;
}
var hogeTmp = $('div1'+cursor_pos);
initiateListColors();
hogeTmp.style.backgroundColor = '#00FF00';
}
}
});
// onFocus イベントを登録します。
Event.observe($('hoge'), 'focus', function(event) {
if (div1) {
// div1*がnullでなければcandidateをvisibleにします。
$('candidate').style.visibility = "visible";
} else {
// nullの場合はエレメントを作成して<div id="candidate"></div>に
// appendします。
var i;
for (i = 0; i < week.length; i++) {
var tmpId = 'div1'+i;
div1 = new Element('div', {'id' : tmpId });
div1.innerHTML = week[i];
div1.style.backgroundColor = "#FF0000";
div1.style.width = "100px";
$('candidate').appendChild(div1);
Event.observe(tmpId, 'mouseover', function(event) {
this.style.backgroundColor = "#00FF00";
});
Event.observe(tmpId, 'mouseout', function(event) {
this.style.backgroundColor = "#FF0000";
});
Event.observe(tmpId, 'mousedown', function(event) {
$('hoge').value = this.innerHTML;
$('candidate').style.visibility = "hidden";
});
}
element_len = i;
}
});
// onBlur イベントを登録します。
Event.observe('hoge', 'blur', function(event) {
if (div1) {
// div1がnullでない場合はhiddenにします。
$('candidate').style.visibility = "hidden";
// ポジションを初期化します。
cursor_pos = -1;
}
});
});

function initiateListColors() {
// .style.backgroundColor = "#FF0000";
for (k = 0; k < element_len; k++) {
$('div1'+k).style.backgroundColor = "#FF0000";
}
}

■a.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<script type="text/css" src="my.css"></script>
<!-- 変数をmy.jsより先に読み込む必要があります。 -->
<script type="text/javascript">
var week = new Array("日","月","火","水","木","金","土");
</script>
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/my.js"></script>
<title>Ajax tutorial - a</title>
</head>
<body>
<input type="text" id="hoge" name="hoge" />
<div id="candidate" />
</body>
</html>

■my.css
@CHARSET "UTF-8";
/* CSSは表示と関係ありません */
#div1 {
visibility:hidden;
}

.

今さらながら入力補完JavaScript(5)

【段取り】
(3)補完候補の選択確認

【詳細】
生成したDIV要素をキーボード/マウスで選択できるようにします。
次に選択された文字列をテキストボックスに入れ込みます。
mousedownイベントを定義します(思ったより順調ですよ)。

※mousedown -> mouseup -> click という順にイベントが走ります。
mousedownの時点でonblurが走ってしまうため、DIV要素が消えてしまいます。
従ってclickイベントでは動きません。

ディレクトリ構造は変更なしです。
WebContent
- js/prototype.js
- js/my.js
- a.html
- my.css

■my.js
// 外出しです。
var div1 = null;

Event.observe(window, 'load', function(event) {
// onFocus イベントを登録します。
Event.observe('hoge', 'focus', function(event) {
if (div1) {
// div1*がnullでなければcandidateをvisibleにします。
$('candidate').style.visibility = "visible";
} else {
// nullの場合はエレメントを作成して<div id="candidate"></div>に
// appendします。
for (i = 0; i < week.length; i++) {
var tmpId = 'div1'+i;
div1 = new Element('div', {'id' : tmpId });
div1.innerHTML = week[i];
div1.style.backgroundColor = "#FF0000";
div1.style.width = "100px";
$('candidate').appendChild(div1);
Event.observe(tmpId, 'mouseover', function(event) {
this.style.backgroundColor = "#00FF00";
});
Event.observe(tmpId, 'mouseout', function(event) {
this.style.backgroundColor = "#FF0000";
});
Event.observe(tmpId, 'mousedown', function(event) {
$('hoge').value = this.innerHTML;
$('candidate').style.visibility = "hidden";
});
}
}
});
// onBlur イベントを登録します。
Event.observe('hoge', 'blur', function(event) {
if (div1) {
// div1がnullでない場合はhiddenにします。
$('candidate').style.visibility = "hidden";
}
});
});

■a.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<script type="text/css" src="my.css"></script>
<!-- 変数をmy.jsより先に読み込む必要があります。 -->
<script type="text/javascript">
var week = new Array("日","月","火","水","木","金","土");
</script>
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/my.js"></script>
<title>Ajax tutorial - a</title>
</head>
<body>
<input type="text" id="hoge" name="hoge" />
<div id="candidate" />
</body>
</html>

■my.css
@CHARSET "UTF-8";
/* CSSは表示と関係ありません */
#div1 {
visibility:hidden;
}

.

今さらながら入力補完JavaScript(4)

【段取り】
(3)補完候補の選択確認

【詳細】
生成したDIV要素をキーボード/マウスで選択できるようにします。
まずはマウスでハイライトさせます。mouseoverとmouseoutイベントを定義します。

ディレクトリ構造は変更なしです。
WebContent
- js/prototype.js
- js/my.js
- a.html
- my.css

■my.js
// 外出しです。
var div1 = null;

Event.observe(window, 'load', function(event) {
// onFocus イベントを登録します。
Event.observe('hoge', 'focus', function(event) {
if (div1) {
// div1*がnullでなければcandidateをvisibleにします。
$('candidate').style.visibility = "visible";
} else {
// nullの場合はエレメントを作成して<div id="candidate"></div>に
// appendします。
for (i = 0; i < week.length; i++) {
var tmpId = 'div1'+i;
div1 = new Element('div', {'id' : tmpId });
div1.innerHTML = week[i];
div1.style.backgroundColor = "#FF0000";
div1.style.width = "100px";
$('candidate').appendChild(div1);
Event.observe(tmpId, 'mouseover', function(event) {
this.style.backgroundColor = "#00FF00";
});
Event.observe(tmpId, 'mouseout', function(event) {
this.style.backgroundColor = "#FF0000";
});
}
}
});
// onBlur イベントを登録します。
Event.observe('hoge', 'blur', function(event) {
if (div1) {
// div1がnullでない場合はhiddenにします。
$('candidate').style.visibility = "hidden";
}
});
});

■a.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<script type="text/css" src="my.css"></script>
<!-- 変数をmy.jsより先に読み込む必要があります。 -->
<script type="text/javascript">
var week = new Array("日","月","火","水","木","金","土");
</script>
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/my.js"></script>
<title>Ajax tutorial - a</title>
</head>
<body>
<input type="text" id="hoge" name="hoge" />
<div id="candidate" />
</body>
</html>

■my.css
@CHARSET "UTF-8";
/* CSSは表示と関係ありません */
#div1 {
visibility:hidden;
}

.

今さらながら入力補完JavaScript(3)

【段取り】
(2)手作りリストボックスの確認

【詳細】
(2)手作りリストボックスの確認
DIV要素を配列から生成します。意外と簡単にできました。

ディレクトリ構造は変更なしです。
WebContent
- js/prototype.js
- js/my.js
- a.html
- my.css

■my.js
// 外出しです。
var div1 = null;

Event.observe(window, 'load', function(event) {
// onFocus イベントを登録します。
Event.observe('hoge', 'focus', function(event) {
if (div1) {
// div1がnullでなければvisibleにします。
$('candidate').style.visibility = "visible";
} else {
// nullの場合はエレメントを作成して<div id="candidate"></div>に
// appendします。
for (i = 0; i < week.length; i++) {
div1 = new Element('div', {'id' : 'div1'+i });
div1.innerHTML = week[i];
div1.style.backgroundColor = "#FF0000";
div1.style.width = "100px";
$('candidate').appendChild(div1);
}
}
});
// onBlur イベントを登録します。
Event.observe('hoge', 'blur', function(event) {
if (div1) {
// div1がnullでない場合はhiddenにします。
$('candidate').style.visibility = "hidden";
}
});
});

■a.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<script type="text/css" src="my.css"></script>
<!-- 変数をmy.jsより先に読み込む必要があります。 -->
<script type="text/javascript">
var week = new Array("日","月","火","水","木","金","土");
</script>
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/my.js"></script>
<title>Ajax tutorial - a</title>
</head>
<body>
<input type="text" id="hoge" name="hoge" />
<div id="candidate" />
</body>
</html>

■my.css
@CHARSET "UTF-8";
/* CSSは表示と関係ありません */
#div1 {
visibility:hidden;
}

.

今さらながら入力補完JavaScript(2)

【段取り】
(1)イベントハンドリングの確認
まだ続きます。

【詳細】
(1)イベントハンドリングの確認
テキストボックスにフォーカスが当たったらDIV要素を表示、blurしたらDIV要素を消します。
DIV要素を動的に作ります。

【恥ずかしながらハマった点】
input要素にappendChildしても表示されない(分かってみれば当たり前)のでハマりました。

ディレクトリ構造は変更なしです。
WebContent
- js/prototype.js
- js/my.js
- a.html
- my.css

■my.js
// 外出しです。
var div1 = null;

Event.observe(window, 'load', function(event) {
// onFocus イベントを登録します。
Event.observe('hoge', 'focus', function(event) {
if (div1) {
// div1がnullでなければvisibleにします。
div1.style.visibility = "visible";
} else {
// nullの場合はエレメントを作成して<div id="candidate"></div>に
// appendします。
div1 = new Element('div', {'id' : 'div1' });
div1.innerHTML = "HOGE!";
div1.style.backgroundColor = "#FF0000";
div1.style.width = "100px";
$('candidate').appendChild(div1);
}
});
// onBlur イベントを登録します。
Event.observe('hoge', 'blur', function(event) {
if (div1) {
// div1がnullでない場合はhiddenにします。
div1.style.visibility = "hidden";
}
});
});

■my.css
@CHARSET "UTF-8";
/* CSSは表示と関係ありません */
#div1 {
visibility:hidden;
}

■a.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/my.js"></script>
<script type="text/css" src="my.css"></script>
<script type="text/javascript">
</script>
<title>Ajax tutorial - a</title>
</head>
<body>
<input type="text" id="hoge" name="hoge" />
<div id="candidate" />
</body>
</html>

.

2008年12月25日木曜日

今さらながら入力補完JavaScript(1)

使い勝手のいいライブラリも出ている(suggest.js)以上、今さら入力補完JavaScriptを作ってみてもしょうがないといえばしょうがないのですが、自前で実装できないというのはやはり悔しいので、勉強がてら作ってみます。

てゆーか本当に難しいですよ。JavaScriptってやつは。

【最終形】
prototype.js(v1.6)を使います。
配列の変数に、補完候補を持ちます。。
インプットボックスに入力された文字列とマッチする補完候補があったら、それをリストボックスとして表示します。
そのリストボックスはキーボードの上/下ボタンで選択、TABあるいはENTERキーで決定できます。マウスで選択もできます。

【段取り】
(1)イベントハンドリングの確認

(2)手作りリストボックスの確認
テキストエリアに文字が入力されると、配列の変数にある補完候補をリスト表示する。

(3)補完候補の選択確認
リストされた保管候補を、キーボード、マウスで選択できる。

(4)最終形
テキストエリアに入力された文字列にマッチする補完候補をリスト表示する。

さて、上手くいくかどうか。

【詳細】
(1)イベントハンドリングの確認
テキストボックスにフォーカスが当たったらDIV要素を表示、blurしたらDIV要素を消します。
ディレクトリ構造は以下の通りです。
WebContent
- js/prototype.js
- js/my.js
- a.html
- my.css

■my.js
Event.observe(window, 'load', function(event) {
Event.observe('hoge', 'focus', function(event) {
$('div1').style.visibility = "visible"
});
Event.observe('hoge', 'blur', function(event) {
$('div1').style.visibility = "hidden"
});
});

■my.css
@CHARSET "UTF-8";

#div1 {
visibility:hidden;
}

■a.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/my.js"></script>
<script type="text/javascript">
</script>
<title>Ajax tutorial - a</title>
</head>
<body>
<input type="text" id="hoge" name="hoge" />
<div id="div1">test</div>
</body>
</html>

どうなることやら不安がいっぱいです。
.

2008年12月23日火曜日

高度成長期のいわゆる中産階級に生まれた

クリスマス(今日はイブ・イブだけど)というのは、私にとっては高度成長期(団塊Jr)のいわゆる中産階級(中企業サラリーマン)に生まれたことを実感するイベントです。

どういうことかと言えば、今日はクリスマスだ。ワー。じゃあ、ハンバーグにしましょうか。やったー!夕方何気にテレビをつけるとディケンズのクリスマスキャロル(人形劇)をやってる。やったー!さあ、ハンバーグ食った。寝るぞ。プレゼント楽しみ~!という感じですんなり収まってしまう感覚。それが日本高度成長時代の中産階級に生まれた子の発想だと思うのです。

すなわち、クリスマスだからいつもとは違う感が欲しい。でもだからといってローストビーフとか、丸一匹のローストチキンというのもなんだか場違いな気がする。いや、別に親にねだればそのくらい作ってくれるのは分かってるし、ハンバーグが凄く特別なわけじゃない(てゆーか先週もハンバーグ食べた)。でも親もいそがしそうだし、ローストビーフが格別ハンバーグより美味いとも思えない。プレゼントももらえる。ハンバーグでかなり満足。別に苦労して背伸びする必要はないじゃん。やれば出来るけどさ(アンニュイ)。という感じ。

クリスマスというイベントを真剣に楽しもうとカロリーを消費し、熱く頑張る人と比較した時、若干「損?」という気もしないではありませんが、トータルで見れば妥当というか、バランスが取れている態度にも思えるわけで。家にはお手伝いさんがいました。クリスマスといえばローストチキンが当たり前。というお坊ちゃんお嬢ちゃん。あるいは、昔貧乏したことがあってなんとなくコンプレックスがあるんだよねー、だからクリスマスからローストビーフははずせない。という価値観よりも、まあ、それなりに楽しもうや、というところが自然体でよろしいのではないか、と。

そんなふうに自己肯定できるだけ、成長したなと自分を褒めてやろうじゃないか。自分を「よし」としたいと思う、今日この頃です。
.

吉行淳之介「飲む」

吉行淳之介の「飲む」というエッセーがあって、これがエッセーの白眉というか、何年かおきに読み返してしまうのです。

個人的には傑作と思ってます。一杯の酒がもたらす潤い。

琥珀色の美酒。ストイックでありつつも、酒を楽しむことのできる余裕。酒への憧れとストイックさとの共存。一杯の貴重な酒を飲むことで、生きている文脈に戻る。生きている実感と、酒を飲む幸せとが完全に合体する時。

いいですね。うん。

以上。
.

クリスマスの危機

まあ、今日はクリスマス・イブ・イブなわけですが。

だいたい子供というのは、こういうイベントがある日には朝からハイになり、日中は尋常じゃないテンションで騒ぎまくるわけです。

そして両親はせっかくだから、とケーキを作ってみたり、ご馳走を作ってみたりして神経を使いつつ、日中は労働しているわけで。

ということは、次第に子供はわけも分からず騒ぎ立て、父母は労働による疲れがかさみつつ、ハイテンションを引きずりつつ疲れも見えてきた子供たちに振り回されることで、次第に不機嫌になるわけで。

で、クライマックス。ケーキとかハレのデザートを準備し、ハレのご馳走を準備しつつあるそのとき、事故は起こるものなのです。

まあ、さすがになれましたけどね。皿やグラスが割れなければもう上出来というか。怪我しなけりゃあそれでいいか、みたいな。

今年は妻がクッキーで作るお菓子の家なるギミックを採用し、苦労して作ってました。及ばずながら私も皿洗いなど手伝いましたけど。それからローストチキン丸一羽分。これも妻が選択し、妻が頑張って作りました。美味かったです。一家四人おなか一杯食べた後、残った残骸から出来るだけ肉をこそげ取り、さらに残ったガラを鶏がらスープに。チェ・ゲバラ率いるゲリラのメンバーに食べさせてあげたいと思った。マジで。でも血はにごった感じ。昼食抜いたのにな。また断食しなければ・・・

という訳で、誰も怪我せず、皿が割れることもなく、楽しく過ごしました。うんうん。


.

2008年12月21日日曜日

Ajaxとか

Ajax入門。いいページですね。Ajaxがよく分かる。

これまでJavascriptでコーディングする人は神だと思っていましたが、この入門を一通りチェックして少し神が身近に感じられました。そうか。FireBugを使えばいいのか(それにしても大変だと思うけどなあ)。

それからSOAだとかweb serviceという(胡散臭い)ジャーゴンがここ数年生きながらえている理由も、少し理解できたような気がしました。上手く言えませんが、要するにショッピングサイトの構築には相性がいいんだなってとこでしょうか。まだまだEnterpriseの領域でSOAとかweb serviceが活用できるとは思えないんだけどな。だって必要性がありませんぜ。データベースを使えばいいんだからさ。

以上です。
.

今日の料理(タラコディップ・サンマのみりん干し)

カラスミを目指していたタラコの塩漬け。ハエにファーストキッスを奪われた悔しさのあまり、火あぶりにして食べてみたらちゃんと美味しいタラコでした。魚卵好きのうちの妻は喜んでました。当然アミノ酸やら蛋白加水分解物は入っていないので分かりやすい旨味はありません。でもタラコ好きならイケるんじゃないかな。無添加だし。ちゃんとしたタラコっぽい発酵臭としょっぱいツブツブ・プチプチのテクスチャ。それに遠くの方から漂ってくるほのかな旨味。うん。タラコだ。って感じです。戦前のタラコってこうじゃなかったのかな。食べたことないけど。

今日はそんなタラコを使ってマヨネーズディップを作り、蒸し野菜と食べました。美味かった。私が料理するとたんぱく質と脂が過剰になるので、野菜を意識的に摂取する必要があります。一部はマヨネーズと和えずに、妻がご飯と食べてました。

それから昨日作ったサンマのみりん干し。これが美味かった。鯵で作ったときはちょっと干し過ぎてしまい、焼いたら硬かったんですが、今回やや生干しっぽくしてみたらご飯に合う合う。今度鯵のみりん干しを作るときは干し加減に気をつけようと心に誓いました。

なんだか血が濁ってきた気がするのでしばらく野菜優先で行きたいと思ってます。(でも鳥ハム仕込んじゃってるんだよな・・・)

以上。
.