2010-03-24

SMS 길이 체크하기

오늘 웹에서 SMS 전송 모듈을 작성했다.

  • 메시지 박스는 textarea로 구현한다.
  • SMS는 최대 80 바이트까지만 전송할 수 있다.
  • 사용자가 메시지 박스에 텍스트를 입력하면 실시간으로 하단에 텍스트 바이트 크기를 보여준다.

HTML 구조는 다음과 같다.

<div>
    <textarea id="text" rows="4" cols="30"></textarea>
    <br/>
    <span id="length"></span>
</div>


그리고 onkeydown(up, press) 이벤트로 바이트 크기를 체크하려는데 파이어폭스에서는 한글 입력에 대해서는 이 이벤트가 발행하지 않았다 ㅠㅠ


어쩔 수 없이 스케줄러(setInterval)로 백그라운드에서 바이트 크기를 처리하기로 했다. 약간의 딜레이를 감수하면서...

Prototype을 사용했다. 코드는 단순하지만 Prototype에 익숙하지 않으면 이해하기 쉽지 않다;;


우선 문자열 바이트 크기를 체크하는 함수를 String 클래스에 추가했다.

Object.extend(String.prototype, {bytes: function() {
    var source = this;
    var result = 0;
    for (var i = 0; i < source.length; i++) {
        result += (source.charCodeAt(i) > 128) ? 2 : 1;
    }
    return result;
}});

  • 기존 클래스에 메소드를 추가할 수 있다는 것이 자바 스크립트와 같은 언어의 장점이다.
  • Object.extend는 Prototype이 제공하는 메소드이다.
  • bytes라는 이름으로 메소드를 추가했다.

그리고 LengthChecker 클래스를 다음과 같이 작성했다.

var LengthChecker = Class.create({
    initialize: function(target, handler) {
        this.target = $(target);
        this.handler = handler;
    },
    apply: function() {
      this.target.observe("focus", this.start.bind(this));
      this.target.observe("change", this.stop.bind(this));
      this.target.observe("keydown", this.callback.bind(this));
    },
    start: function() {
        this.executer = new PeriodicalExecuter(this.callback.bind(this), 1);
    },
    stop: function() {
        this.executer.stop();
        this.callback();
    },
    callback: function() {
        this.handler($F(this.target).bytes());
    }
});

  • apply 메소드에서 observe 메소드로 target에 foucs, change, keydown 이벤트를 등록했다. focus에서 스케줄러를 시작하고, change 메소드에서 스케줄러를 정지한다. 한글이 아닌 경우에는 문제가 없기 때문에 keydown 이벤트도 등록하였다.
  • Protoype이 제공하는 PeriodicalExecuter는 setInterval을 이용한 스케줄러이다.


사용 방법은 다음과 같다.

new LengthChecker("text", function(length) {$("length").update(length);}).apply();


LengthChecker 클래스 생성자의 파라미터는 다음과 같다.

  • target: 대상 textarea 요소(혹은 id)
  • handler: 주기적으로 호출되는 함수. 이 함수의 첫번째 파라미터는 target에 입력한 텍스트의 바이트 크기이다.
LengthChecker 객체를 생성한 후 apply 메소드를 호출하면 백그라운드에서 바이트 크기 체크 작업이 이루어진다.

  • Prototype 라이브러리 PeriodicalExecuter는 최소 1초 단위로 반복된다. 딜레이를 최소화하려면 setInterval 함수를 사용하야 한다.

No comments: