Form 유효성 검사 API


이전 포스트 주제인 FORM 태그에 관한 내용 중 태그에 관한 정의는 아래와 같다고 말씀드렸습니다.



정의: "웹상에서 사용자 정보를 입력하는 여러(text, button, checkbox, file, hidden, image, password, radio, reset, submit)방식의 영역을 제공하며, 사용자로부터 할당된 데이터를 서버로 전송하는 역활을 담당한다."



즉, 사용자가 입력한 데이터를 서버로 전송하여 사용한다는 말입니다.



하지만 사용자가 입력한 데이터에 대한 유효성 검사 없이 서버로 전송한다는 것은 사용자 접근성 및 데이터 무결성을 보장할 수 없는 방법이며, 만약 클라이언트 단의 유효성 검사를 마쳤다 할지라도 서버단 체크가 이루어지지 않는다면 그것 또한, 데이터 무결성을 보장할 수 없습니다.



즉, 클라이언트 단 검증과 서버 단 검증은 분리시켜 생각해야 한다는 말이며, 클라이언트 단 검증은 그 목적 자체가 사용자 접근성 향상에 있다고 봐도 무방할 것입니다.



아래는 가장 일반적인 형태의 유효성 검사만 다루고 있으므로, 새로운 기능에 대한 확장이 필요한 경우 코드를 추가 / 수정하여 사용하시기 바랍니다.





자바스크립트 소스:


  1. // Forms API
  2.  
  3. var Forms = (function(win, doc){
  4.  
  5.     return function(callbacks){
  6.        
  7.         callbacks = callbacks.constructor === Array ? callbacks : [callbacks];
  8.  
  9.         function init(){
  10.            
  11.             this.forms = document.forms;
  12.             this.$forms = getForms(this.forms, callbacks) || {};
  13.                    
  14.             appendSubmitEvent.apply(this, [this.$forms]);
  15.  
  16.             return this;
  17.         }
  18.  
  19.         Forms.fn = init.prototype = {
  20.            
  21.             getForms: getForms,
  22.             valids:
  23.             {
  24.                 // 빈값 체크
  25.                 empty: function empty(o, opt){
  26.  
  27.                     return new (function(){
  28.                    
  29.                         return function()
  30.                         {
  31.                             this.msg = '값을 입력해주세요.';
  32.                             this.exp = null;
  33.                        
  34.  
  35.                             extend.call(this, opt);
  36.                                            
  37.                             this.test = trim(o.value) !== '' ? true : false
  38.  
  39.                             return this;
  40.                         };
  41.  
  42.                     }());
  43.  
  44.                 },
  45.                
  46.                 // 한글 체크
  47.                 han: function(o, opt){
  48.  
  49.                     return new (function(){
  50.                        
  51.                         return function()
  52.                         {
  53.                             this.msg = '한글만 입력만 가능합니다.';
  54.                             this.exp = /^([가-힣ㄱ-ㅎ]| ){1,}$/i;
  55.  
  56.                             extend.call(this, opt);
  57.  
  58.                             var val = o.value;
  59.  
  60.                             this.test = (val !== '' && this.exp.test(val)) ? true : false
  61.  
  62.                             return this;
  63.                         };
  64.  
  65.                     }());
  66.                 },
  67.                
  68.                 // 영문 체크
  69.                 eng: function(o, opt){
  70.  
  71.                     return new (function(){
  72.                        
  73.                         return function()
  74.                         {
  75.                             this.msg = '영문만 입력만 가능합니다.';
  76.                             this.exp = /^([a-zA-Z]| ){1,}$/i;
  77.  
  78.                             extend.call(this, opt);
  79.  
  80.                             var val = o.value;
  81.  
  82.                             this.test = (val !== '' && this.exp.test(val)) ? true : false
  83.  
  84.                             return this;
  85.                         };
  86.  
  87.                     }());
  88.                 },
  89.                
  90.                 // 문자 체크
  91.                 str: function(o, opt){
  92.                    
  93.                     return new (function(){
  94.                        
  95.                         return function()
  96.                         {
  97.                             this.msg = '문자를 입력해주세요.';
  98.                             this.exp = /^([\w가-힣]| ){1,}$/i;
  99.  
  100.                             extend.call(this, opt);
  101.  
  102.                             var val = o.value;
  103.  
  104.                             this.test = (val !== '' && this.exp.test(val)) ? true : false
  105.  
  106.                             return this;
  107.                         };
  108.  
  109.                     }());
  110.                 },
  111.                
  112.                 // 숫자 체크
  113.                 num: function(o, opt){
  114.  
  115.                     return new (function(){
  116.                        
  117.                         return function()
  118.                         {
  119.                             this.msg = '숫자 입력만 가능합니다.';
  120.                             this.exp = /^([0-9]| ){1,}$/i;
  121.  
  122.                             extend.call(this, opt);
  123.  
  124.                             var val = o.value;
  125.  
  126.                             this.test = (val !== '' && this.exp.test(val)) ? true : false
  127.  
  128.                             return this;
  129.                         };
  130.  
  131.                     }());
  132.                 }
  133.  
  134.                 // 유효성 검사 기능 함수 추가.....
  135.             }
  136.         }
  137.  
  138.         return new init();
  139.  
  140.     };
  141.  
  142.  
  143.     function getForms(forms, callbacks){
  144.  
  145.         var $forms = {};
  146.  
  147.         for (var i = 0, ilength = forms.length; i < ilength; i++){                 
  148.            
  149.             var f = forms[i];
  150.            
  151.             $forms[f.id] = {
  152.                 f: f,
  153.                 inputs: [],
  154.                 pns: [],
  155.                 callback: callbacks[i]
  156.             };
  157.  
  158.        
  159.             for (var k = 0, klength = f.length; k < klength; k++){                                     
  160.                                
  161.                 var cs = f[k].className && f[k].className.split(' ');
  162.  
  163.                 for (var t = 0, tlength = cs.length; t < tlength; t++){
  164.                     if (Forms.fn.valids[cs[t]]){
  165.                         $forms[f.id].inputs.push(f[k]);
  166.                         $forms[f.id].pns.push(cs[t]);
  167.  
  168.                         continue;
  169.                     }
  170.                 }
  171.             }
  172.         }
  173.  
  174.         return $forms;
  175.     };
  176.  
  177.  
  178.     function appendSubmitEvent(forms){
  179.        
  180.         var $forms = forms || {};
  181.  
  182.         for (var n in $forms){
  183.            
  184.             (function($){
  185.  
  186.                 var f = $.$forms[n].f
  187.                   , inputs = $.$forms[n].inputs
  188.                   , pns = $.$forms[n].pns
  189.                   , callback = $.$forms[n].callback;
  190.                
  191.                 bind(f, 'submit', function(e){
  192.                                                    
  193.                     for (var i = 0, length = inputs.length; i < length; i++){
  194.                        
  195.                         var match = $.valids[pns[i]](inputs[i]);
  196.                        
  197.                         if (!match.test){
  198.                             alert(match.msg);
  199.                             inputs[i].focus();
  200.                             return false;
  201.                         }                      
  202.                     }
  203.                    
  204.                     if (typeof callback === 'function') callback.call(f);
  205.  
  206.                 });
  207.  
  208.             })(this);
  209.         }
  210.     }
  211.  
  212.     // 객체 상속 함수
  213.     function extend(){
  214.        
  215.         var target = this
  216.           , opts = []
  217.           , src = null
  218.           , copy = null;
  219.  
  220.         for (var i = 0, length = arguments.length; i < length; i++) {
  221.            
  222.             opts = arguments[i];
  223.            
  224.             for (var n in opts) {
  225.                 src = target[n];
  226.                 copy = opts[n];
  227.  
  228.                 if (src === copy) continue;
  229.                 if (copy) target[n] = copy;
  230.             }
  231.         }
  232.     };
  233.  
  234.  
  235.     function trim(s){
  236.        
  237.         return s.replace(/(\s)/g, '');
  238.     };
  239.  
  240. })(window, document);
  241.  
  242.  
  243. // submit callback 함수
  244. var Member = (function(){
  245.  
  246.  
  247.    return new (function(){
  248.      
  249.        function init(){  
  250.          
  251.            return this;
  252.        }
  253.  
  254.        init.prototype = {
  255.            login: login
  256.        };
  257.  
  258.  
  259.        return init;
  260.  
  261.    }());
  262.  
  263.  
  264.     function login(){    
  265.        
  266.         var id = document.getElementById('loginId');
  267.         var pass = document.getElementById('loginPass');
  268.  
  269.         if (!id.value || !pass.value) this.submit();
  270.     }
  271.  
  272. })();
  273.  
  274.    
  275. // 이벤트 할당
  276. function bind(elem, type, handler, capture)
  277. {    
  278.     type = typeof type === 'string' && type || '';
  279.     handler = handler || function(){ ; };
  280.    
  281.     if (elem.addEventListener){
  282.         elem.addEventListener(type, handler, capture);
  283.     }
  284.     else if (elem.attachEvent){
  285.         elem.attachEvent('on' + type, handler);
  286.     }
  287.  
  288.     return elem;
  289. };
  290.  
  291.  
  292.  
  293. // api 호출
  294. bind(window, 'load', function(){
  295.     // Forms([callback, callback, callback]);
  296.     Forms([
  297.         Member.login,
  298.         Member.login,
  299.         Member.login
  300.     ]);
  301. });
  302.  





HTML 소스:


  1. <form id="login1" method="post" target="login_frm1" action="http://naver.com" enctype="application/x-www-form-urlencoded">
  2.     <fieldset>
  3.         <legend>폼 1</legend>
  4.         <input type="text" id="loginId" name="loginId" value="아이디" class="empty han" />
  5.         <input type="password" id="loginPass" name="loginPass" class="empty class"  />     
  6.     </fieldset>
  7.     <input type="submit" value="폼제출" />
  8. </form>
  9.  
  10. <iframe id="login_frm1" name="login_frm1" width="0" height="0" frameborder="0"></iframe>
  11.  
  12. <!-- 두 번째 폼 -->
  13. <form id="login2" method="post" target="login_frm2" action="http://naver.com" enctype="application/x-www-form-urlencoded">
  14.     <fieldset>
  15.         <legend>폼 2</legend>
  16.         <input type="text" id="loginId" name="loginId" value="아이디" class="han class" />
  17.         <input type="password" id="loginPass" name="loginPass" class="empty class"  />
  18.         <input type="text" id="loginId" name="loginId" value="아이디" class="eng class" />
  19.         <input type="password" id="loginPass" name="loginPass" class="empty"  />
  20.         <input type="text" id="loginString" name="loginPass" class="str"  />
  21.         <input type="text" id="loginNum" name="loginPass" class="num"  />
  22.     </fieldset>
  23.     <input type="submit" value="폼제출" />
  24. </form>
  25.  
  26. <iframe id="login_frm2" name="login_frm2" width="0" height="0" frameborder="0"></iframe>
  27.  
  28. <!-- 세 번째 폼 -->
  29. <form id="login3" method="post" target="login_frm3" action="http://naver.com" enctype="application/x-www-form-urlencoded">
  30.     <fieldset>
  31.         <legend>폼 3</legend>
  32.         <input type="text" id="loginId" name="loginId" value="아이디" class="han class" />
  33.         <input type="password" id="loginPass" name="loginPass" class="empty class"  />
  34.         <input type="text" id="loginId" name="loginId" value="아이디" class="eng class" />
  35.         <input type="password" id="loginPass" name="loginPass" class="empty"  />
  36.         <input type="text" id="loginString" name="loginPass" class="str"  />
  37.         <input type="text" id="loginNum" name="loginPass" class="num"  />
  38.     </fieldset>
  39.     <input type="submit" value="폼제출" />
  40. </form>
  41.  
  42. <iframe id="login_frm3" name="login_frm3" width="0" height="0" frameborder="0"></iframe>





폼 화면: