• R/O
  • SSH
  • HTTPS

r42utils: コミット


コミットメタ情報

リビジョン29 (tree)
日時2010-08-14 19:58:44
作者takahashikzn

ログメッセージ

NarrowDownSelectionListのバグを修正。

変更サマリ

差分

--- trunk/src/main/js/ArgContract.js (nonexistent)
+++ trunk/src/main/js/ArgContract.js (revision 29)
@@ -0,0 +1,58 @@
1+/*
2+ * Copyright (C) 2010 root42 Inc. All rights reserved.
3+ */
4+
5+/**
6+ * R42フレームワーク
7+ *
8+ * 引数チェック用ユーティリティ
9+ *
10+ * @author root42 Inc.
11+ * @version $Id: ArgContract.js 2777 2010-05-05 10:55:32Z kaz $
12+ */
13+
14+var ArgContract = {};
15+
16+
17+/**
18+ * 引数がnullでないことをチェックします。
19+ *
20+ * @param name 引数名
21+ * @param value 引数値
22+ */
23+ArgContract.notNull = /* void */ function(/* String */ name, /* Object */ value) {
24+ if (value == null) {
25+ throw new Error(name + " is null");
26+ }
27+};
28+
29+
30+/**
31+ * 引数が指定のタイプであることをチェックします。
32+ *
33+ * @param name 引数名
34+ * @param type 引数型
35+ * @param value 引数値
36+ */
37+ArgContract.isTypeof = /* void */ function(/* String */ name, /* String */ type, /* Object */ value) {
38+ ArgContract.notNull(name, value);
39+
40+ if ((typeof value) != type) {
41+ throw new Error(name + " is not " + type + ": " + (typeof value));
42+ }
43+};
44+
45+
46+/**
47+ * 引数が空白文字列でないことをチェックします。
48+ *
49+ * @param name 引数名
50+ * @param value 引数値
51+ */
52+ArgContract.notBlank = /* void */ function(/* String */ name, /* String */ value) {
53+ ArgContract.isTypeof(name, "string", value);
54+
55+ if (value.match(/^[\s ]*$/g) != null) {
56+ throw new Error(name + " is blank");
57+ }
58+};
--- trunk/src/main/js/NarrowDownSelectionList-Sample.html (revision 28)
+++ trunk/src/main/js/NarrowDownSelectionList-Sample.html (revision 29)
@@ -1,12 +1,13 @@
11 <html>
22
33 <head>
4+<script src="./ArgContract.js"></script>
45 <script src="./Utils.js"></script>
56 <script src="./NarrowDownSelectionList.js"></script>
67 </head>
78
89 <body>
9-<form method="post" action="http://localhost:8080/">
10+<form method="post" action="http://www.kojikoji.net/">
1011 <div id="sample"></div>
1112 <input type="submit" value="確認" />
1213 </form>
--- trunk/src/main/js/Utils.js (revision 28)
+++ trunk/src/main/js/Utils.js (revision 29)
@@ -84,3 +84,56 @@
8484 node[handlerName][listenersName].push(listener);
8585 }
8686 };
87+
88+
89+/**
90+ * 文字列がnullまたはから文字であるか判定します。
91+ *
92+ * @param text
93+ * 文字列
94+ */
95+Utils.isEmptyString = /* boolean */ function(/* String */ text) {
96+ ArgContract.isTypeof("text", "string", text);
97+
98+ return (text == null) || (text == "");
99+};
100+
101+
102+/**
103+ * ノードの子要素をすべて削除します。
104+ *
105+ * @param elem
106+ * 親要素
107+ */
108+Utils.clearChildNodes = /* void */ function(/* Node */ elem) {
109+ elem.innerHTML = "";
110+
111+ // while (0 < elem.childNodes.length) { elem.removeChild(elem.childNodes[0]); }
112+};
113+
114+
115+/**
116+ * Option要素を作成する。
117+ *
118+ * @param document
119+ * @param text
120+ * @param value
121+ * @return Option要素。
122+ */
123+Utils.createOption = /* Option */ function(/* Document */ document, /* String */ text, /* String */ value) {
124+
125+ ArgContract.notNull("document", document);
126+
127+ //IEだとこのやり方では動かない
128+ //return new Option(text, value);
129+
130+ /* Option */ var option = document.createElement("option");
131+
132+ //IEだとこれはダメ
133+ //option.text = text;
134+
135+ option.appendChild(document.createTextNode(text));
136+ option.value = value;
137+
138+ return option;
139+};
--- trunk/src/main/js/NarrowDownSelectionList.js (revision 28)
+++ trunk/src/main/js/NarrowDownSelectionList.js (revision 29)
@@ -24,13 +24,19 @@
2424 /** initialvalue */
2525 /* String */ self.initialValue = null;
2626
27+ /** initialvalueName */
28+ /* String */ self.initialValueName = null;
29+
2730 /** warnIncompleteInput */
28- /* boolean */ self.warnIncompleteInput = true;
31+ /* boolean */ self.warnIncompleteInput = false;
2932
3033 /** initialAutoSelected */
3134 /* boolean */ self.initialAutoSelected = false;
3235
36+ /** sendAllLevelValues */
37+ /* boolean */ self.sendAllLevelValues = false;
3338
39+
3440 /**
3541 * リストの要素を設定する。
3642 *
@@ -37,6 +43,8 @@
3743 * @param listItems リストの要素
3844 */
3945 self.setListItems = /* void */ function(/* Map<String, Object> */ listItems) {
46+ ArgContract.notNull("listItems", listItems);
47+
4048 self.listItems = listItems;
4149 };
4250
@@ -43,52 +51,42 @@
4351 /**
4452 * 初期値を設定する。
4553 *
46- * @param initialValue 初期値
54+ * @param initialValue 初期値の名前
55+ * @param initialValue 初期値の値
4756 */
48- self.setInitialValue = /* void */ function(/* String */ initialValue) {
57+ self.setInitialValue = /* void */ function(/* String */ initialValueName, /* String */ initialValue) {
58+ ArgContract.notBlank("initialValueName", initialValueName);
59+ ArgContract.notNull("initialValue", initialValue);
60+
61+ self.initialValueName = initialValueName;
4962 self.initialValue = initialValue;
5063 };
5164
5265 /**
53- * 入力が不完全な状態の時、警告するか否かを指定する。
66+ * 入力が不完全な状態の時、警告するか否かを指定する。(デフォルト値: false)
5467 *
5568 * @param warnIncompleteInput 入力が不完全な状態の時、警告するならtrue
5669 */
5770 self.setWarnIncompleteInput = /* void */ function(/* boolean */ warnIncompleteInput) {
58- self.warnIncompleteInput = warnIncompleteInput;
71+ self.warnIncompleteInput = !!warnIncompleteInput;
5972 };
6073
6174 /**
62- * 初期状態(画面に最初に表示するとき)で、自動選択を有効にするか否かを指定する。
75+ * 初期状態(画面に最初に表示するとき)で、自動選択を有効にするか否かを指定する。(デフォルト値: false)
6376 *
6477 * @param initialAutoSelected 初期状態で、自動選択を有効にするならtrue
6578 */
6679 self.setInitialAutoSelected = /* void */ function(/* boolean */ initialAutoSelected) {
67- self.initialAutoSelected = initialAutoSelected;
80+ self.initialAutoSelected = !!initialAutoSelected;
6881 };
6982
70-
7183 /**
72- * Option要素を作成する。
84+ * 選択した全ての階層の値を送信するか否かを指定する。(デフォルト値: false)
7385 *
74- * @param text
75- * @param value
76- * @return Option要素。
86+ * @param initialAutoSelected 選択した全ての階層の値を送信するならtrue
7787 */
78- /* private Function */ var createOption = /* Option */ function(/* String */ text, /* String */ value) {
79-
80- //IEだとこのやり方では動かない
81- //return new Option(text, value);
82-
83- /* Option */ var option = self.document.createElement("option");
84-
85- //IEだとこれはダメ
86- //option.text = text;
87-
88- option.appendChild(self.document.createTextNode(text));
89- option.value = value;
90-
91- return option;
88+ self.setSendAllLevelValues = /* void */ function(/* boolean */ sendAllLevelValues) {
89+ self.sendAllLevelValues = !!sendAllLevelValues;
9290 };
9391
9492 /**
@@ -95,17 +93,17 @@
9593 * @param listItemValue リスト要素
9694 * @return リスト要素の値
9795 */
98- /* private Function */ getValueOf = /* String */ function(/* Map<String, Object> */ listItemValue) {
96+ /* private Function */ var getValueOf = /* String */ function(/* Map<String, Object> */ listItemValue) {
9997 return listItemValue[NarrowDownSelectionList.METADATA_KEY].value;
100- }
98+ };
10199
102100 /**
103101 * @param listItemValue リスト要素
104102 * @return リスト要素の値
105103 */
106- /* private Function */ getNameOf = /* String */ function(/* Map<String, Object> */ listItemValue) {
104+ /* private Function */ var getNameOf = /* String */ function(/* Map<String, Object> */ listItemValue) {
107105 return listItemValue[NarrowDownSelectionList.METADATA_KEY].name;
108- }
106+ };
109107
110108 /**
111109 * 空のSelect要素を作成する。
@@ -114,9 +112,10 @@
114112 */
115113 /* private Function */ var createEmptySelect = /* Selectd */ function() {
116114 /* Select */ var selectElem = self.document.createElement("select");
117-
115+
118116 // 先頭に空選択肢を入れる
119- selectElem.appendChild(createOption(NarrowDownSelectionList.EMPTY_VALUE, ""));
117+ selectElem.appendChild(
118+ Utils.createOption(self.document, NarrowDownSelectionList.EMPTY_VALUE, ""));
120119
121120 selectElem.setOptions = /* void */ function(/* Map<String, Object> */ listItems) {
122121 if (!listItems) {
@@ -124,9 +123,10 @@
124123 }
125124
126125 // optionを全部消す
127- selectElem.options.length = 0;
126+ Utils.clearChildNodes(selectElem);
127+
128128 // 先頭に空選択肢を入れる
129- /* Option */ var emptyOption = createOption(NarrowDownSelectionList.EMPTY_VALUE, "");
129+ /* Option */ var emptyOption = Utils.createOption(self.document, NarrowDownSelectionList.EMPTY_VALUE, "");
130130 selectElem.appendChild(emptyOption);
131131
132132 // 動的リスト生成用に使うので保持しておく。
@@ -140,7 +140,7 @@
140140 /* Object */ var listItemValue = listItems[listItemKey];
141141
142142 selectElem.appendChild(
143- createOption(listItemKey, getValueOf(listItemValue)));
143+ Utils.createOption(self.document, listItemKey, getValueOf(listItemValue)));
144144 }
145145
146146 // 選択肢が一つしかない場合、選択状態にする
@@ -165,17 +165,29 @@
165165
166166 /* Map<String, String> */ var listItem = selectElem.listItems[listItemKey];
167167 if (selectedValue == getValueOf(listItem)) {
168- selectElem.name = getNameOf(listItem);
168+ self.setInputName(selectElem, getNameOf(listItem));
169169 return;
170170 }
171171 }
172+
173+ self.setInputName(selectElem, "");
172174 });
173175 };
174176
175177 return selectElem;
176- }
178+ };
177179
178180 /**
181+ * Select要素における、name属性の値の設定をフックするメソッド。
182+ *
183+ * @param selectElem Select要素
184+ * @param inputName Select要素のname属性の値
185+ */
186+ self.setInputName = /* void */ function(/* Select */ selectElem, /* String */ inputName) {
187+ selectElem.name = inputName;
188+ };
189+
190+ /**
179191 * 絞り込みリストの最大深さを取得する。
180192 *
181193 * @param listItems リストの要素
@@ -209,9 +221,11 @@
209221 * 初期値を復元する。
210222 *
211223 * @param narrowDownSelects
224+ * @param initialValueName
212225 * @param initialValue
213226 */
214- /* private Function */ var restoreSelectionState = function(/* List<Select> */ narrowDownSelects, /* Object */ initialValue) {
227+ /* private Function */ var restoreSelectionState = function(/* List<Select> */ narrowDownSelects,
228+ /* String */ initialValueName, /* String */ initialValue) {
215229
216230 // 選択されたキーのリスト
217231 /* List<String> */ var selectedItemKeys = [];
@@ -232,7 +246,11 @@
232246
233247 /* Object */ var listItemValue = listItems[listItemKey];
234248
235- if (listItemValue[NarrowDownSelectionList.METADATA_KEY].value == initialValue) {
249+ /* boolean */ var isTargetListItem =
250+ (listItemValue[NarrowDownSelectionList.METADATA_KEY].name == initialValueName) &&
251+ (listItemValue[NarrowDownSelectionList.METADATA_KEY].value == initialValue);
252+
253+ if (isTargetListItem) {
236254 // 大域脱出する
237255 throw 0;
238256 } else if (typeof(listItemValue) == "object") {
@@ -255,9 +273,7 @@
255273
256274
257275 // 選択されたキーの探索に失敗した場合は何もしない
258- if (selectedItemKeys.length != narrowDownSelects.length) {
259- return;
260- }
276+ // if (selectedItemKeys.length != narrowDownSelects.length) { return; }
261277
262278
263279 for (/* int */ var i = 0; i < selectedItemKeys.length; i++) {
@@ -333,6 +349,28 @@
333349 }
334350 });
335351
352+
353+ // フラグがONの場合、最後の選択済みしか送信しない(=フォーム名を消す)
354+ Utils.addEventListener(narrowDownSelect, "blur", /* void */ function() {
355+ if (self.sendAllLevelValues) {
356+ return;
357+ }
358+
359+ /* boolean */ var lastSelectedLevelFound = false;
360+ for (/* int */ var k = (narrowDownSelects.length - 1); 0 <= k; k--) {
361+ if (Utils.isEmptyString(narrowDownSelects[k].name)) {
362+ continue;
363+ }
364+
365+ if (lastSelectedLevelFound) {
366+ narrowDownSelects[k].name = "";
367+ } else {
368+ lastSelectedLevelFound = true;
369+ }
370+ }
371+ });
372+
373+
336374 narrowDownSelects.push(narrowDownSelect);
337375
338376 // ----
@@ -353,8 +391,8 @@
353391
354392
355393 // 初期値があれば状態を復元する
356- if (!!self.initialValue) {
357- restoreSelectionState(narrowDownSelects, self.initialValue);
394+ if (!!self.initialValueName) {
395+ restoreSelectionState(narrowDownSelects, self.initialValueName, self.initialValue);
358396 }
359397 // 初期状態における自動選択済みを解除する。(初期値が指定されていない場合のみ)
360398 else if (!self.initialAutoSelected) {
旧リポジトリブラウザで表示