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都无问题。
祝大家好运!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述