asp.net实现类似MaskTextBox功能
最近项目中遇到一个文号格式验证问题,需要按照已定义的文号格式,输入内容,然后验证特定部分是否合法的功能。技术难度不是很大,关键是该文号格式可以自定义,这样就会造成待验证的特定部分是不定的,用正则表达式也很难匹配。比如文号格式:国教委[$YYYY$]年$MM$月第$0$号文件,其中$YYYY$表示四位年,$MM$表示两位月,$0$表示文件编号。如果格式变为国教委$YYYY$年$0$号或其他格式,正则很难匹配特定位置是否为正确的格式,最重要的是要获取到$0$表示的文件编号,如果是这样的格式:国教委$YYYY$$MM$$0$,同样都是数字,无法区分哪个是编号。于是考虑用正则表达式分析文号格式,然后动态生成各部分的文本框,给每个特定验证的部分以特定ID,在提交输入内容的时候将动态生成的文本框内容拼合起来,再获取特定验证部分的内容,这样就可以实现自定义格式的验证了。由于要动态生成和删除html元素,以及获取指定name和id的文本框内容,所以用jquery库会大大提高编程速度。
一、正则表达式分析文号格式
文号格式中的特定部分由$$分割,我们依次作为正则匹配的分界点,可以将文号格式拆分成固定和可变的部分,然后依次来动态生成文本框。
正则表达式:
1: var regPa = new RegExp("\\$(.*?)\\$","g");
匹配字符串:
1: pattArr = regPa.exec(fileNumformat)
二、动态生成文本框
1: var regPa = new RegExp("\\$(.*?)\\$","g");
2: var pattArr;
3: var iIndex=0; // 正则匹配项位置
4: var iCount=0; // 正则匹配个数
5: var strSplit="<span name='lbl_fileNum' id='span_fileNum_blank'> </span>"; // 分割文本框的字符
6: while((pattArr = regPa.exec(fileNumformat))!=null)
7: {
8: var textBoxStr=""; // 控件字符串
9: if(iIndex!=pattArr.index)
10: {
11: textBoxStr="<input name='txt_fileNum' id='txt_fileNum_"+(++iCount)+"' value='"+fileNumformat.substring(iIndex,pattArr.index)+"' type='text' style='width:80px'/>"+strSplit;
12: }
13: iCount++;
14: if(pattArr[1]=="0") // 流水号
15: {
16: textBoxStr+="<input name='txt_fileNum' id='txt_fileNum_num"+"' value='' type='text' style='width:40px'/>"+strSplit;
17: }
18: else
19: {
20: textBoxStr+="<input name='txt_fileNum' id='txt_fileNum_'"+iCount+"' value='' type='text' style='width:40px'/>"+strSplit;
21: }
22: $("#span_must").before(textBoxStr);
23: iIndex=pattArr.index+pattArr[0].length;
24: }
25: if(iIndex<fileNumformat.length)
26: {
27: $("#span_must").before("<input name='txt_fileNum' id='txt_fileNum_'"+(++iCount)+"' value='"+fileNumformat.substring(iIndex)+"' type='text' style='width:80px'/>"+strSplit)
28: }
上面的代码考虑了$$在最开始、最末位、两个$$紧挨的情况,可以正确分割文号格式中的各个部分。特别处理的部分就是如果当前特定格式是$0$即编号,就给他一个特定的id,以便于后边jquery获取编号。
三、获取填写后的文号和特定编号
1: var str="";
2: var currNum="";
3: $("[name='txt_fileNum']").each(function(){
4: str+=$(this).val();
5: });
6: alert("文号:"+str+"的编号是:"+$("#txt_fileNum_num").val());
四、清除动态生成的html标签
如果会多次匹配文号,即文号格式可动态选择,那么就需要将原来动态生成的html元素清除,然后再次分析、生成。
1: // 清除原来元素
2: $("[name='txt_fileNum'],[name='lbl_fileNum']").remove();
五、效果
六、全部源码
1: function SetFileNumTextBox(fileNumformat)
2: {
3: // 清除原来元素
4: $("[name='txt_fileNum'],[name='lbl_fileNum']").remove();
5:
6: if (fileNumformat == "" || fileNumformat == undefined)
7: {
8: $("#span_must").before("<span name='lbl_fileNum' id='span_fileNum_alert' style='color: #FF0000'>文号格式缺失</span>");
9: return;
10: }
11:
12: var regPa = new RegExp("\\$(.*?)\\$","g");
13: var pattArr;
14: var iIndex=0; // 正则匹配项位置
15: var iCount=0; // 正则匹配个数
16: var strSplit="<span name='lbl_fileNum' id='span_fileNum_blank'> </span>"; // 分割文本框的字符
17: while((pattArr = regPa.exec(fileNumformat))!=null)
18: {
19: var textBoxStr=""; // 控件字符串
20: if(iIndex!=pattArr.index)
21: {
22: textBoxStr="<input name='txt_fileNum' id='txt_fileNum_"+(++iCount)+"' value='"+fileNumformat.substring(iIndex,pattArr.index)+"' type='text' style='width:80px'/>"+strSplit;
23: }
24: iCount++;
25: if(pattArr[1]=="0") // 流水号
26: {
27: textBoxStr+="<input name='txt_fileNum' id='txt_fileNum_num"+"' value='' type='text' style='width:40px'/>"+strSplit;
28: }
29: else
30: {
31: textBoxStr+="<input name='txt_fileNum' id='txt_fileNum_'"+iCount+"' value='' type='text' style='width:40px'/>"+strSplit;
32: }
33: $("#span_must").before(textBoxStr);
34: iIndex=pattArr.index+pattArr[0].length;
35: }
36: if(iIndex<fileNumformat.length)
37: {
38: $("#span_must").before("<input name='txt_fileNum' id='txt_fileNum_'"+(++iCount)+"' value='"+fileNumformat.substring(iIndex)+"' type='text' style='width:80px'/>"+strSplit)
39: }
40: $("#span_must").before("<span name='lbl_fileNum' id='span_fileNum_help' style='color: #FF0000'>"+fileNumformat+"</span>");
41: document.getElementById(<%="\""+hid_currNum.ClientID+"\"" %>).value=iCount;
42: }
传入参数是文号格式,span_must就是效果图中的“*”,作为一个插入html元素的标志位置。
七、兼容性
已解决由于RegExp的lastIndex属性在Firefox和Chrome中不存在而导致截取字符串内容出错的问题,由匹配字符串长度加index来替换lastIndex的计算,经测试,IE、Firefox和Chrome都无问题。
祝大家好运!