1
*--------------- 客户端表单通用验证checkForm(oForm) -----------------
2
* 本程序最初是由wanghr100(灰豆宝宝.net)的checkForm基础上进行修改的,增加了很多功能,如下:
3
* 1.对非ie的支持
4
* 2.增加了内置表达式和内置提示
5
* 3.增加了显示方式(弹出式和页面显示式)
6
* 4.增加了显示一条和显示全部
7
* 5.进行了封装(CLASS_CHECK)
8
* 6.支持外接函数或表达式(应用在密码一致)
9
* 7.简化了调用方式,所有操作只需要<script language='javascript' src='checkform.js'>,
10
然后在HTML里定义各标签验证格式
11
* 8.对IE增加了对键盘输入的限制(如:定义usage='int'时,输入框只能输入数字(非IE无效)
12
* 9.增加了对disabled的不验证
13
* 10.自定义报警方式(重写showMessageEx方法)
14
*-----------------------------申明信息-----------------------------
15
*
16
* 作者: ttyp
17
* 邮箱: ttyp@21cn.com
18
* 博客: http://www.cnblogs.com/ttyp/
19
* 声明: 对本程序可以任意复制传播,但请保留这些声明,对于内置的表达式有些没有做到很严格,如果你
20
有好的建议和意见,欢迎邮件和我联系或者上我的博客留言
21
22
* 简介:
23
本程序只需要对需要验证的标签设置三个属性:usage,exp,tip
24
25
usage : 内置格式或表达式或函数
26
exp : 正则表达式(注意如果指定了usage则忽略exp)
27
tip : 出错提示(如果是内置格式可以不要此属性,有缺省提示)
28
29
调用时只需要引用<script language='javascript' src='checkform.js'>,然后为每个标记
30
增加以上3个属性(不一定需要全部)
31
32
* 原作者: wanghr100(灰豆宝宝.net)
33
* email: wanghr100@126.com
34
*
35
*--------------- 客户端表单通用验证checkForm(oForm) -----------------
36
*/
37
////////////////////////////////////////////////////////////////////////////////
38
39
40
function CLASS_CHECK()
41

{
42
this.pass = true; //是否通过验证
43
this.showAll = true; //是否显示所有的验证错误
44
this.alert = false; //报警方式(默认alert报警)
45
this.message = ""; //错误内容
46
this.first = null; //在显示全部验证错误时的第一个错误控件(用于回到焦点)
47
48
//定义内置格式
49
var aUsage =
50
{
51
"int":"^([+-]?)\\d+$", //整数
52
"int+":"^([+]?)\\d+$", //正整数
53
"int-":"^-\\d+$", //负整数
54
"num":"^([+-]?)\\d*\\.?\\d+$", //数字
55
"num+":"^([+]?)\\d*\\.?\\d+$", //正数
56
"num-":"^-\\d*\\.?\\d+$", //负数
57
"float":"^([+-]?)\\d*\\.\\d+$", //浮点数
58
"float+":"^([+]?)\\d*\\.\\d+$", //正浮点数
59
"float-":"^-\\d*\\.\\d+$", //负浮点数
60
//邮件
61
"email":"^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$",
62
"color":"^#[a-fA-F0-9]{6}", //颜色
63
"url":"^http[s]?:\\/\\/([\\w-]+\\.)+[\\w-]+([\\w-./?%&=]*)?$", //联接
64
"chinese":"^[\\u4E00-\\u9FA5\\uF900-\\uFA2D]+$", //仅中文
65
"ascii":"^[\\x00-\\xFF]+$", //仅ACSII字符
66
"zipcode":"^\\d{6}$", //邮编
67
"mobile":"^0{0,1}13[0-9]{9}$", //手机
68
"ip4":"^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}.\\d{1,3}$", //ip地址
69
"notempty":"^\\S+$", //非空
70
"picture":"(.*)\\.(jpg|bmp|gif|ico|pcx|jpeg|tif|png|raw|tga)$", //图片
71
"rar":"(.*)\\.(rar|zip|7zip|tgz)$", //压缩文件
72
"date":"^\\d{4}(\\-|\\/|\.)\\d{1,2}\\1\\d{1,2}$" //日期
73
};
74
75
//缺省消息
76
var aMessage =
77
{
78
"int" :"请输入整数", //整数
79
"int+" :"请输入正整数", //正整数
80
"int-" :"请输入负整数", //负整数
81
"num" :"请输入数字", //数字
82
"num+" :"请输入正数", //正数
83
"num-" :"请输入负整数", //负数
84
"float" :"请输入浮点数", //浮点数
85
"float+":"请输入正浮点数", //正浮点数
86
"float-":"请输入负浮点数", //负浮点数
87
"email" :"请输入正确的邮箱地址", //邮件
88
"color" :"请输入正确的颜色", //颜色
89
"url" :"请输入正确的连接地址", //联接
90
"chinese":"请输入中文", //中文
91
"ascii" :"请输入ascii字符", //仅ACSII字符
92
"zipcode":"请输入正确的邮政编码", //邮编
93
"mobile":"请输入正确的手机号码", //手机
94
"ip4" :"请输入正确的IP地址", //ip地址
95
"notempty":"不能为空", //非空
96
"picture":"请选择图片", //图片
97
"rar" :"请输入压缩文件", //压缩文件
98
"date" :"请输入正确的日期" //日期
99
}
100
101
var me = this;
102
103
function checkForm(oForm)
104
{
105
me.pass = true;
106
me.message = "";
107
me.first = null;
108
var els = oForm.elements;
109
//遍历所有表元素
110
for(var i=0;i<els.length;i++)
111
{
112
//取得格式
113
var sUsage = els[i].getAttribute("Usage");
114
var sReg = "";
115
116
//如果设置Usage,则使用内置正则表达式,忽略Exp
117
if(typeof(sUsage)!="undefined"&&sUsage!=null)
118
{
119
//如果Usage在表达室里找到,则使用内置表达式,无则认为是表达式;表达式可以是函数;
120
if(aUsage[sUsage]!=null)
121
{
122
sReg = aUsage[sUsage];
123
}
124
else
125
{
126
try
127
{
128
if(eval(sUsage)==false)
129
{
130
me.pass = false;
131
if(me.first==null)
132
{
133
me.first = els[i];
134
}
135
136
addMessage(getMessage(els[i]));
137
138
if(me.showAll==false)
139
{
140
setFocus(els[i]);
141
break;
142
}
143
}
144
}
145
catch(e)
146
{
147
alert("表达式[" + sUsage +"]错误:" + e.description)
148
return false;
149
}
150
}
151
}
152
else
153
{
154
sReg = els[i].getAttribute("Exp");
155
}
156
157
if(typeof(sReg)!="undefined"&&sReg!=null)
158
{
159
//对于失效状态不验证
160
if(isDisabled(els[i])==true)
161
{
162
continue;
163
}
164
165
//取得表单的值,用通用取值函数
166
var sVal = getValue(els[i]);
167
//字符串->正则表达式,不区分大小写
168
var reg = new RegExp(sReg,"i");
169
if(!reg.test(sVal))
170
{
171
me.pass = false;
172
if(me.first==null)
173
{
174
me.first = els[i];
175
}
176
177
//alert(reg);
178
//验证不通过,弹出提示warning
179
var sTip = getMessage(els[i]);
180
if(sTip.length==0&&typeof(sUsage)!="undefined"&&sUsage!=null&&aMessage[sUsage]!=null)
181
{
182
sTip = aMessage[sUsage];
183
}
184
addMessage(sTip);
185
186
if(me.showAll==false)
187
{
188
//该表单元素取得焦点,用通用返回函数
189
setFocus(els[i]);
190
break;
191
}
192
193
}
194
}
195
}
196
197
if(me.pass==false)
198
{
199
showMessage();
200
201
if(me.first!=null&&me.showAll==true)
202
{
203
setFocus(me.first);
204
}
205
}
206
207
return me.pass;
208
}
209
210
/**//*
211
* 添加错误信息
212
*/
213
function addMessage(msg)
214
{
215
if(me.alert==true)
216
{
217
me.message += msg + "\n";
218
}
219
else
220
{
221
me.message += msg + "<br>";
222
}
223
}
224
225
/**//*
226
* 显示错误
227
*/
228
function getMessage(els)
229
{
230
var sTip = els.getAttribute("tip");
231
if(typeof(sTip)!="undefined"&&sTip!=null)
232
{
233
return sTip;
234
}
235
else
236
{
237
return "";
238
}
239
}
240
241
242
/**//*
243
* 显示错误
244
*/
245
function showMessage()
246
{
247
//外接显示错误函数
248
if(typeof(me.showMessageEx)=="function")
249
{
250
return me.showMessageEx(me.message);
251
}
252
253
if(me.alert==true)
254
{
255
alert(me.message);
256
}
257
else
258
{
259
var divTip;
260
divTip = document.getElementById("divErrorMessage");
261
try
262
{
263
if(typeof(divTip)=="undefined"||divTip==null)
264
{
265
divTip = document.createElement("div");
266
divTip.id = "divErrorMessage";
267
divTip.name = "divErrorMessage";
268
divTip.style.color = "red";
269
document.body.appendChild(divTip);
270
}
271
272
divTip.innerHTML = me.message;
273
}catch(e)
{}
274
}
275
}
276
277
/**//*
278
* 获得元素是否失效(失效的元素不做判断)
279
*/
280
function isDisabled(el)
281
{
282
//对于radio,checkbox元素,只要其中有一个非失效元素就验证
283
if(el.type=="radio"||el.type=="checkbox")
284
{
285
//取得第一个元素的name,搜索这个元素组
286
var tmpels = document.getElementsByName(el.name);
287
for(var i=0;i<tmpels.length;i++)
288
{
289
if(tmpels[i].disabled==false)
290
{
291
return false;
292
}
293
}
294
return true;
295
}
296
else
297
{
298
return el.disabled;
299
}
300
}
301
302
303
/**//*
304
* 取得对象的值(对于单选多选框把其选择的个数作为需要验证的值)
305
*/
306
function getValue(el)
307
{
308
//取得表单元素的类型
309
var sType = el.type;
310
switch(sType)
311
{
312
//文本输入框,直接取值el.value
313
case "text":
314
case "hidden":
315
case "password":
316
case "file":
317
case "textarea": return el.value;
318
//单多下拉菜单,遍历所有选项取得被选中的个数返回结果"0"表示选中一个,"00"表示选中两个
319
case "checkbox":
320
case "radio": return getRadioValue(el);
321
case "select-one":
322
case "select-multiple": return getSelectValue(el);
323
}
324
//取得radio,checkbox的选中数,用"0"来表示选中的个数,我们写正则的时候就可以通过0{1,}来表示选中个数
325
function getRadioValue(el)
326
{
327
var sValue = "";
328
//取得第一个元素的name,搜索这个元素组
329
var tmpels = document.getElementsByName(el.name);
330
for(var i=0;i<tmpels.length;i++)
331
{
332
if(tmpels[i].checked)
333
{
334
sValue += "0";
335
}
336
}
337
return sValue;
338
}
339
//取得select的选中数,用"0"来表示选中的个数,我们写正则的时候就可以通过0{1,}来表示选中个数
340
function getSelectValue(el)
341
{
342
var sValue = "";
343
for(var i=0;i<el.options.length;i++)
344
{
345
//单选下拉框提示选项设置为value=""
346
if(el.options[i].selected && el.options[i].value!="")
347
{
348
sValue += "0";
349
}
350
}
351
return sValue;
352
}
353
}
354
355
/**//*
356
* 对没有通过验证的元素设置焦点
357
*/
358
function setFocus(el)
359
{
360
//取得表单元素的类型
361
var sType = el.type;
362
switch(sType)
363
{
364
//文本输入框,光标定位在文本输入框的末尾
365
case "text":
366
case "hidden":
367
case "password":
368
case "file":
369
case "textarea":
370
try
{el.focus();var rng = el.createTextRange(); rng.collapse(false); rng.select();}catch(e)
{};
371
break;
372
373
//单多选,第一选项非失效控件取得焦点
374
case "checkbox":
375
case "radio":
376
var els = document.getElementsByName(el.name);
377
for(var i=0;i<els.length;i++)
378
{
379
if(els[i].disabled == false)
380
{
381
els[i].focus();
382
break;
383
}
384
}
385
break;
386
case "select-one":
387
case "select-multiple":
388
el.focus();
389
break;
390
}
391
}
392
393
394
//自动绑定到所有form的onsubmit事件
395
if(window.attachEvent)
396
{
397
window.attachEvent("onload",function()
{for(var i=0;i<document.forms.length;i++)
{var theFrom = document.forms[i]; if(theFrom)
{theFrom.attachEvent("onsubmit",function()
{return checkForm(theFrom);});}}});
398
}
399
else
400
{
401
window.onsubmit = function(e)
{var theFrom = e.target;if(theFrom)
{return checkForm(theFrom);}}
402
}
403
404
this.keyCheck = function()
405
{
406
if(window.attachEvent)
407
{
408
window.attachEvent("onload",function()
{for(var i=0;i<document.forms.length;i++)
{var theFrom = document.forms[i]; if(theFrom)
{myKeyCheck(theFrom);}}});
409
}
410
else
411
{
412
//TOOD
413
}
414
415
function myKeyCheck(oForm)
416
{
417
var els = oForm.elements;
418
//遍历所有表元素
419
for(var i=0;i<els.length;i++)
420
{
421
//取得格式
422
var sUsage = els[i].getAttribute("Usage");
423
424
//如果设置Usage,则使用内置正则表达式,忽略Exp
425
if(typeof(sUsage)!="undefined"&&sUsage!=null)
426
{
427
switch(sUsage.toLowerCase ())
428
{
429
case "zipcode":
430
case "int":
431
els[i].onkeypress = function()
{return /\d/.test(String.fromCharCode(event.keyCode))||(this.value.indexOf('+')<0?String.fromCharCode(event.keyCode)=="+":false)||(this.value.indexOf('-')<0?String.fromCharCode(event.keyCode)=="-":false);}
432
els[i].onpaste = function()
{return !clipboardData.getData('text').match(/\D/);}
433
els[i].ondragenter = function()
{return false;}
434
els[i].style.imeMode= "disabled";
435
break;
436
case "mobile":
437
case "int+":
438
els[i].onkeypress = function()
{return /\d/.test(String.fromCharCode(event.keyCode))||(this.value.indexOf('+')<0?String.fromCharCode(event.keyCode)=="+":false);}
439
els[i].onpaste = function()
{return !clipboardData.getData('text').match(/\D/);}
440
els[i].ondragenter = function()
{return false;}
441
els[i].style.imeMode= "disabled";
442
break;
443
case "int-":
444
els[i].onkeypress = function()
{return /\d/.test(String.fromCharCode(event.keyCode))||(this.value.indexOf('-')<0?String.fromCharCode(event.keyCode)=="-":false);}
445
els[i].onpaste = function()
{return !clipboardData.getData('text').match(/\D/);}
446
els[i].ondragenter = function()
{return false;}
447
els[i].style.imeMode= "disabled";
448
break;
449
case "float":
450
case "num":
451
els[i].onkeypress = function()
{return /[\+\-\.]|\d/.test(String.fromCharCode(event.keyCode));}
452
els[i].onpaste = function()
{return !clipboardData.getData('text').match(/\D/);}
453
els[i].ondragenter = function()
{return false;}
454
els[i].style.imeMode= "disabled";
455
break;
456
case "float+":
457
case "num+":
458
els[i].onkeypress = function()
{return /[\+\.]|\d/.test(String.fromCharCode(event.keyCode));}
459
els[i].onpaste = function()
{return !clipboardData.getData('text').match(/\D/);}
460
els[i].ondragenter = function()
{return false;}
461
els[i].style.imeMode= "disabled";
462
break;
463
case "float-":
464
case "num-":
465
els[i].onkeypress = function()
{return /[\-\.]|\d/.test(String.fromCharCode(event.keyCode));}
466
els[i].onpaste = function()
{return !clipboardData.getData('text').match(/\D/);}
467
els[i].ondragenter = function()
{return false;}
468
els[i].style.imeMode= "disabled";
469
break;
470
case "ascii":
471
els[i].style.imeMode= "disabled";
472
break;
473
case "ip4":
474
els[i].onkeypress = function()
{return /[\.]|\d/.test(String.fromCharCode(event.keyCode));}
475
els[i].onpaste = function()
{return !clipboardData.getData('text').match(/\D/);}
476
els[i].ondragenter = function()
{return false;}
477
els[i].style.imeMode= "disabled";
478
els[i].maxLength = 15;
479
break;
480
case "color":
481
els[i].onkeypress = function()
{return /[a-fA-Z]|\d/.test(String.fromCharCode(event.keyCode))||(this.value.indexOf('#')<0?String.fromCharCode(event.keyCode)=="#":false);}
482
els[i].onpaste = function()
{return !clipboardData.getData('text').match(/\D/);}
483
els[i].ondragenter = function()
{return false;}
484
els[i].maxLength = 7;
485
els[i].style.imeMode= "disabled";
486
break;
487
case "date":
488
els[i].onkeypress = function()
{return /[\/\-\.]|\d/.test(String.fromCharCode(event.keyCode));}
489
els[i].onpaste = function()
{return !clipboardData.getData('text').match(/\D/);}
490
els[i].ondragenter = function()
{return false;}
491
els[i].style.imeMode= "disabled";
492
break;
493
}
494
}
495
}
496
}
497
}
498
}
499
500
//初始化
501
var g_check = new CLASS_CHECK();
502
g_check.keyCheck();
503
504
505

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41



42

43

44

45

46

47

48

49

50



51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77



78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104



105

106

107

108

109

110

111



112

113

114

115

116

117

118



119

120

121



122

123

124

125



126

127



128

129



130

131

132



133

134

135

136

137

138

139



140

141

142

143

144

145

146



147

148

149

150

151

152

153



154

155

156

157

158



159

160

161



162

163

164

165

166

167

168

169

170



171

172

173



174

175

176

177

178

179

180

181



182

183

184

185

186

187



188

189

190

191

192

193

194

195

196

197

198



199

200

201

202



203

204

205

206

207

208

209

210


211

212

213

214



215

216



217

218

219

220



221

222

223

224

225


226

227

228

229



230

231

232



233

234

235

236



237

238

239

240

241

242


243

244

245

246



247

248

249



250

251

252

253

254



255

256

257

258



259

260

261

262



263

264



265

266

267

268

269

270

271

272

273



274

275

276

277


278

279

280

281



282

283

284



285

286

287

288



289

290



291

292

293

294

295

296

297



298

299

300

301

302

303


304

305

306

307



308

309

310

311



312

313

314

315

316

317

318

319

320

321

322

323

324

325

326



327

328

329

330

331



332

333



334

335

336

337

338

339

340

341



342

343

344



345

346

347



348

349

350

351

352

353

354

355


356

357

358

359



360

361

362

363



364

365

366

367

368

369

370




371

372

373

374

375

376

377

378



379

380



381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396



397






398

399

400



401




402

403

404

405



406

407



408





409

410

411



412

413

414

415

416



417

418

419

420



421

422

423

424

425

426



427

428



429

430

431



432



433



434

435

436

437

438



439



440



441

442

443

444



445



446



447

448

449

450

451



452



453



454

455

456

457

458



459



460



461

462

463

464

465



466



467



468

469

470

471

472

473

474



475



476



477

478

479

480

481



482



483



484

485

486

487

488



489



490



491

492

493

494

495

496

497

498

499

500

501

502

503

504

505
