---
tags: Example,
disqus: hackmd
---
# 正規表達式練習
## 程式碼
### HTML
```htmlmixed=
<html>
<head>
<title>week1 HTML Form 表單驗證</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="page-body">
<h2>正規表達式-表單驗證練習</h2>
<form id="myForm" class="myForm" onsubmit="return false">
<label for="account">帳號:</label>
<input type="text" id="account" class="account field" value="">
<span class="rule">規則: 4~15 碼英文大小寫及數字</span><br>
<label for="password">密碼:</label>
<input type="password" id="password" class="password field" value="">
<span class="rule">規則: 6-12 大小寫英文及數字(密碼中至少要包含一個英文大寫)</span><br>
<label for="confirmPassword">確認密碼:</label>
<input type="password" id="confirmPassword" class="confirmPassword field" value="">
<span class="rule">規則: 欄位必須與密碼相符</span><br>
<label for="nickname">暱稱:</label>
<input type="text" id="nickname" class="nickname field" value="">
<span class="rule">規則: 名稱中不可包含 {}[]"", 並且僅能輸入 2-10字元</span><br>
<label for="realname">真實姓名:</label>
<input type="text" id="realname" class="realname field" value="">
<span class="rule">規則: 不可輸入數字、空白及特殊符號 最多6字</span><br>
<label for="enName">英文姓名:</label>
<input type="text" id="enName" class="enName field" value="">
<span class="rule">規則: 可輸入英文大小寫、空白、單引號及底線</span><br>
<label for="birthday">生日:</label>
<input type="text" id="birthday" class="birthday field" value="">
<span class="rule">規則: dd/mm/yyyy</span><br>
<label for="country">國家:</label>
<input type="text" id="country" class="country field" value="">
<span class="rule">規則: 不能輸入特殊符號,但可以輸入空格</span><br>
<label for="identity">證件:</label>
<input type="text" id="identity" class="identity field" value="">
<span class="rule">規則: 可輸入英文大小寫數字也可以輸入底線</span><br>
<label for="cellphone">手機:</label>
<input type="tel" id="cellphone" class="cellphone field" value="">
<span class="rule">規則: 僅能數字但可以包含+開頭</span><br>
<label for="function1">function1:</label>
<span id="function1Notice"></span>
<input type="tel" id="function1" class="function1 field" value="">
<br><br>
<label for="function2">function2:</label>
<span id="function2Notice"></span>
<input type="tel" id="function2" class="function2 field" value="">
<span class="rule">規則: 僅能整數或包含小數點</span><br>
<br>
<input id="submitButton" type="submit" value="送出">
<input id="resetButton" type="reset" value="清除">
</form>
</div>
</body>
<script src="index.js"></script>
</html>
```
### CSS
```css=
.page-body {
white-space: nowrap;
text-align: center;
}
.myForm {
display: inline-block;
margin: 0 auto;
border-radius: 15px;
padding: 15px;
background: bisque;
width: 700px;
box-sizing: border-box;
vertical-align: middle;
}
.myForm label {
display: inline-block;
width: 70px;
}
input:focus{
outline: none;
}
input {
border: solid 1px #CCC;
}
.field.error {
border-color: red;
}
.rule {
display: block;
color: red;
font-size: 14px;
opacity: 0;
}
.rule.show {
opacity: 1;
}
```
### JS
```javascript=
/* 立即函示 + 閉包 */
(function() {
function handleOnload(){
var myForm = document.getElementById('myForm');
var inputField = document.getElementsByClassName('field');
var password = document.getElementById('password');
var confirmPassword = document.getElementById('confirmPassword');
var function1 = document.getElementById('function1');
var function2 = document.getElementById('function2');
var function1Notice = document.getElementById('function1Notice');
var function2Notice = document.getElementById('function2Notice');
var submitButton = document.getElementById('submitButton');
var resetButton = document.getElementById('resetButton');
var myObj = {
checkConfirmPassword: function() {
var passwordValue = password.value;
var confirmPasswordValue = confirmPassword.value;
return passwordValue === confirmPasswordValue;
},
checkHandler: function(name, pattern) {
var targetInput = document.getElementById(name);
var targetInputCheck = pattern.test(targetInput.value);
return targetInputCheck;
},
verifyList: function(id) {
var result = null;
switch (id) {
case 'account':
result = this.checkHandler('account', /^([a-zA-Z0-9]){4,15}$/g);
break;
case 'password':
result = this.checkHandler('password', /^(?=.*[A-Z])[a-zA-Z0-9]{6,12}$/g);
break;
case 'confirmPassword':
result = this.checkConfirmPassword();
break;
case 'nickname':
result = this.checkHandler('nickname', /^[^{}\]\["]{2,10}$/g);
break;
case 'realname':
result = this.checkHandler('realname', /^[a-zA-Z\u4e00-\u9fa5]{1,6}$/g);
break;
case 'enName':
result = this.checkHandler('enName', /^[a-zA-Z _']+$/g);
break;
case 'birthday':
result = this.checkHandler('birthday', /^([0][1-9]|[1-2][0-9]|[3][0-1])[\/]([0-1][1-9]|[01][0-2])[\/](19|20)([\d]{2})$/g);
break;
case 'country':
result = this.checkHandler('country', /^([^\W]|[ \u4e00-\u9fa5])+$/g);
break;
case 'identity':
result = this.checkHandler('identity', /^[\w]+$/g);
break;
case 'cellphone':
result = this.checkHandler('cellphone', /^([+]?)([\d]+)$/g);
break;
case 'function2':
result = this.checkHandler('function2', /^([\d]+)(([\.][\d]+)?)$/g);
break;
default:
result = true;
}
return result;
},
handleVerify: function(id, type) {
var result = null;
if (type === 'submit') {
result = document.getElementById(id).value && this.verifyList(id);
if (!result) {
document.getElementById(id).classList.add('error');
document.getElementById(id).nextElementSibling.classList.add('show');
}
if (id === 'function1' && result) {
this.handleRemoveSpace();
}
if (id === 'function2' && result) {
this.handleDecimalPoint();
}
return result;
}
if (type === 'keyup' || type === 'blur') {
result = document.getElementById(id).value && this.verifyList(id);
if (id === 'password' && confirmPassword.value) {
result = result && this.checkConfirmPassword();
if (result) {
confirmPassword.classList.remove('error');
confirmPassword.nextElementSibling.classList.remove('show');
} else {
confirmPassword.classList.add('error');
confirmPassword.nextElementSibling.classList.add('show');
}
} else {
if (result) {
document.getElementById(id).classList.remove('error');
document.getElementById(id).nextElementSibling.classList.remove('show');
} else {
document.getElementById(id).classList.add('error');
document.getElementById(id).nextElementSibling.classList.add('show');
}
}
}
},
handleSubmit: function() {
submitButton.addEventListener('click', function() {
let succeedVerify = 0;
for (let index = 0; index < inputField.length; index++) {
var id = inputField[index].getAttribute('id');
var state = myObj.handleVerify(id, 'submit');
if (state) {
succeedVerify = succeedVerify + 1;
}
}
if (succeedVerify === inputField.length) {
alert('表單送出成功');
myForm.submit();
} else {
document.getElementsByClassName('error')[0].focus();
}
});
},
handleKeyup: function() {
for (let index = 0; index < inputField.length; index++) {
inputField[index].addEventListener('keyup', function() {
myObj.handleVerify(inputField[index].getAttribute('id'), 'keyup');
}, true);
}
},
handleUnfocus: function() {
for (let index = 0; index < inputField.length; index++) {
inputField[index].addEventListener('blur', function() {
myObj.handleVerify(inputField[index].getAttribute('id'), 'blur');
}, true);
}
},
handleReset: function() {
resetButton.addEventListener('click', function() {
for (let index = 0; index < inputField.length; index++) {
inputField[index].classList.remove('error');
inputField[index].nextElementSibling.classList.remove('show');
}
function1Notice.innerHTML = '';
function2Notice.innerHTML = '';
});
},
handleRemoveSpace: function() {
function1Notice.innerHTML = function1.value.split(/([\S][\w\W\s]+[\S])/g)[1];
},
handleDecimalPoint: function() {
function2Notice.innerHTML = function2.value.replace(/([0-9]+)[\.]?([\d]+)?/, '『整數:$1, 小數點:0.$2』');
},
handleExecute: function() {
this.handleSubmit();
this.handleKeyup();
this.handleUnfocus();
this.handleReset();
}
}
return myObj;
};
var executeOnload = handleOnload();
executeOnload.handleExecute();
})();
/* 立即函示 + 閉包 */
```