首先,描述一下问题:
?? 因为最近需要在进行中的 J2EE 项目中(已经快结束了,不然会考虑用 ROR的 ),需要支持 AJAX 的功能(Type Aheand suggest),所以在页面中引用了 prototype.js , 同时,项目本身早就用上 Struts Validator,并且启用client端的就 javascript 验证,在成功实现了Ajax 的 Type Ahead Suggest 后, 欣喜之后发现:client端的就 javascript 验证不起作用了,查了3个小时,最终发现:是上述两个框架冲突了。
?
接下来,详解:
?? 以上一帖的“必填”验证为例:
?? function theForm_required ()
??? {
????? this.a0 = new Array("theField", "The Field is required.", new Function ("varName", " return this[varName];"));
????? this.a0 = new Array("theField", "The Field is required.", new Function ("varName", " return this[varName];"));
??? }
??
? 接下来,我提一下 Struts Validator 包中的javascript目录里的validateRequired.js 的function validateRequired(form) 函数,如下:
?
? function validateRequired(form) {
??????? var isValid = true;
??????? var focusField = null;
??????? var i = 0;
??????? var fields = new Array();
??????? var formName = form.getAttributeNode("name");
??????? var isValid = true;
??????? var focusField = null;
??????? var i = 0;
??????? var fields = new Array();
??????? var formName = form.getAttributeNode("name");
??????? oRequired = eval('new ' + formName.value + '_required()');
alert(oRequired);
??????? for (x in oRequired) {
??????????? var field = form[oRequired[x][0]];
alert(x);
??????????? if ((field.type == 'hidden' ||
??????????????? field.type == 'text' ||
??????????????? field.type == 'textarea' ||
??????????????? field.type == 'file' ||
??????????????? field.type == 'checkbox' ||
??????????????? field.type == 'select-one' ||
??????????????? field.type == 'password') &&
??????????????? field.disabled == false) {
alert(oRequired);
??????? for (x in oRequired) {
??????????? var field = form[oRequired[x][0]];
alert(x);
??????????? if ((field.type == 'hidden' ||
??????????????? field.type == 'text' ||
??????????????? field.type == 'textarea' ||
??????????????? field.type == 'file' ||
??????????????? field.type == 'checkbox' ||
??????????????? field.type == 'select-one' ||
??????????????? field.type == 'password') &&
??????????????? field.disabled == false) {
??????????????? var value = '';
??????????????? // get field's value
??????????????? if (field.type == "select-one") {
??????????????????? var si = field.selectedIndex;
??????????????????? if (si >= 0) {
??????????????????????? value = field.options[si].value;
??????????????????? }
??????????????? } else if (field.type == 'checkbox') {
??????????????????? if (field.checked) {
??????????????????????? value = field.value;
??????????????????? }
??????????????? } else {
??????????????????? value = field.value;
??????????????? }
??????????????? // get field's value
??????????????? if (field.type == "select-one") {
??????????????????? var si = field.selectedIndex;
??????????????????? if (si >= 0) {
??????????????????????? value = field.options[si].value;
??????????????????? }
??????????????? } else if (field.type == 'checkbox') {
??????????????????? if (field.checked) {
??????????????????????? value = field.value;
??????????????????? }
??????????????? } else {
??????????????????? value = field.value;
??????????????? }
??????????????? if (trim(value).length == 0) {
??????????????????? if (i == 0) {
??????????????????????? focusField = field;
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid = false;
??????????????? }
??????????? } else if (field.type == "select-multiple") {
??????????????? var numOptions = field.options.length;
??????????????? lastSelected=-1;
??????????????? for(loop=numOptions-1;loop>=0;loop--) {
??????????????????? if(field.options[loop].selected) {
??????????????????????? lastSelected = loop;
??????????????????????? value = field.options[loop].value;
??????????????????????? break;
??????????????????? }
??????????????? }
??????????????? if(lastSelected < 0 || trim(value).length == 0) {
??????????????????? if(i == 0) {
??????????????????????? focusField = field;
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid=false;
??????????????? }
??????????? } else if ((field.length > 0) && (field[0].type == 'radio' || field[0].type == 'checkbox')) {
??????????????? isChecked=-1;
??????????????? for (loop=0;loop < field.length;loop++) {
??????????????????? if (field[loop].checked) {
??????????????????????? isChecked=loop;
??????????????????????? break; // only one needs to be checked
??????????????????? }
??????????????? }
??????????????? if (isChecked < 0) {
??????????????????? if (i == 0) {
??????????????????????? focusField = field[0];
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid=false;
??????????????? }
??????????? }
??????? }
??????? if (fields.length > 0) {
?????????? focusField.focus();
?????????? alert(fields.join('\n'));
??????? }
??????? return isValid;
??? }
??????????????????????? focusField = field;
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid = false;
??????????????? }
??????????? } else if (field.type == "select-multiple") {
??????????????? var numOptions = field.options.length;
??????????????? lastSelected=-1;
??????????????? for(loop=numOptions-1;loop>=0;loop--) {
??????????????????? if(field.options[loop].selected) {
??????????????????????? lastSelected = loop;
??????????????????????? value = field.options[loop].value;
??????????????????????? break;
??????????????????? }
??????????????? }
??????????????? if(lastSelected < 0 || trim(value).length == 0) {
??????????????????? if(i == 0) {
??????????????????????? focusField = field;
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid=false;
??????????????? }
??????????? } else if ((field.length > 0) && (field[0].type == 'radio' || field[0].type == 'checkbox')) {
??????????????? isChecked=-1;
??????????????? for (loop=0;loop < field.length;loop++) {
??????????????????? if (field[loop].checked) {
??????????????????????? isChecked=loop;
??????????????????????? break; // only one needs to be checked
??????????????????? }
??????????????? }
??????????????? if (isChecked < 0) {
??????????????????? if (i == 0) {
??????????????????????? focusField = field[0];
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid=false;
??????????????? }
??????????? }
??????? }
??????? if (fields.length > 0) {
?????????? focusField.focus();
?????????? alert(fields.join('\n'));
??????? }
??????? return isValid;
??? }
?
??? 请注意我在上面的代码中标示红色的代码行,看到了吧,其实 'new ' + formName.value + '_required()' 就是 theForm_required() 函数名, 而 oRequired? 就是利用javascript 强大的动态解析功能得到的theForm_required对象,后面的代码我就不用多做解析了吧,就是循环此对象的每个内部的数组(每个数组就是配置文件内容的客户端表示,就此例来说分别是:字段名,出错提示,提示参数获取函数)。
?
本帖重点:
?
?? 说了那么多,前面描述的问题还没用解决呢? 好,开始把,其实很简单(看似简单的问题最会搞死人! ^_^); 只要在 Struts Validator 包中的javascript目录里的的每一个 .js 文件里的函数内部加入以下标示为红色的代码行即可!?
???
?? function validateRequired(form) {
??????? var isValid = true;
??????? var focusField = null;
??????? var i = 0;
??????? var fields = new Array();
??????? var formName = form.getAttributeNode("name");
??????? var isValid = true;
??????? var focusField = null;
??????? var i = 0;
??????? var fields = new Array();
??????? var formName = form.getAttributeNode("name");
??????? oRequired = eval('new ' + formName.value + '_required()');
alert(oRequired);
??????? for (x in oRequired) {
??????????? var re = /^a\d+/;
??????????? if(! re.test(x) )
??????????? {
??????????? ?continue;
??????????? }
??????????? var field = form[oRequired[x][0]];
alert(x);
??????????? if ((field.type == 'hidden' ||
??????????????? field.type == 'text' ||
??????????????? field.type == 'textarea' ||
??????????????? field.type == 'file' ||
??????????????? field.type == 'checkbox' ||
??????????????? field.type == 'select-one' ||
??????????????? field.type == 'password') &&
??????????????? field.disabled == false) {
alert(oRequired);
??????? for (x in oRequired) {
??????????? var re = /^a\d+/;
??????????? if(! re.test(x) )
??????????? {
??????????? ?continue;
??????????? }
??????????? var field = form[oRequired[x][0]];
alert(x);
??????????? if ((field.type == 'hidden' ||
??????????????? field.type == 'text' ||
??????????????? field.type == 'textarea' ||
??????????????? field.type == 'file' ||
??????????????? field.type == 'checkbox' ||
??????????????? field.type == 'select-one' ||
??????????????? field.type == 'password') &&
??????????????? field.disabled == false) {
??????????????? var value = '';
??????????????? // get field's value
??????????????? if (field.type == "select-one") {
??????????????????? var si = field.selectedIndex;
??????????????????? if (si >= 0) {
??????????????????????? value = field.options[si].value;
??????????????????? }
??????????????? } else if (field.type == 'checkbox') {
??????????????????? if (field.checked) {
??????????????????????? value = field.value;
??????????????????? }
??????????????? } else {
??????????????????? value = field.value;
??????????????? }
??????????????? // get field's value
??????????????? if (field.type == "select-one") {
??????????????????? var si = field.selectedIndex;
??????????????????? if (si >= 0) {
??????????????????????? value = field.options[si].value;
??????????????????? }
??????????????? } else if (field.type == 'checkbox') {
??????????????????? if (field.checked) {
??????????????????????? value = field.value;
??????????????????? }
??????????????? } else {
??????????????????? value = field.value;
??????????????? }
??????????????? if (trim(value).length == 0) {
??????????????????? if (i == 0) {
??????????????????????? focusField = field;
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid = false;
??????????????? }
??????????? } else if (field.type == "select-multiple") {
??????????????? var numOptions = field.options.length;
??????????????? lastSelected=-1;
??????????????? for(loop=numOptions-1;loop>=0;loop--) {
??????????????????? if(field.options[loop].selected) {
??????????????????????? lastSelected = loop;
??????????????????????? value = field.options[loop].value;
??????????????????????? break;
??????????????????? }
??????????????? }
??????????????? if(lastSelected < 0 || trim(value).length == 0) {
??????????????????? if(i == 0) {
??????????????????????? focusField = field;
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid=false;
??????????????? }
??????????? } else if ((field.length > 0) && (field[0].type == 'radio' || field[0].type == 'checkbox')) {
??????????????? isChecked=-1;
??????????????? for (loop=0;loop < field.length;loop++) {
??????????????????? if (field[loop].checked) {
??????????????????????? isChecked=loop;
??????????????????????? break; // only one needs to be checked
??????????????????? }
??????????????? }
??????????????? if (isChecked < 0) {
??????????????????? if (i == 0) {
??????????????????????? focusField = field[0];
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid=false;
??????????????? }
??????????? }
??????? }
??????? if (fields.length > 0) {
?????????? focusField.focus();
?????????? alert(fields.join('\n'));
??????? }
??????? return isValid;
??? }
??????????????????????? focusField = field;
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid = false;
??????????????? }
??????????? } else if (field.type == "select-multiple") {
??????????????? var numOptions = field.options.length;
??????????????? lastSelected=-1;
??????????????? for(loop=numOptions-1;loop>=0;loop--) {
??????????????????? if(field.options[loop].selected) {
??????????????????????? lastSelected = loop;
??????????????????????? value = field.options[loop].value;
??????????????????????? break;
??????????????????? }
??????????????? }
??????????????? if(lastSelected < 0 || trim(value).length == 0) {
??????????????????? if(i == 0) {
??????????????????????? focusField = field;
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid=false;
??????????????? }
??????????? } else if ((field.length > 0) && (field[0].type == 'radio' || field[0].type == 'checkbox')) {
??????????????? isChecked=-1;
??????????????? for (loop=0;loop < field.length;loop++) {
??????????????????? if (field[loop].checked) {
??????????????????????? isChecked=loop;
??????????????????????? break; // only one needs to be checked
??????????????????? }
??????????????? }
??????????????? if (isChecked < 0) {
??????????????????? if (i == 0) {
??????????????????????? focusField = field[0];
??????????????????? }
??????????????????? fields[i++] = oRequired[x][1];
??????????????????? isValid=false;
??????????????? }
??????????? }
??????? }
??????? if (fields.length > 0) {
?????????? focusField.focus();
?????????? alert(fields.join('\n'));
??????? }
??????? return isValid;
??? }
?
总结:
?? 由于 prototype.js 对 Object() 类作了扩展,因此上面的 eval() 语句动态生成的对象除了this.a0? 还有其他的字段, 而 Struts Validator 所需要的是配置文件内容的客户端表示的 a[XXXX] 字段而已。
???注意!要在 Struts Validator 包中的javascript目录里的的每一个 .js 文件里的函数内部都加入以上标示为红色的代码行,并重新打包成.jar。
?
后语:
?? 本帖提到的Ajax支持的后端也是本人在Struts Action 基础上实现的,后端没有用其他的Ajax框架,前端还用到了 Rico 框架!