Struts2客戶端驗(yàn)證的一個(gè)bug
Posted on 2007-06-03 17:56 shaofan 閱讀(2540) 評(píng)論(3) 編輯 收藏 所屬分類: JavaStruts2默認(rèn)theme是xhtml,它用表格來(lái)對(duì)表單中的控件進(jìn)行排版。它也提供一個(gè)客戶端的js驗(yàn)證功能,但是它的js腳本卻有些問(wèn)題,在某些情況下,前次驗(yàn)證的提示信息無(wú)法被清除,提示信息會(huì)不斷的累積顯示在屏幕上。而按照設(shè)計(jì),每次提交表單時(shí)應(yīng)只顯示每次驗(yàn)證的出錯(cuò)信息。
它的客戶端驗(yàn)證的流程大概是這樣,用戶提交表單時(shí),對(duì)各個(gè)控件的輸入按預(yù)先設(shè)置的規(guī)則進(jìn)行驗(yàn)證,如果有問(wèn)題,則清除表單里原有的出錯(cuò)提示信息,并寫入新的提示。其設(shè)計(jì)的功能是把出錯(cuò)信息寫表格里出錯(cuò)控件的上方,以便用戶看得更加清楚。問(wèn)題就出在其用來(lái)清除原出錯(cuò)信息的函數(shù),其代碼是這樣的(在struts.jar的template/xhtml目錄下可以找到):
看這個(gè)函數(shù)的前三行,它試圖取得form的第1個(gè)或第2個(gè)子節(jié)點(diǎn),并把它作為table來(lái)處理(看接下來(lái)的幾行)。要想清除表格里的錯(cuò)誤信息,首先要取得表格本身,這沒(méi)錯(cuò),但是如果第1個(gè)或第2個(gè)子節(jié)點(diǎn)不是table的話,腳本就會(huì)出錯(cuò),造成原出錯(cuò)信息無(wú)法清除,這樣每次提交后的提示信息就會(huì)累積在屏幕上。
要解決這個(gè)問(wèn)題有兩個(gè)辦法:
它的客戶端驗(yàn)證的流程大概是這樣,用戶提交表單時(shí),對(duì)各個(gè)控件的輸入按預(yù)先設(shè)置的規(guī)則進(jìn)行驗(yàn)證,如果有問(wèn)題,則清除表單里原有的出錯(cuò)提示信息,并寫入新的提示。其設(shè)計(jì)的功能是把出錯(cuò)信息寫表格里出錯(cuò)控件的上方,以便用戶看得更加清楚。問(wèn)題就出在其用來(lái)清除原出錯(cuò)信息的函數(shù),其代碼是這樣的(在struts.jar的template/xhtml目錄下可以找到):
1 function clearErrorMessages(form) {
2
3 var table = form.childNodes[1];
4 if( typeof table == "undefined" ) {
5 table = form.childNodes[0];
6 }
7
8 // clear out any rows with an "errorFor" attribute
9 var rows = table.rows;
10 var rowsToDelete = new Array();
11 if (rows == null){
12 return;
13 }
14
15 for(var i = 0; i < rows.length; i++) {
16 var r = rows[i];
17 if (r.getAttribute("errorFor")) {
18 rowsToDelete.push(r);
19 }
20 }
21
22 // now delete the rows
23 for (var i = 0; i < rowsToDelete.length; i++) {
24 var r = rowsToDelete[i];
25 table.deleteRow(r.rowIndex);
26 //table.removeChild(rowsToDelete[i]);
27 }
28 }
2
3 var table = form.childNodes[1];
4 if( typeof table == "undefined" ) {
5 table = form.childNodes[0];
6 }
7
8 // clear out any rows with an "errorFor" attribute
9 var rows = table.rows;
10 var rowsToDelete = new Array();
11 if (rows == null){
12 return;
13 }
14
15 for(var i = 0; i < rows.length; i++) {
16 var r = rows[i];
17 if (r.getAttribute("errorFor")) {
18 rowsToDelete.push(r);
19 }
20 }
21
22 // now delete the rows
23 for (var i = 0; i < rowsToDelete.length; i++) {
24 var r = rowsToDelete[i];
25 table.deleteRow(r.rowIndex);
26 //table.removeChild(rowsToDelete[i]);
27 }
28 }
看這個(gè)函數(shù)的前三行,它試圖取得form的第1個(gè)或第2個(gè)子節(jié)點(diǎn),并把它作為table來(lái)處理(看接下來(lái)的幾行)。要想清除表格里的錯(cuò)誤信息,首先要取得表格本身,這沒(méi)錯(cuò),但是如果第1個(gè)或第2個(gè)子節(jié)點(diǎn)不是table的話,腳本就會(huì)出錯(cuò),造成原出錯(cuò)信息無(wú)法清除,這樣每次提交后的提示信息就會(huì)累積在屏幕上。
要解決這個(gè)問(wèn)題有兩個(gè)辦法:
- 寫代碼時(shí)要小心,保證form的第1或2個(gè)子節(jié)點(diǎn)是table,不要在生成table前加其他代碼。
- 或,修改xhtml的validation.js,使它總能獲得正確的table元素,重新打包到struts.jar。