[AngularJS] 폼(form)과 유효성 검사

Posted in 모바일/Javascript // Posted at 2016. 7. 18. 00:30
728x90

AngularJS는 HTML 폼을 확장하여 입력요소에 자바스크립트 객체를 바인딩하고, 전체 폼 또는 개별 입력요소에 대한 유효성 검사를 추가할 수 있는 방법을 제공한다.

* 폼의 데이터 바인딩
- 폼의 입력요소와 AngularJS의 상호작용은 (뷰와 컨트롤러의 상호작용이 늘 그렇듯이) $scope 객체를 매개로 이뤄진다. 폼 요소와 $scope 객체의 관계를 확인하기 위해 다음과 같이 간단한 코드를 작성해 본다.

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
var app = angular.module("myApp",[]);
app.controller("myCtrl", function($scope){ 
 $scope.checkScope = function(){  
  console.log($scope); //$scope객체를 console 로그에서 확인해 본다.
 };
});
</script>
<body ng-app="myApp" ng-controller="myCtrl">
<div>
 <p>Name: <input type="text" ng-model="name"></p>
 <p ng-bind="name"></p> 
 <button ng-click="checkScope();">check</button>
</div>
</body>
</html>

input 박스에 ng-model 디렉티브를 선언하고, 바로 밑 <p> 요소에 ng-bind 디렉티브를 동일한 이름으로 선언하였다. (ng-bind 대신 '{{ name }} ' 형태의 표현식으로 해도 동일하게 동작한다)

코드를 실행해 보면, input 요소에 입력한 값들이 자동으로 <p> 요소에 반영되어 데이터가 같이 변경되는 것을 확인할 수 있다.

이와 같은 폼 요소에 대한 자동 바인딩 내부에는 $scope 객체가 존재한다.
코드에서는 명시적으로 $scope 객체에 name이라는 속성을 추가한 적은 없지만, ng-model 디렉티브로 인해 입력요소에 값이 입력되는 순간 $scope에 name라는 속성이 자동으로 추가된다.

콘솔로그를 통해 확인해 보자.
코드가 처음 브라우저에 로딩된 순간에는 $scope객체에 name이 속성을 찾을 수 없다. 그러나 input요소에 값을 입력하는 순간 자동으로 $scope객체에 name속성이 (입력 값과 함께) 자동으로 추가된다. 다음 그림은 콘솔로그를 통해 확인해 본 것이다.

결국 뷰와 컨트롤러의 데이터바인딩은 $scope 객체를 통해 이뤄지며, 이는 폼 요소에 대한 ng-model 디렉티브 설정을 통해 $scope객체의 속성과 연결되어 양방향 바인딩이 자동으로 이뤄지는 메커니즘이다.

* 폼의 입력요소
폼의 입력요소에는 다음과 같은 것들이 있다.
- input 엘리먼트: 텍스트박스, 체크박스, 라디오 버튼 등 입력요소
- select 엘리먼트: 여러개의 아이템 중 하나를 선택할 수 있는 입력요소
- textarea 엘리먼트: 여러 행의 글을 작성할 수 있는 입력요소
- button 엘리먼트: 클릭으로 명령을 전송할 수 있는 입력요소

* CheckBox
- 다음 코드는 체크박스에 대한 AngularJS의 임의구현이다.  첫 번째 체크박스의 ng-model 값을 두 번째 체크박스의 ng-checked 디렉티브로 연결하고 있다. 이렇게 하면 두 번째 체크박스는 첫 번째 체크박스의 선택여부에 동기화되어 선택/해제 된다.
그리고 ng-show 디렉티브는 첫 번째 체크박스의 선택여부에 따라 화면에 표시할 지 여부를 결정한다.

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app>
  <form>
    checkbox1: <input type="checkbox" ng-model="chk1">
    <br />
    checkbox2: <input type="checkbox" ng-checked=chk1">
  </form>
  <!-- checkbox가 선택된 경우 화면에 표시 -->
  <h1 ng-show="chk1">checkbox1 is checked</h1>
</div>
</body>
</html>

* RadioButton
- 다음 코드는 라이오버튼에 대한 AngularJS의 임의구현이다. 라이브버턴 마다 ng-model을 설정하고 {{xxx}} 표현식으로 선택된 값을 출력한다. 그리고 ng-switch계열 디렉티브를 통해 조건식을 구현할 수 있다.

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app>
<form>
  Pick a topic:
  <input type="radio" ng-model="rdobtn" value="r1">Radio1
  <input type="radio" ng-model="rdobtn" value="r2">Radio2 
</form>
<div ng-switch="rdobtn">
  <!-- 선택된 값 출력 -->
  <h1>checked: {{rdobtn}}</h1>

  <!-- 선택된 값에 대한 조건식 로직 -->
  <div ng-switch-when="r1">
     <h1>radio1 is checked</h1>   
  </div>
  <div ng-switch-when="r2">
     <h1>radio2 is checked</h1>
  </div> 
</div>
</body>
</html>


* SelectBox
- 라이브버튼과 거의 유사한 임의코드이다.

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app>
<form>
  Select a topic:
  <select ng-model="selbox">
    <option value="">
    <option value="v1">value1
    <option value="v2">value2
  </select>
</form>
<div ng-switch="selbox">
  <!-- 선택된 값 출력 -->
  <h1>selected: {{selbox}}</h1>

  <div ng-switch-when="v1">
     <h1>value1 is selected</h1>   
  </div>
  <div ng-switch-when="v2">
     <h1>value2 is selected</h1>   
  </div>
</div>
</body>
</html>

 

* AngularJS의 폼 확장
- AngularJS는 표준 HTML 폼 요소를 확장한 form 디렉티브와 폼의 상태를 추적하기 위한 FormController 컨트롤러의 인스턴스를 생성해 폼을 관리한다.

HTML페이지의 폼의 name 특성을 통해 폼이름을 지정하면 $scope객체에 지정된 이름으로 폼 객체가 추가되며 하위 폼 요소들도 주어진 이름으로 추가된 폼 객체의 하위 프로퍼티로 자동 추가된다. 이후 이들 이름을 기반으로 뷰 및 컨트롤러에서 폼 요소들을 참조하여 특정 작업을 수행할 수 있다.

폼 요소들이 지정된 name값을 기반으로 $scope 객체에 자동추가 된다는 것을 눈으로 확인해보자.
다음과 같은 입력요소를 하나 가지는 간단한 폼을 만든다. 주의할 점은 폼요소가 모두 로딩된 후 $scope 객체를 확인해야 하므로 <script> 요소를 </body> 직전에 위치 시켰다. (일반적으로 스크립트 태그는 이 위치에 두는 것을 권장하는데, 이는 DOM 구성이 스크립트 로딩과 실행으로 지연되지 않도록 하기 위함으로 모든 DOM이 구성되고 난 후 안정적으로 스크립트를 실행시키기 위함도 있다.)

<!DOCTYPE html>
<html lang="en">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="formCtrl">
  <form name="myForm">
    UserName:
    <input type="text" name="myInput" ng-model="myInput"><br>   
  </form>  
</div>
<script>
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) { 
 console.log($scope); 
});
</script>
</body>
</html>

지금 상황에서 input 요소에 ng-model 디렉터리가 꼭 필요한 것은 아니지만, AngularJS는 ng-model 디렉티브가 추가된 입력요소에 한해서 $scope 객체에 등록시키기 때문에 추가한 것이다.
결과로 본 콘솔로그는 다음과 같다.

이렇게 폼 요소의 name 값을 기준으로 $scope객체에 자동추가 되기 때문에, 이후 컨트롤러나 뷰에서 해당 폼 요소의 이름으로 접근 가능한 것이다.

* 폼과 입력필드의 상태(폼 유효성 검사의 기반)
- AngularJS는 폼의 유효성 검사를 위해 폼과 입력요소의 상태값을 지속적으로 감시하고 관리한다.
다음은 각각 폼과 입력필드의 상태를 알 수 있는 참조변수를 보여준다.

 

 

 

 

사용자 반응에 따른 폼과 입력요소의 상태값 변화를 눈으로 확인해 보기 위해, 직전의 예제를 다음과 같이 조금 수정해 보자.

<!DOCTYPE html>
<html lang="en">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app>
  <form name="myForm">
    UserName:
    <input type="text" name="myInput" ng-model="myInput" required><br>   
  </form>  
  <div>
  <h1>Form States</h1>
   Pristine: {{myForm.$pristine}} <br /> 
   Dirty: {{myForm.$dirty}} <br />
   Valid: {{myForm.$valid}} <br />
   Invalid: {{myForm.$invalid}} <br />  
   Submitted: {{myForm.$submitted}} <br />
   Error: {{myForm.$error}} <br />
  
   <h1>Input States</h1>
   Touched: {{myForm.myInput.$touched}} <br />
   Untouched: {{myForm.myInput.$untouched}} <br />
   Pristine: {{myForm.myInput.$pristine}} <br /> 
   Dirty: {{myForm.myInput.$dirty}} <br />
   Valid: {{myForm.myInput.$valid}} <br />
   Invalid: {{myForm.myInput.$invalid}} <br />     
   Error: {{myForm.myInput.$error}} <br />

  </div>
</div>
</body>
</html>

 예제를 브라우저로 실행시키고, 입력요소에 값을 입력하거나 포커스를 이동시켜보자. 그러면 각 행위에 따라 폼의 상태값의 변경을 확인할 수 있을 것이다. 이와같은 폼 상태 변화는 AngularJS가 폼 유효성을 검사하는 기반으로 활용된다.

* 폼 초기화

- 폼을 최초 로딩된 상태로 초기화 시키는 것은, 최초값을 보관해 두었다가 다시 그 값으로 회귀 시켜 주면 된다. 다만 데이터 초기화와 AngularJS의 폼 유효성 검사를 위한 상태값까지 모두 초기화 시켜 주는 것이 좋다. 앞서 살펴본바와 같이 AngularJS는 폼 및 입력요소에 대한 상태값을 지속적으로 관리하는데, 이부분까지 모두 초기화 시켜주면 완벽하다.

다음 코드는 폼 초기화를 위한 코드 샘플인데, 데이터 초기화의 경우 원본을 유지한채 복사본을 사용하는 것으로 처리하고 추가로 $setPristine(), $setUntouched() 함수를 호출하여, 폼 변경에 따른 내부 상태값의 변화 역시 같이 초기화 시켜준다.

<!DOCTYPE html>
<html lang="en">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
    //폼 초기화를 위한 초기값 저장 
    $scope.origin = {firstName:"OriginFirst", lastName:"OriginLast"};
    //초기값에 기반하여 복사 수행(이 값은 폼과 양방향 바인딩 됨)
    $scope.user = angular.copy($scope.origin);
   
    $scope.resetForm = function() { 
         //폼 요소들의 입력값을 초기 값으로 변경
         $scope.user = angular.copy($scope.origin);   
         //폼 요소를 최초의 깨끗한 상태로 돌리기
         $scope.myForm.$setPristine();
         //폼 요소를 한번도 손대지 않은 상태로 돌리기
         $scope.myForm.$setUntouched();
    };       
});
</script>
<body>
<div ng-app="myApp" ng-controller="formCtrl">
  <form name="myForm" novalidate>
    First Name:<br>
    <input type="text" ng-model="user.firstName"><br>
    Last Name:<br>
    <input type="text" ng-model="user.lastName">
    <br><br>
    <button ng-click="resetForm();">RESET</button>
  </form>
  <p>Pristine: {{myForm.$pristine}}</p>   
</div>
</body>
</html>


* 폼 유효성 검사
- 지금까지 살펴본 것처럼, AngularJS는 폼의 입력요소들의 변경에 따른 상태값을 지속적으로 관리하며 이를 기반으로 폼의 유효성 검사를 지원한다. 폼의 유효성 검사 기준은 HTML5에 새로이 추가된 유효성 관련 특성(Attribute)에 근거하거나 개발자가 직접 자신만의 유효성 검사 기준을 만들 수 있도록 지원한다.

HTML5의 새로운 입력타입과 특성에 기반한 유효성 검사
- 가장 흔한 유효성 검사는 입력필드에 대한 필수입력 여부와 입력필드 타입에 따른 유효값 검사이다.
다음 코드는 HTML5의 required 특성을 부여한 필수 입력필드에 대한 입력여부와 email 타입의 입력필드에 대한 입력값 유효성 검사 샘플이다. 입력필드에 대한 $valid는 입력값 여부에 따라 true/false 값 중 하나를 반환한다.

<form name="myForm">
  <input name="txtName" ng-model="txtName" required
  {{myForm.txtName.$valid}}
  <br />
  <input name="txtEmail" ng-model="txtEmail" type="email" required
  {{myForm.txtEmail.$valid}}
</form>

AngularJS 디렉티브에 기반한 유효성 검사
- AngularJS가 미리 정의해 둔 디렉티브 기반으로 유효성 검사도 가능하다. 다음 코드는 필수입력 지정과 입력문자의 최소/최대 길이를 지정하여 유효성 검사를 수행한다.

<form name="myForm">
   <input name="txtName" ng-model="txtName" ng-required="true" ng-minlength="3"
     ng-maxlength="5"
>
   {{myForm.txtName.$valid}}
</form>

입력폼 검사의 일반적 패턴
- 이번에는 좀 더 실용적인 코드 샘플을 보자. 하나의 필수 입력필드와 이메일 입력필드가 존재한다. 각 입력필드 바로 옆에는 유효성 실패에 대한 안내 메시지를 보여준다. ng-show 디렉티브는 주어진 조건값이 참/거짓에 따라 표시여부를 결정한다. 코드에서 주어진 조건은 입력필드에서 포서커를 잃고($touched) 유효성 검사에 실패한 경우($invalid)에 대한 And 조건으로 부여한다.
그리고 submit 버튼은 ng-disabled 디렉티비를 지정하는데 두 입력필드 중 하나라도 유효하지 않으면 비활성화 되도록 조건을 부여한다.

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app>
<form name="myForm">
  <input name="txtName" ng-model="txtName" required autofocus>
  <span style="color:red" ng-show="myForm.txtName.$touched && myForm.txtName.$invalid">
   <span ng-show="myForm.txtName.$error.required">Username is required.</span>
  </span>
  <br />
  <input type="email" name="txtEmail" ng-model="txtEmail" required>
  <span style="color:red" ng-show="myForm.txtEmail.$touched && myForm.txtEmail.$invalid">
   <span ng-show="myForm.txtEmail.$error.required">Email is required.</span>
   <span ng-show="myForm.txtEmail.$error.email">Invalid email address.</span>
  </span>
  <br />
  <input type="submit" ng-disabled="myForm.txtName.$invalid || myForm.txtEmail.$invalid">
</form>
</body>
</html>


* ngMessages 모듈 이용하기
- ngMessages 서브모듈을 이용하여 유효성 검사에 따른 메시지 표시를 보다 체계적으로 관리할 수 있을 것이다. 이 모듈을 사용하려면 angular-messages.js 파일을 따로 참조해 줘야 한다.
ng-messages 디렉티브에 $error 객체를 바인딩해서 해당 입력요소가 유효한지 여부를 판단할 수 있게 한다. 그리고 ng-message 디렉티브에 검사하고자 하는 유효성 조건의 이름을 지정한다. 예에서는 총 3개(required, minlength, maxlength) 조건을 지정했다.
만일 해당 입력요소에 유효성 오류가 있고, 각 오류가 어떤 검사 기준인지에 따라 서로 다른 메시지를 보여주게 될 것이다.

<!DOCTYPE html>
<html>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular-messages.js"></script>

<script>
(function(angular) {
 angular.module('myApp', ['ngMessages']);
})(window.angular);
</script>

<body ng-app="myApp">
<form name="myForm">
  Name: <input type="text" name="txtName" ng-model="txtName" required ng-minlength="5" ng-maxlength="10">
  <div ng-messages="myForm.txtName.$error">
   <div ng-message="required">You did not enter a field</div>
    <div ng-message="minlength">Your field is too short</div>
    <div ng-message="maxlength">Your field is too long</div>
  </div>

</body>
</html>

 

* 사용자 정의 유효성 검사
- 지금까지는 입력요소의 필수입력여부, 타입 및 길이 등 HTML5의 새로운 특성이나 AngularJS가 내부적으로 지원하는 유효성 검사 기준을 사용하여 체크를 수행하였다.

그러나 실무환경에서는 보다 다양한 유효성 검사 조건이 존재할 수 있다. 예를 들어 입력필드에 들어가는 값은 반드시 숫자여야 하던지, 아님 어떤 정규식에 근거하여 유효성 검사를 수행하기도 한다.

이런 경우, 사용자 정의 유효성 검사기를 새로 만들면 된다. 사용자 정의 유효성 검사를 위해서는 커스텀 디렉티브를 생성하며 기존 디렉티브와의 차이점은 ngModel 모듈을 디렉티브에 추가해야 한다는 점이다.

다음 코드는 정규표현식에 기반한 사용자 정의 유효성 검사 디렉티브 구현을 보여준다. AngularJS 공식문서의 샘플코드이며, 커스텀 디렉티브의 link 함수를 통해 구현한다.

유효성 검사기의 이름은 integer으로 기존 필수입력 조건인 required와 마찬가지로 HTML의 특정 입력요소에 integer라는 이름으로 유효성 기준을 추가할 수 있다.

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>

(function(angular) { 
 var app = angular.module('myApp', []);
 
 var INTEGER_REGEXP = /^\-?\d+$/;
 app.directive("integer", function(){
  return {
   require: 'ngModel',
   link: function(scope, elm, attrs, ctrl){
    ctrl.$validators.integer = function(modelValue, viewValue){
     if(ctrl.$isEmpty(modelValue)){
      //비어 있을 경우 유효한 것으로 간주한다.
      return true;
     };
     if(INTEGER_REGEXP.test(viewValue)){
      //정규식과 일치하므로 유효함
      return true;
     };
     //위 두조건을 모두 만족하지 않으므로 유효하지 않음
     return false;
    };
   }
  };
 });
})(window.angular);
</script>
<body ng-app="myApp">
<form name="myForm">
 <input type="text" ng-model="amount" name="amount" integer /><br />
 <span ng-show="myForm.amount.$error.integer">정수가 아닙니다.</span> 
</form>
</body>
</html>

 

[HTML5] 웹 양식(Web Form)의 개선, 폼 태그

Posted in 모바일/HTML5 // Posted at 2010. 8. 26. 17:31
728x90

웹 양식(Web Form)의 개선
웹 양식을 지원하는 태그를 폼 태그(Form Tag)라 한다
보통 회원가입이나 게시판 글쓰기 같은 UI를 만들 때 사용되는 태그로
input 박스, select 박스, button, checkbox , radio 버턴 등이 있다

이러한 폼 태그는 HTML 문서에서 사용자 입력을 위해 제공되는 양식 태그이다
물론 폼 태그는 HTML5 이전에도 제공되어 왔다. 다만, HTML5 에서는 기존 폼 태그와 더불어 대폭 개선된 형태를 새로 추가하였다

기존 폼 태그는 텍스트, 버턴, 선택박스, 체크박스 등 단순한 형태의 입력 양식만을 제공했지만 HTML5에서는 달력양식, Range 양식, email 등 새롭고 실용적인 양식이 추가 되었으며 입력 보조 수단이나 입력 값 검증 등 기존에는 스크립트에 의존할 수 밖에 없었던 기능적 요소도 폼 태그에 추가 되었다
이러한 향상된 웹 폼을 Web Forms 2.0 이라 한다


이러한 다양하고 실용적인 양식 태그들이 추가됨으로써 좀더 쉽고 빠르게 개발을 할 수 있게 된 것이다

브라우저 지원 현황

아직까지 대부분의 브라우저에서는 모든 폼 태그를 지원하지는 않는 것 같다
각 브라우저가 폼 태그의 부분적인 것을 지원하며 그 부분적인 것은 브라우저마다 조금씩 상이하다
예를 들어 range input 요소의 경우 크롬에서는 지원되지만 파이어폭스에서는 지원되지 않는다

일단 caniuse.com 에서 제공하는 지원표를 보도록 하자



그림1. 브라우저별 새 폼 태그 지원 현황 (출처: http://caniuse.com/)

위의 표에서도 알 수 있듯이 대부분의 브라우저가 부분적으로 새 폼 태그를 지원하고 있다
다만 오페라는 모두 지원한다고 나와 있는데 확인해 볼 일이다

현재 시점에 브라우저 지원현황은 부분적이며 일관적이지도 않아 만족스럽지 못하기는 하다
(브라우저 호환성을 확보하기 힘드니 실 서비스 적용이 꺼려지는 것이다)
그러나 머지 않은 시기에  모든 요소가 지원되지 않을까 하고 기대 해 본다

Google's WebForms2 라이브러리
http://code.google.com/p/webforms2/

HTML5 의 Canvas를 지원하지 않는 IE8 이전 버전을 위해
ExplorerCanvas(http://code.google.com/p/explorercanvas/) 라이브러리가 제공되듯이
HTML5 확장 폼을 지원하지 않는 브라우저의 경우 WebForm2 라이브러리를 사용할만 하다

라이브러리를 다운받고 아래와 같이 라이브러리를 참조한다
<script type='text/javascript' src='webforms2.js'></script>

WebForms2 라이브러리는 HTML 폼 확장에 대해 각 브라우저마다 다르게 동작하는 문제점을 극복하기 위해 제공되며 Cross Broswer HTML5 Form 구현을 가능하도록 해 준다.
이와 관련한 다음의 글을 참고해 보기 바란다
http://nz.pe.kr/wordpress/programming/html5/번역-지금-바로-cross-browser-html5-form-만드는-방법


웹 양식 다루기
그럼 이제 HTML5 에서 추가되거나 개선된 웹 양식을 하나 씩 살펴보자
참고로 브라우저마다 웹 양식의 지원 범위가 다르기 때문에 각 요소를 설명할 때 지원되는 브라우저를 각각 달리하여 테스트 할 것이다(예제 실행 화면 옆에 브라우저를 명시한다)

새로운 입력 양식(새로 추가된 i
nput 타입)
input 태그에 다양한 타입이 새로 추가되었다.
기존에 제공되었던 text, button,checkbox 등은 여전히 유효하며 다음과 같은 양식이 추가되었다

1) range
일정한 범위의 숫자를 입력 받기 위한 양식이다
min, max 속성에 범위의 최소, 최대값을 지정하고 step 으로 범위 이동 크기를 지정한다
아래 예는 0 ~ 10 까지의 범위를 가지는 2칸식 이동 가능한 Range 컨트롤이다(기본값은 2)

<input type="range" min=0 max=10 step=2 value=2>

(크롬)

2) number
숫자를 입력 받기 위한 양식이다
range 양식과 마찬가지로 min, max, step 속성을 가진다

<input type="number" min=1 max=10 step=1 value=5>

(오페라)

3) date
날짜를 입력 받기 위한 양식이다. 날짜 선택을 위한 달력이 표시된다
역시 min, max, step 속성이 제공된다

<input type="date" min="2001-01-01" max="2010-08-31" step=1 value="2010-08-26">

(오페라)

날짜와 시간관련 양식은 data 외에데 몇 가지가 더 있다. 다음을 참고하자

<input type="datetime"><input type="datetime-local"><input type="month">
<input type="week"><input type="time">




4) 기타 새로운 타입들
검색을 위한 search 타입, 전화번호 입력을 위한 tel 타입, 리소스 주소 입력을 위한 url 타입, 이메일 입력을 위한 email 타입, 색상 입력을 위한 color 타입 등이 새로 추가되었다
현재 데스크탑 브라우저들에서는 이들 타입이 지원되지 않거나 평범한 text 타입처럼 보이기 때문에
설명으로만 대체하겠다

다만 특이한 점은 이러한 타입이 아이폰과 같은 모바일 기기에서는 해당 타입에 맞춰 UI가 다르게 보이기도 한다. 아래 글을 참고 바란다

iPhone의 모바일 Safari 브라우저에서는 이러한 새 유형을 일부 사용하여 사용자에게 표시되는 키보드 유형을 변경한다. 예를 들면, 이메일 유형과 함께 @ 기호와 .com 단축 아이콘이 표시된다. 또한, Opera에서는 숫자 유형을 선택할 수 있는 스피너와 날짜 관련 유형을 선택할 수 있는 날짜 선택도구와 같은 다양한 제어를 구현하는 데 필요한 새로운 위젯을 일부 제공한다
- IBM Developer Works HTML5 컬럼 중... -

참고: 새로운 입력(input) 양식에 대한 다음 글을 참고하기 바란다
http://www.w3schools.com/html5/html5_form_input_types.asp

개선된 폼 양식
새로운 양식의 추가는 물론이고 기존 양식의 기능적 요소들도 상당 부분 개선되었다
 
1) 입력 보조 수단
새로운 양식의 추가 이외에도 자동 포커싱이나 PlaceHolder 와 같은 입력 보조 수단도 제공된다
자동 포커싱은 페이지가 로딩될 때 특정 양식으로 포커스를 주는 것이며 PlaceHolder은 텍스트기반 입력양식이 비어있을 경우 표시하는 텍스트를 지정할 수 있도록 한다
중요한 것은 이전 환경에서 이들 기능을 구현하려면 자바스크립트에 의존했어야 했지만 HTML5는 양식태그의 속성만으로 해결해 준다

<input type='search' autofocus>
<input type='email' placeholder="이메일 주소 입력">
<input type='tel' placeholder="전화번호 입력">

 

(크롬)


2) 파일 선택 양식의 개선
웹 페이지에서 서버로 파일을 업로드 하기 위해서 사용되던 것이 파일 input 박스이다
이는 이전에도 제공되는 것이지만 HTML5 에서는 기능적으로 보다 개선되었다

- 다중 파일 업로드(multiple 속성)
HTML5 이전 환경에서는 하나의 파일 박스에는 하나의 파일만 선택 가능했었다
다중 파일을 업로드 하기 위해서는 여러개의 파일박스를 두거나 서드파티업체의 제품을 이용했어야 했다. 그러나 HTML5 에서는 하나의 파일박스에 여러개의 파일을 지정할 수 있도록 개선되었다

<input type='file' multiple>

- 파일 필터링(accept 속성)
파일 선택 창에서 파일 형식을 제한할 수 있다
기본적으로 모든 파일 형식이지만 MIME 타입을 지정하여 특정 형식으로의 제한이 가능하다

<input type='file' accept="image/gif">

- 파일 정보 액세스(files 속성)
선택된 파일(들)의 정보를 조회하려면 파일박스 DOM 객체의 files 속성을 이용하면 된다
files 속성은 선택된 파일(들)의 정보를 배열형태로 담아 두고 있다. 각 배열의 요서가 특정 한 파일의 정보가 되며 name 및 size 속성등으로 파일 정보를 액세스 할 수 있다

<script type="text/javascript">
  var selectedFiles = document.getElementById("file").files;
  selectedFiles[0].name; //파일이름
  selectedFiles[1].size; //파일사이즈 
</script>


3) submit(폼 전송) 버턴의 개선

input 타입 중 submit , image 는 폼 전송을 수행하는 버턴이다
폼을 전송하기 위해 전송할 곳(action), 전송방식(get or post),enctype 등을 명시해야 하는데
이전 환경에서는 <form> 태그에 이들 속성을 지정하였다
HTML5 에서는 폼 전송 버턴인 submit, image 버턴에도 이들 속성을 지정할 수 있게 되었다

<form>
    <input type="submit" formmethod="POST" formaction="/formOk.html">
</form>

만일 <form> 과 submit 버턴 둘 다 action 이 지정되면 submit 에 지정된 action 값이 우선 적용 된다
(현재 오페라 브라우저에서만 정상 동작함)

 
추가된 폼 양식
input 타입에 새로운 양식이 추가된 것과 더불어 새로운 폼 요소들도 몇 가지 추가되었다

1) Progress 요소
진행 상태를 알려 주는 프로그레스 바를 나타낸다
max, value 를 이용하여 진행량의 최대값과 초기값을 지정할 수 있으며 position 속성을 참조하여 진행률을 계산할 수 있다. 현재 시점에 progress 요소를 지원하는 브라우저는 없다

<progress max="1" value="0"></progress>


2) Output 요소
새로 추가된 폼 출력요소이다. Input 요소가 폼 입력을 담당한다면 Output 요소는 폼 출력을 담당한다
보기에는 단순한 텍스트처럼 보이지만 실제로 폼 전송시 Output 요소의 값도 같이 전송된다. 이런 의미에서 눈에 보이는 히든 요소라는 표현도 있다. 읽기전용 폼 전송 요소를 정의한다고 보면 된다

<output name="sum">100</output>


3) DataList 요소
input (입력) 양식에 대한 옵션 리스트를 제공한다
즉 입력 양식에 들어갈 내용을 미리 제공하여 input 박스에 포커스가 오면 이 리스트를 보여준다
input 박스의 list 속성에 datalist id를 지정하여 둘을 매핑 시킨다

<input type="url" list="url_list" />
  <datalist id="url_list">
  <option label="모바일플랫폼" value="http://m.mkexdev.net" />
  <option label="MKEX의닷넷" value="http://www.mkexdev.net" />
  <option label="Microsoft" value="http://www.microsoft.com" />
  </datalist>

(오페라)

4) Keygen 요소
암호 키를 생성해 주는 폼 요소이다.
공개키기반의 키 쌍을 생성하며 폼 전송 시 공개키가 서버로 전송된다
다음은 RSA 키를 생성하는 코드이며 브라우에 이 요소가 표시될 때 키의 길이를 선택하도록 표시된다

<keygen name="key" keytype="rsa"></keygen>

(크롬)


5) Meter 요소
디스크 사용량과 같은 용량과 임계치가 존재하는 상황에서 현재 사용량을 보여주는 UI를 표시한다
min, max 로 최소값과 최대값(임계치)를 설정하며 현재 사용량의 정도(낮음, 높음, 적정)을 나타내는 low, high, optimum 속성이 제공된다. 현재 시점에 progress 요소를 지원하는 브라우저는 없다

<meter min="0" max="10"></meter>


폼 유효성 검사(입력값 검증)
HTML5 의 폼은 자체적으로 입력 값 검증을 수행하도록 되어 있다
예를 들어 <input type=email>에 입력된 값이 이메일 패턴과 다를 경우 폼은 전송되지 않고 에러 메시지를 표시해 준다. 그리고 입력 양식에 required 속성을 부여하면 빈 값이 허용되지 않는다
또한 입력 양식에 pattern 속성으로 정규표현식으로 입력 패턴을 지정할 수 있다
지정한 패턴과 다른 형태의 값은 입력이 허용되지 않는다

ex) 우편번호 패턴
<input type="text" name="postCode" pattern="/^\d{3}-?\d{3}$/" title="123-123">

이전 환경에서는 이 모든 것을 스크립트 영역에서 별도로 처래해 줘야 했다

<form action="demo_form.asp" method="get">
  First name: <input type="text" name="fname" required /><br />
  Last name: <input type="text" name="lname"  /><br />
  E-mail: <input type="email" name="email" /><br />
  <input type="submit" />
</form>


(오페라)
 
이렇듯 폼이 자동으로 입력 값 유효성을 검사하는 것은 폼에 validate 가 기본적으로 활성화되었기 때문이다. 만일 폼의 자동 유효성 검사를 꺼두고 싶다면 폼에 novalidate 를 부여하면 된다

<form novalidate action="demo_form.asp" method="get">
   .....


개선된 폼 이벤트(Event)
HTML5 에서는 폼과 관련한 몇 가지 이벤트도 추가되었다
대표적으로 forminput 이벤트와 formchange 이벤트를 들 수 있다

이 이벤트들은 폼의 하위 요소가 아닌, 폼 자체에 걸 수 있는 이벤트로써 폼에 포함되어 있는 각종 요소들을 특정 이벤트로 연계시키기 좋은 구조를 제공한다

간단한 예를 보자
폼에 3개의 요소가 있고 특정 한 요소의 입력 변화를 감지해 다른 두 요소를 제어하는 샘플이다
<form onforminput="ta2.value = ta1.value;textLength.value=ta1.value.length;">
  <textarea id="ta1"></textarea> <br>
  글자 복사 ↓<br> 
</form

<textarea id="ta2"></textarea>
글자 수:<output id="textLength"></output>

폼에 forminput 이벤트를 구현하여 글이 입력될 때 마다 아래로 복사하고 글자 수를 표시하는 코드이다
참고로 코드에서는 폼에 하나의 요소(textarea)만 존재하지만, forminput 이벤트는 폼에 포함된 모든 요소의 변화를 감지한다. 아래는 실행화면이다
(오페라)

이렇듯 forminput, formchange 이벤트를 이용하면 폼의 각 요소를 쉽게 연계할 수 있다

'모바일 > HTML5' 카테고리의 다른 글

[HTML5] Server-Sent Events  (4) 2010.08.31
[HTML5] Notifications (알림)  (2) 2010.08.30
HTML5 관련 유용한 레퍼(참조) 사이트  (0) 2010.08.26
[HTML5] Video & Audio  (6) 2010.08.24
[HTML5] Canvas  (3) 2010.08.19