NARADESIGN

웹표준, 웹접근성, 유니버설디자인, HTML, CSS, UI, UX, UD


jQuery 입문: form 데이터 유효성 검사.

본문 건너 뛰기

사용자가 form 안에서 올바른 값을 입력했는지 여부(데이터 유효성)는 기본적으로 서버측 스크립트로 확인해야 합니다. 사용자가 입력한 form을 서버로 전송하면 서버측 스크립트는 사용자 값을 받아서 맞는지 틀린지 확인하고 틀린 경우 다시 입력 페이지를 내놓습니다. 이 과정의 문제는 서버측 스크립트로부터 데이터 유효성 검사를 받으려면 네트웍 환경이 좋지 못한 환경에서 너무 오랜 시간을 기다려야한다는 점입니다. 사실 네트웍 환경이 좋아도 같은 페이지를 자꾸 갱신하는 것은 짜증스러운 일이죠. form이 포함된 페이지를 아무런 실수 없이 한번에 유효하게 작성해서 전송 OK! 하는 사람들이 얼마나 많을까요?

그래서 웹 개발자는 언제부터인가 이런 불편을 개선할 목적으로 데이터 유효성 확인과 같은 핵심 기능을 자바스크립트에 의존하기 시작했습니다. 데이터 유효성 검사를 자바스크립트로 처리하면 서버에 한번 다녀오지 않아도 데이터 유효성 확인이 가능하기 때문에 잘못된 데이터를 페이지 갱신 없이 즉석에서 정정할 수 있습니다. 자바스크립트에 의존한 것은 창의적으로 UX를 개선한 일로써 전혀 문제가 되지 않는데요. 문제는 자바스크립트에만 의존하는 것입니다. 개발자가 작성한 자바스크립트 가운데 전부 또는 일부를 해석하지 못하는 브라우저는 현재도 존재하고 앞으로도 존재할지 모릅니다. 대중적인 브라우저만 지원하면 그만이라는 생각은 학생증이 있는 청소년에게만 책을 빌려주는 도서관 운영 방침과 같은 겁니다.

자바스크립트를 지원하는 환경에서는 자바스크립트에 의존하여 사용성(만족, 효율)을 높이고, 자바스크립트를 지원하지 않는 환경에서는 HTML, CSS, 서버측 스크립트에 의존하도록 양쪽 방향을 모두 고려하여 설계함으로써 상호 운용성(JS 지원 여무에 무관한 운용성)을 확보할 수 있습니다. 이런 설계 기법을 겸손한 자바스크립트(Unobtrusive Javasript)라고 합니다. 겸손한 자바스크립트 관련글 하나, 겸손한 자바스크립트 관련글 둘. 이런 개념을 탑재하고 나서 자바스크립트 실력을 향상시켜도 늦지 않습니다.

오늘의 주제는 jQuery를 이용한 데이터 유효성 검사 입니다. 서버측 유효성 검사 방법은 다루지 않겠지만 서버측 스크립트에 의한 데이터 유효성 검사 또한 진행할 것이라는 전제 아래 자바스크립트로 데이터 유효성 검사 기능을 구현해 봤습니다.

데이터 유효성 검사 예제 미리보기

(*) 항목은 반드시 입력해 주세요.

  • 영문, 숫자, 언더스코어(_), 하이픈(-)이 포함 3~16 문자.
  • 영문, 숫자, 언더스코어(_), 하이픈(-) 포함 6~18 문자.
  • 하이픈(-)은 입력하지 마세요.

데이터 유효성 검사 예제 코드

<form action="" class="form">
	<p>(*) 항목은 반드시 입력해 주세요.</p>
	<ul>
		<li>
			<label for="uid">ID(*):</label>
			<input id="uid" />
			영문, 숫자, 언더스코어(_), 하이픈(-)이 포함된 3~16 문자.
		</li>
		<li>
			<label for="upw">PW(*):</label>
			<input id="upw" type="password" />
			영문, 숫자, 언더스코어(_), 하이픈(-)이 포함된 6~18 문자.
		</li>
		<li>
			<label for="mail">Email(*):</label>
			<input id="mail" value="@" />
		</li>
		<li>
			<label for="url">Web(*):</label>
			<input id="url" value="http://" />
		</li>
		<li>
			<label for="tel">Tel(*):</label>
			<input id="tel" />
			하이픈(-)은 입력하지 마세요.
		</li>
	</ul>
	<input type="submit" value="전송" />
</form>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
// <![CDATA[
jQuery( function($) { // HTML 문서를 모두 읽으면 포함한 코드를 실행

	// 정규식을 변수에 할당
	// 정규식을 직접 작성할 줄 알면 참 좋겠지만
	// 변수 우측에 할당된 정규식은 검색하면 쉽게 찾을 수 있다 
	// 이 변수들의 활약상을 기대한다
	// 변수 이름을 're_'로 정한것은 'Reguar Expression'의 머릿글자
	var re_id = /^[a-z0-9_-]{3,16}$/; // 아이디 검사식
	var re_pw = /^[a-z0-9_-]{6,18}$/; // 비밀번호 검사식
	var re_mail = /^([\w\.-]+)@([a-z\d\.-]+)\.([a-z\.]{2,6})$/; // 이메일 검사식
	var re_url = /^(https?:\/\/)?([a-z\d\.-]+)\.([a-z\.]{2,6})([\/\w\.-]*)*\/?$/; // URL 검사식
	var re_tel = /^[0-9]{8,11}$/; // 전화번호 검사식
	
	// 선택할 요소를 변수에 할당
	// 변수에 할당하지 않으면 매번 HTML 요소를 선택해야 하기 때문에 귀찮고 성능에도 좋지 않다
	// 쉼표를 이용해서 여러 변수를 한 번에 선언할 수 있다
	// 보기 좋으라고 쉼표 단위로 줄을 바꿨다 
	var 
		form = $('.form'), 
		uid = $('#uid'), 
		upw = $('#upw'), 
		mail = $('#mail'), 
		url = $('#url'), 
		tel = $('#tel');
		
	// 선택한 form에 서밋 이벤트가 발생하면 실행한다
	// if (사용자 입력 값이 정규식 검사에 의해 참이 아니면) {포함한 코드를 실행}
	// if 조건절 안의 '정규식.test(검사할값)' 형식은 true 또는 false를 반환한다
	// if 조건절 안의 검사 결과가 '!= true' 참이 아니면 {...} 실행
	// 사용자 입력 값이 참이 아니면 alert을 띄운다
	// 사용자 입력 값이 참이 아니면 오류가 발생한 input으로 포커스를 보낸다
	// 사용자 입력 값이 참이 아니면 form 서밋을 중단한다
	form.submit( function() {
		if (re_id.test(uid.val()) != true) { // 아이디 검사
			alert('[ID 입력 오류] 유효한 ID를 입력해 주세요.');
			uid.focus();
			return false;
		} else if(re_pw.test(upw.val()) != true) { // 비밀번호 검사
			alert('[PW 입력 오류] 유효한 PW를 입력해 주세요.');
			upw.focus();
			return false;
		} else if(re_mail.test(mail.val()) != true) { // 이메일 검사
			alert('[Email 입력 오류] 유효한 이메일 주소를 입력해 주세요.');
			mail.focus();
			return false;
		} else if(re_url.test(url.val()) != true) { // URL 검사
			alert('[Web 입력 오류] 유효한 웹 사이트 주소를 입력해 주세요.');
			url.focus();
			return false;
		} else if(re_tel.test(tel.val()) != true) { // 전화번호 검사
			alert('[Tel 입력 오류] 유효한 전화번호를 입력해 주세요.');
			tel.focus();
			return false;
		}
	});
	
	// #uid, #upw 인풋에 입력된 값의 길이가 적당한지 알려주려고 한다
	// #uid, #upw 다음 순서에 경고 텍스트 출력을 위한 빈 strong 요소를 추가한다
	// 무턱대고 자바스크립트를 이용해서 HTML 삽입하는 것은 좋지 않은 버릇
	// 그러나 이 경우는 strong 요소가 없어도 누구나 form 핵심 기능을 이용할 수 있으니까 문제 없다
	$('#uid, #upw').after('<strong></strong>');
	
	// #uid 인풋에서 onkeyup 이벤트가 발생하면
	uid.keyup( function() {
		var s = $(this).next('strong'); // strong 요소를 변수에 할당
		if (uid.val().length == 0) { // 입력 값이 없을 때
			s.text(''); // strong 요소에 포함된 문자 지움
		} else if (uid.val().length < 3) { // 입력 값이 3보다 작을 때
			s.text('너무 짧아요.'); // strong 요소에 문자 출력
		} else if (uid.val().length > 16) { // 입력 값이 16보다 클 때
			s.text('너무 길어요.'); // strong 요소에 문자 출력
		} else if ( re_id.test(uid.val()) != true ) { // 유효하지 않은 문자 입력 시
			s.text('유효한 문자를 입력해 주세요.'); // strong 요소에 문자 출력
		} else { // 입력 값이 3 이상 16 이하일 때
			s.text('적당해요.'); // strong 요소에 문자 출력
		}
	});
	
	// #upw 인풋에서 onkeyup 이벤트가 발생하면
	upw.keyup( function() {
		var s = $(this).next('strong'); // strong 요소를 변수에 할당
		if (upw.val().length == 0) { // 입력 값이 없을 때
			s.text(''); // strong 요소에 포함된 문자 지움
		} else if (upw.val().length < 6) { // 입력 값이 6보다 작을 때
			s.text('너무 짧아요.'); // strong 요소에 문자 출력
		} else if (upw.val().length > 18) { // 입력 값이 18보다 클 때
			s.text('너무 길어요.'); // strong 요소에 문자 출력
		} else { // 입력 값이 6 이상 18 이하일 때
			s.text('적당해요.'); // strong 요소에 문자 출력
		}
	});
	
	// #tel 인풋에 onkeydown 이벤트가 발생하면
	// 하이픈(-) 키가 눌렸는지 확인
	// 하이픈(-) 키가 눌렸다면 입력 중단
	tel.keydown( function() {
		if(event.keyCode==109 || event.keyCode==189) {
			return false;
		}
	});
});
// ]]>
</script>

jQuery 코드 해설

  • 변수 할당은 ‘var 변수이름 = 할당 값’  형식으로 작성한다. re_* 라는 변수에 다양한 정규식을 할당했다. 정규식 표현은 사용자 입력 값이 유효한지 검사해 줄 것이다.
  • 정규 표현식을 어떤 값과 비교하면 true 또는 false 값을 얻을 수 있다. true라면 form을 서밋하고 false라면 form 서밋을 중단한다. 정규 표현식으로 데이터 유효성을 확인하려면 ‘정규식.test(어떤값)’ 형식으로 작성한다.
  • .val() 메소드는 선택한 input 또는 select 요소의 value 값을 구한다. uid.val()은 $(‘#uid’).val()과 같다. 이렇게 val() 괄호 안쪽이 비어있으면 값을 구해온다. 만약 val() 괄호 안쪽에 명시적으로 어떤 값이 있으면 값을 구해오는 것이 아니라 값을 넣는다. 여기서 val() 값은 사용자가 #uid 인풋에 입력한 값이다.
  • if(좌변의 정규식과 != 우변의 사용자 입력 값이 같지 않으면) 사용자가 입력한 값은 오류이다. 이 조건문은 사용자 입력 값이 올바르지 않은 경우 {실행문}을 실행한다. 조건문 안에서는 ==(같음), !=(같지않음), !(아님), >(보다큰), <(보다작은), >=(같거나 큰), <=(같거나 작은) 이런 등호가 자주 쓰인다. 등호는 어떤 값을 true, false와 같은 참 거짓 또는 숫자와 자주 비교한다.
  • .after() 메소드는 선택한 요소의 다음(형제 노드) 순서에 문자열이나 HTML 요소를 넣는다. 이 예제는 $(‘#uid, #upw’).after(‘<strong></strong>’) 두 요소를 선택하고 두 요소의 다음에 strong 요소를 넣었다. 반대 개념의 메소드 .before()는 선택한 요소의 이전 형제노드에 문자열을 넣는다.
  • .length 메소드는 선택한 HTML 요소의 개수 또는 val() 값의 문자 개수를 구해온다. 이 경우는 선택한 HTML 요소의 개수를 구한 것이 아니라 val() 값의 문자 개수를 구했다.
  • .next() 메소드는 선택한 요소의 바로 다음에 등장하는 형제를 선택한다. $(this).next(‘strong’) 예제는 선택된 본인의 다음에 등장하는 strong 요소를 선택한다. 반대 개념의 메소드 .prev()는 이전 형제 요소를 선택한다.
  • .text() 메소드는 .val() 메소드와 사용법이 유사하다. HTML 요소 내부에 포함된 문자열을 구하거나 셋팅한다. 값이 비어있으면 값을 구해오지만 값이 설정되어 있으면 값을 셋팅한다. 이 코드는 값을 셋팅하는 예제만 포함하고 있다.
  • event.keyCode는 사용자가 누른 키의 값을 구한다. 키 값은 숫자를 반환하는데. 109, 189는 하이픈(-)의 키 값이다. 즉 하이픈(-) 키가 눌리면 keydown 동작을 취소함으로써 하이픈(-) 입력을 제한한다.
분류: 자바스크립트 | 2011년 7월 20일, 10:32 | 정찬명 | 댓글: 32개 |
트랙백URI - http://naradesign.net/wp/2011/07/20/1663/trackback/

32개의 댓글이 있습니다.

  1. 이군 댓글:

    이번에 작업진행 중인 플젝이 있는데요~ㅋㅋ 조금 활용을 해도 괜찮아요? 기능이 추가로 더 필요한 것이 있어서 응용해서 가져다 쓸께요~!!

  2. 정찬명 댓글:

    @이군
    당연히 괜찮죠. 사용하면서 개선점이 있으면 피드백 주세요. ㅎㅎ

  3. 이군 댓글:

    옙~ 깔끔해서 맘에들어요. valid 플러그인에 의지할 뻔 했거든요.

  4. Espressivo 댓글:

    예제에 앞서 겸손한 자바스크립트에 대해 언급하신 부분에
    “역시” 하며 감탄했습니다. 유익한 포스팅 고맙습니다 :)

  5. eerieN 댓글:

    상세한 설명이 좋네요. 잘 읽었습니다. :)

  6. 문영신 댓글:

    form 데이터 유효성 검사 관련 javascript 는 개발자 몫이라 생각하여 소홀히 했었는데.. 이렇게 한페이지로 정리해주시니 쉽게 이해가 되는군요^^.
    하지만, “영문, 숫자, 언더스코어(_), 하이픈(-)이 포함 3~16 문자” 등 입력 힌트가 서식 요소 이전에 있었으면 더 접근성 좋은 코드가 되는데 간과하신거 같습니다.

  7. 태희 댓글:

    저도 유효성검사기 만들고있는데 머리가둔해서 ㅎㅎ
    많은 힌트를 얻어갑니다 감사합니다.

  8. JUL 댓글:

    정규식 머리앞화효~~~~ ㅠㅠ

  9. 정의장 댓글:

    마땅히 남길곳이 없어 여기다 글 남깁니다. 익스프레스 엔진 사이트에 가입을 하고 싶은데요 회원가입 누르고 정보입력해도 자꾸 가입이 안됩니다. 권한이 없습니다 라는 자바알림창만 뜨고 가입이 더이상 진행이 안되네요 이거 오류인거 같은데 수정좀 빨리 부탁 드려요 ^^::

  10. 정찬명 댓글:

    @정의장
    contact앳xpressengine.com 앞으로 이메일을 보내주세요.

  11. 퍼브르 댓글:

    찬명님 요새 블로그에 글이 뜸하신거 같아요 ㅠ,ㅠ

  12. 정찬명 댓글:

    @퍼브르
    저도 그게 참 안타깝습니다. ㅡㅡ;

  13. 비스타 댓글:

    잘 배워갑니다.
    감사합니다!

  14. […] NARADESIGN:BLOG var allblet_id = 137025, allblet_type = 4; var allblet_id = 137025, allblet_type = 4; Posted on January 1, 2012 by koreablogarchive. This entry was posted in Archive and tagged form, jQuery, 검사, 데이터, 유효성, 입문. Bookmark the permalink. « 올해 마지막주 .. 마무리가 중요한 시점 교과부 장관이 보내는 신년 인사입니다! » […]

  15. neverStop 댓글:

    저의 저렴했던 자바스크립트에 대한 이해도가 다소나마 높아졌습니다 ㅎㅎ감사해요

  16. 리키 댓글:

    기존에 ajax로 구현된 중복 모듈이 있는데,
    이 유효성 검사 모듈에 같이 적용하려고 하는데 비동기(ajax) 모듈들은 어떤식으로 처리할 수 있을까요?

    그냥 내부에다가 ajax 펑션두고 success 콜백함수에 submit 과정을 적어두긴 소스가 깔끔(?)하지 못 한 것 같아서요…

  17. 정찬명 댓글:

    @리키
    저라면 Ajax로 처리하던 유효성 검사 기능을 그냥 서버측 스크립트로 처리하는 방법을 선택했을것 같아요. 그렇게 하면 스크립트가 지원되는 환경에서는 스크립트로만 유효성 검사를 처리하고 스크립트 미지원 환경에서는 서버측 스크립트로 검사를 하게 되서 상호 운용성을 확보하는 정석적인 방법인데요. 물론 시간이 허락 한다면요.

  18. 익명 댓글:

    감사합니다. 좋은 도움 되었습니다.

  19. 익명 댓글:

    잘이해하고 도움이 많이되었습니다.
    다른부분은 이해가 잘 되는데…
    form.submit (function() 부분에서
    re_id.test(uid.val()) ——> .test()
    이부분이 이해되질않습니다. (밑부분도요)
    test라는 것에대한 이해가 어렵습니다..
    설명좀 부탁드릴게요.

  20. 정찬명 댓글:

    @익명
    test() 메서드는 괄호() 안에 포함된 문자열과 앞 부분에 있는 정규식 변수의 값을 비교해서 true 또는 false를 반환하는 역할을 합니다.

    작성된정규식변수.test(앞에있는정규식과비교할문자열)

    예를 들어

    정규식에서숫자만허용.test(‘123’)
    이라면 true가 되는 것이고

    정규식에서알파벳만허용.test(‘123’)
    이면 false가 되는 것이죠.

    http://www.w3schools.com/jsref/jsref_regexp_test.asp
    링크 설명도 참고해 보세요.

  21. 익명 댓글:

    수업에 필요한 자료를 찾고 있었는데 필요한 자료를 활요하게 되었습니다. 고맙습니다.

  22. 최지혜 댓글:

    제가 이 소스를 사용하고 싶은데 저는 로그인화면에서 아이디와 비밀번호 입력후 로그인(sumit)버튼을 누르면 로그인되어 메인페이지로 넘기고 싶은데, 아이디와 비밀번호를 입력을 하지 않으면 아이디와 비밀번호를 입력하라는 메세지와 그 페이지에 머물고 싶은데 알람이 뜨고 링크걸린 페이지로 넘어갑니다. 공백이 걸린 상태로요. 이 부분에 이 소스가 적용이 될까요? 지금 하고는 있는데 잘 안되서요

  23. 정찬명 댓글:

    @최지혜
    본문에 작성된 코드를 이용하면 유효하지 않은 데이터 입력 시 form submit을 중단하기 때문에 페이지 이동하지 않고 현재 페이지에 머물게 됩니다. 본문의 코드를 응용해서 적용해 보세요.

  24. 익명 댓글:

    설명이 너무 훌륭하네요..감사합니다..완전 짱~

  25. 문현배 댓글:

    많이 배웠습니다
    Jquery Datatable을 이용해서 테이블 그리는 문제 도움 받고 싶습니다
    코드는 아래와 같습니다

    $.ajax({
    url: request_url,
    method: ‘POST’,
    dataType: ‘json’,
    data: {
    start: kpi1,
    end: kpi2,
    type: range,
    },
    error: function()
    {
    alert(“An error occoured”);
    },
    success: function(response)
    {

    var html= getTableHtml(response.rowdata);
    $(“#table_div”).html(html);
    $(‘#sample_1’).dataTable();
    }
    });

    이렇게 하니 테이블은 그려집니다.
    근데 페이징, 탐색을 비롯해서 Datatable이 전혀 동작하질 않습니다
    도와주세요

  26. 정찬명 댓글:

    @문현배
    클라이언트 측 스크립트가 아니라서 저도 잘 모르겠네요. ^^

  27. 마사 댓글:

    아주 유용하게 잘봤습니다..^^

  28. 익명 댓글:

    감사합니다 덕분에 해결했습니다!

  29. 익명 댓글:

    혹시 전송버튼을 누르지 않고 바로 옆에 뜰 수 있게 할 수 있는 방법은 없을까요? 입력창에 입력이 끝나면 바로 유효성 검사할 수 있게요.. 요즘 네이버나 구글 등 큰 사이트들에서는 회원가입시 그렇게 할 수 있는데 보기에 너무 편리해보여서 한번 그런식으로 구현해보고 싶어서요…

  30. 정찬명 댓글:

    @익명
    제 예제에서 #uid, #upw 항목이 그렇게 되어 있습니다. keyup 될 때 마다 유효성 검사를 처리하고 있지요. keyup을 focusout으로 변경하시면 한 항목 입력 완료 후 유효성 검사를 하겠지요.

  31. 필수아님? 댓글:

    지나가다 잠시 질문을.. 자바스크립트 공부중인데요. 아직 기초라.. 여기다 질문을 드려도 되는지..

    아이디 입력할때 영문이 아닌 다른 언어(한국어)로 입력시 바로 옆에는 적당해요라고 검사를 마치고 전송 버튼을 눌러야 다시 아이디를 다시 입력하라는 경고창이 뜨더라구요.
    여기에 다시 영문이 아닌 언어 입력시 경고메세지를 출력하려면 어떻게 해야하나요?
    #uid 함수에 else if 구문을 넣어야 하는건지요 ?

  32. 정찬명 댓글:

    @필수아님?
    아래 부분을 수정해야 할 것 같아요.

    수정 전

    uid.keyup( function() {
    	var s = $(this).next('strong'); // strong 요소를 변수에 할당
    	if (uid.val().length == 0) { // 입력 값이 없을 때
    		s.text(''); // strong 요소에 포함된 문자 지움
    	} else if (uid.val().length < 3) { // 입력 값이 3보다 작을 때
    		s.text('너무 짧아요.'); // strong 요소에 문자 출력
    	} else if (uid.val().length > 16) { // 입력 값이 16보다 클 때
    		s.text('너무 길어요.'); // strong 요소에 문자 출력
    	} else { // 입력 값이 3 이상 16 이하일 때
    		s.text('적당해요.'); // strong 요소에 문자 출력
    	}
    });

    수정 후

    uid.keyup( function() {
    	var s = $(this).next('strong'); // strong 요소를 변수에 할당
    	if (uid.val().length == 0) { // 입력 값이 없을 때
    		s.text(''); // strong 요소에 포함된 문자 지움
    	} else if (uid.val().length < 3) { // 입력 값이 3보다 작을 때
    		s.text('너무 짧아요.'); // strong 요소에 문자 출력
    	} else if (uid.val().length > 16) { // 입력 값이 16보다 클 때
    		s.text('너무 길어요.'); // strong 요소에 문자 출력
    	} else if ( re_id.test(uid.val()) != true ) { // 유효하지 않은 문자 입력 시
    		s.text('유효한 문자를 입력해 주세요.'); // strong 요소에 문자 출력
    	} else { // 입력 값이 3 이상 16 이하일 때
    		s.text('적당해요.'); // strong 요소에 문자 출력
    	}
    });

댓글 쓰기

전송된 글이 나타나지 않는다면 필터링 된 것입니다. dece24앳gmail.com 으로 메일 주세요.
(X)HTML 코드 사용이 가능하지만 소스 코드 출력을 원하시면 <꺽쇠>는 [괄호]로 변환하여 작성해 주세요.

필수 아님

필수 아님