게시판 본문 ASP, ASP.NET, IIS & Script - Read Only
HTML 입력필드에 값검증 기능을 내장시키자! HTC를 이용한 validator |
---|
작성자: 박노철
작성일시: 2005-07-29 10:19,
조회수: 6,344
|
프로젝트를 하다보면 이런저런 HTML 입력필드들의 값유효성을 검증해야 할 일들
이 많은데요, 그럴 때를 위해서 만들어봤습니다. 다음과 같은 상황을 가정해봅시다. 어떤 input box 에 대해서 YYYYMMDD 형식의 값을 필수적으로 입력해야 하는데, 이런 상황이 여러번 나타납니다. 보통의 경우라면 값검증함수를 .js 파일로 빼놓고 여기다가 input tag object 자체를 파라미터로 던져서 값을 검증하죠. 하지만 좀 더 OOP 적으로 사고를 해본다면, input tag 자체에 값검증 기능이 들어가도록 확장할 수 있으면 더 좋지 않을까요?? 즉, 코드가 다음과 같이 만들어졌으면 좋겠다는 이야기입니다. <input type="text" id="txtMandatoryYYYYMMDDTest" style="behavior:url(validator.htc)" MANDATORY="Y" YYYYMMDD="Y">아시다시피 공식적인 DHTML 표준에는 input 태그에 MANDATORY 니, YYYYMMDD 니 하는 것들이 없습니다. 하지만 HTC 를 사용하면 input 태그 자체를 확장할 수 있습니다. 의미를 설명해드리자면, MANDATORY="Y" 는 이 필드의 값은 필수적으로 입력해야하고 YYYYMMDD="Y"는 이 필드의 값형식은 YYYYMMDD 형식이어야만 한다는 뜻입니다. 이렇게 HTML 태그 자체를 확장해놓고 Javascript 에서 txtMandatoryYYYYMMDD.validate();만 부르면 HTML 에 선언해놓은데로 값검증이 이루어지는 겁니다. 또다른 시나리오로 이런것도 생각해볼 수 있겠죠. SELECT tag 에 대해서 form submit 하기전에 이 SELECT 는 반드시 선택을 해야합니다. 그것을 검증해야되는데, 위의 접근법을 적용한다면 다음과 같은 방식을 생각해볼 수 있습니다. "SELECT 태그자체에 '반드시 이 필드는 선택해야한다' 는 속성을 정의해놓고 validate() 함수를 부르면 그 속성에 따라 값을 검증한다." DHTML 코드로 나타내면 다음과 같겠지요. <select id="selMustChooseTest" style="behavior:url(validator.htc)" MUSTCHOOSE="Y">그런담에 selMustChooseTest.validate();를 부르면 되는겁니다. 위의 두가지를 종합하면 다음과 같은 시나리오도 가능합니다. frmTest라는 폼에 위에서 이야기한 두개의 form element와 validator.htc 를 attach 하지 않은 일반적인 폼 요소가 있다고 합시다. 코드는 대충 다음과 같습니다. <form id="frmTest"> <input type="text" id="txtMandatoryYYYYMMDDTest" style="behavior:url(validator.htc)" MANDATORY="Y" YYYYMMDD="Y"> <select id="selMustChooseTest" style="behavior:url(validator.htc)" MUSTCHOOSE="Y"> <input type="text" id="txtNonValidatorTest"> </form>이제 이 폼을 검증하고 싶습니다. 저는 이렇게 할 것 같습니다. for(var i = 0; i < frmTest.element.length; i++) { try {frmTest.element(i).validate(); } catch(e) {} }try ... catch 를 쓴 이유는 txtNonValidatorTest 때문입니다. 여기에는 validator.htc 가 behavior 로 attach 되어 있지 않습니다. 그래서 validate() 함수를 호출하면 스크립트 에 러가 납니다. 그걸 무시하기 위해서 try ... catch 를 쓴 것이죠. 사실 모든 폼에 validator.htc 를 적용할 수는 없을 것이고, 몇개의 폼요소들이 가지는 값들을 한꺼번 에 검증해야 할 필요도 있습니다. 그럴때는 이 validator.htc 를 사용할 수는 없습니다. 그때는 따로 비즈니스적인 의미가 들어가는 검증로직을 만들어야 하겠죠. 하지만 단 순반복되는 필수입력여부체크, 선택여부체크, YYYYMMDD 체크같은 것들, 숫자만 입 력해야하는 것들의 검증로직들은 validator.htc 에 모두 담아놓고 위의 for 루프 한방 에 기본적인 검증은 모두 끝낼 수 있겠지요. 아래는 validator.htc 의 소스입니다~ 매우 허접하니까 저작권따윈 주장할 생각이 없고요 ^^ 다들 유용하게 고쳐서 쓰세요~ 고친거는 다같이 공유하면 더 좋구요~~ <PUBLIC:COMPONENT> <PUBLIC:PROPERTY ID="isMandatory" NAME="MANDATORY" GET="getMandatory" PUT="setMandatory"></PUBLIC:PROPERTY> <PUBLIC:PROPERTY ID="mandatoryErrMsg" NAME="MANDATORY_MSG" GET="getMandatoryErrMsg" PUT="setMandatoryErrMsg"></PUBLIC:PROPERTY> <PUBLIC:PROPERTY ID="isNumOnly" NAME="NUMONLY" GET="getNumOnly" PUT="setNumOnly"></PUBLIC:PROPERTY> <PUBLIC:PROPERTY ID="numonlyErrMsg" NAME="NUMONLY_MSG" GET="getNumOnlyErrMsg" PUT="setNumOnlyErrMsg"></PUBLIC:PROPERTY> <PUBLIC:PROPERTY ID="isChosen" NAME="MUSTCHOOSE" GET="getChosen" PUT="setChosen"></PUBLIC:PROPERTY> <PUBLIC:PROPERTY ID="chosenErrMsg" NAME="CHOSEN_MSG" GET="getChosenErrMsg" PUT="setChosenErrMsg"></PUBLIC:PROPERTY> <PUBLIC:PROPERTY ID="isYYYYMMDD" NAME="YYYYMMDD" GET="getYYYYMMDD" PUT="setYYYYMMDD"></PUBLIC:PROPERTY> <PUBLIC:METHOD NAME="validate"></PUBLIC:METHOD> <PUBLIC:ATTACH EVENT="onkeyup" ONEVENT="keyup()" /> <PUBLIC:ATTACH EVENT="ondocumentready" ONEVENT="documentready()" /> <script language="jscript"> ///////////////////////////////////////////////////////////////////////////////// // HTML 입력필드 종합 validator // // 사용법: // <input type="text" style="behavior:url(validator.htc)" MANDATORY="Y" // YYYYMMDD="Y"> // <select style="behavior:url(validator.htc)" MUSTCHOOSE="Y"> // // 2005/7/18 박노철 ///////////////////////////////////////////////////////////////////////////////// var isMandatory = null; var mandatoryErrMsg = "필수적으로 값을 입력해야 합니다"; var isNumOnly = null; var numonlyErrMsg = "숫자만 입력해야합니다"; var isChosen = null; var chosenErrMsg = "필수적으로 하나의 항목을 선택해야 합니다"; var isYYYYMMDD = null; var prevVal = ""; // numonly 가 y 일 때 가장 최근에 입력한 값을 저장함. /////////////////// mandatory validation ////////////////////////////////// function getMandatory() { return isMandatory; } function setMandatory(val) { if(element.type.toLowerCase() != "text") throw new Error(0,"<INPUT type=text> 에만 필수입력을 설정할 수 있습니다"); this.isMandatory = (val.toLowerCase() == "true" || val.toLowerCase() == "yes" || val.toLowerCase() == "y") ? true :false; } function getMandatoryErrMsg() { return this.mandatoryErrMsg; } function setMandatoryErrMsg(val) { this.mandatoryErrMsg = (val) ? val : "필수적으로 값을 입력해야 합니다"; } function validateMandatory() { if(!this.isMandatory) return true; if(element.value == "" || element.value == null) { alert(this.mandatoryErrMsg); element.focus(); element.select(); return false; } return true; } /////////////////// numonly validation ///////////////////////////////// function keyup() { if(this.isNumOnly) { // 숫자만 입력받는 조건 체크 var key = window.event.keyCode; // END HOME LEFT RIGHT BACKSPACE if(key == 35 || key == 36 || key == 37 || key == 39 || key == 8) { this.prevVal = element.value; return; } if(key < 48 || key > 57) element.value = this.prevVal; else { if(window.event.shiftKey) element.value = this.prevVal; else this.prevVal = element.value; } } } function documentready() { // 이 element 에 포커스가 왔을 때 한글입력기를 아예 disable 시킨다. // 한글입력을 안받기 위해서 if(this.isNumOnly) element.style.imeMode = "disabled"; } function getNumOnly() { return this.isNumOnly; } function setNumOnly(val) { if(element.type.toLowerCase() != "text") throw new Error(0,"<INPUT type=text> 에만 숫자만 입력가능을 설정할 수 있습니다"); this.isNumOnly = (val.toLowerCase() == "true" || val.toLowerCase() == "yes" || val.toLowerCase() == "y") ? true :false; } function getNumOnlyErrMsg() { return this.numonlyErrMsg; } function setNumOnlyErrMsg(val) { this.numonlyErrMsg = (val) ? val : "숫자만 입력해야합니다"; } function validateNumOnly() { if(!this.isNumOnly) return true; if(isNaN(element.value)) { // 숫자가 아니면 alert(this.numonlyErrMSg); element.focus(); element.select(); return false; } return true; } ////////////////// select box chosen validation ////////////////////////// function getChosen() { return this.isChosen; } function setChosen(val) { if(element.tagName.toLowerCase() != "select") throw new Error(0,"<SELECT> 요소에만 MUSTCHOOSE 를 설정할 수 있습니다"); this.isChosen = (val.toLowerCase() == "true" || val.toLowerCase() == "yes" || val.toLowerCase() == "y") ? true :false; } function getChosenErrMsg() { return this.chosenErrMsg; } function setChosenErrMsg(val) { this.chosenErrMsg = (val) ? val : "필수적으로 하나의 항목을 선택해야 합니다"; } // select 박스에서 하나를 반드시 선택해야 함 function validateChosen() { if(!this.isChosen) return true; if(element.selectedIndex <= 0) { alert(this.chosenErrMsg); element.select(); element.focus(); return false; } return true; } ////////////////// YYYYMMDD 포맷 validation //////////////////////// function getYYYYMMDD() { return isYYYYMMDD; } function setYYYYMMDD(val) { if(element.tagName.toLowerCase() != "input") throw new Error(0,"<INPUT> 요소에만 YYYYMMDD 를 설정할 수 있습니다"); if(element.type.toLowerCase() != "text") throw new Error(0,"<INPUT type=text> 에만 YYYYMMDD 를 설정할 수 있습니다"); this.isYYYYMMDD = (val.toLowerCase() == "true" || val.toLowerCase() == "yes" || val.toLowerCase() == "y") ? true :false; // yyyymmdd 입력가능하다는 이야기는 numonly 라는 것 // yyyymmdd 가 false 이더라도 numonly 일 수 있으므로 // false 처리는 안해줌 if(this.isYYYYMMDD) this.setNumOnly("Y"); } function validateYYYYMMDD() { if(!this.isYYYYMMDD) return true; var val = element.value; var y = parseInt(val.substring(0,4),10); var m = parseInt(val.substring(4,6),10); var d = parseInt(val.substring(6,8), 10); if(val.length != 8) { alert("YYYYMMDD 포맷이 아닙니다. 다시 입력해주십시오."); element.focus(); element.select(); return false; } if(y < 1900) { alert("연도가 잘못 입력되었습니다. 다시 입력해주십시오."); element.focus(); element.select(); return false; } if(m > 12 || m < 1) { alert("잘못된 달입니다. 다시 입력해주십시오."); element.focus(); element.select(); return false; } if(d > 31 || d < 1) { alert("잘못된 날짜입니다. 다시 입력해주십시오."); element.focus(); element.select(); return false; } return true; } /////////////////// 종합 validate 함수 //////////////////////////// function validate() { if(!validateMandatory()) return false; if(!validateChosen()) return false; if(!validateNumOnly()) return false; if(!validateYYYYMMDD()) return false; return true; } </script> </PUBLIC:COMPONENT> |
IP 주소: 165.141.120.133
|
전체 1 건의 댓글이 존재합니다.
송원석 |
대단히 감사합니다. 이런식으로 많은 분들이 자작 HTCs 를 공개해주시면 나중엔 어지간한 수준의 라이브러리도 될 수 있을것 같네요. 유용하게 참고하도록 하겠습니다. 감사합니다. ^_^
|
2005-07-29 10:49 |
전체 2,095 건의 게시물,
84 페이지로 구성된
ASP, ASP.NET, IIS & Script 게시판의
36 페이지입니다.
게시물 | ||||
---|---|---|---|---|
1,257 |
영이 |
2005-08-04 | 1,089 | |
1,256 | 2005-08-04 | 3,091 | ||
1,255 |
영이 |
2005-08-04 | 1,086 | |
1,254 | 2005-08-04 | 3,115 | ||
1,253 |
영이 |
2005-08-04 | 1,033 | |
1,252 | 2005-08-04 | 3,122 | ||
1,251 |
영이 |
2005-08-08 | 1,148 | |
1,250 | 2005-08-09 | 3,054 | ||
1,249 |
궁금이 |
2005-08-03 | 1,027 | |
1,248 | 2005-08-03 | 2,914 | ||
2005-07-29 | 6,344 | |||
1,246 | 2005-07-29 | 3,367 | ||
1,245 | 2005-07-28 | 3,212 | ||
1,244 | 2005-07-28 | 2,944 | ||
1,243 | 2005-07-27 | 3,057 | ||
1,242 | 2005-07-27 | 3,308 | ||
1,241 | 2005-07-25 | 3,427 | ||
1,240 | 2005-07-26 | 3,390 | ||
1,239 |
쿠키에 대한 질문입니다. [2] |
omar |
2005-07-21 | 1,015 |
1,238 |
iE 아날라이즈에서요... [1] |
2005-07-21 | 3,180 | |
1,237 |
강문성 |
2005-07-20 | 1,194 | |
1,236 | 2005-07-21 | 3,889 | ||
1,235 | 2005-07-27 | 3,202 | ||
1,234 | 2005-07-27 | 3,260 | ||
1,233 | 2005-07-20 | 3,289 |