作为上一帖( Struts Validator 之 javascript 分析)的续,发表此帖!
 
首先,描述一下问题:
   因为最近需要在进行中的 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];"));
    }
  
  接下来,我提一下 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");
        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) {
                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;
                }
                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;
    }
 
    请注意我在上面的代码中标示 红色的代码行,看到了吧,其实 '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");
        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) {
                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;
                }
                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;
    }
 
总结:
   由于 prototype.js 对 Object() 类作了扩展,因此上面的 eval() 语句动态生成的对象除了 this.a0  还有 其他的字段, 而 Struts Validator 所需要的是配置文件内容的客户端表示的 a[XXXX] 字段而已。
   注意!要在 Struts Validator 包中的javascript目录里的的每一个 .js 文件里的函数内部都加入以上标示为 红色的代码行,并重新打包成.jar。
 
后语:
   本帖提到的Ajax支持的后端也是本人在Struts Action 基础上实现的,后端没有用其他的Ajax框架,前端还用到了 Rico 框架!
   bye!