Archive for July, 2006

Textarea 크기 자동조절

※ 이 팁은 javascript framework 인 prototype.js 가 필요합니다.

예전에 비슷한 것을 만든 적이 있는데, 이번엔 조금 다른 방식으로 접근해봤습니다.
이번엔 “예측” – 즉, 때려맞추기 방법을 썼습니다. -_-;;

구글 녀석들이 조금 비슷하게 쓰는 것 같길래… 히~
클래스 생성하고, Event 를 attach 하는 쪽에서 prototype.js 에 의존적입니다. protoytpe.js 를 쓰기 시작한지 1년이 조금 넘은 것 같은데, 쓰면 쓸수록 너무 편합니다. 1년 사이에 만들어낸 스크립트들이 거의 다 이넘을 기반으로 하고 있어서 공개도 안하고 있다가… 그나마 이넘은 의존성이 적어서 쉽게 수정하실 수 있을 것 같아 공개합니다. ^^
[code type=js]
/*
* textarea auto expander by gony (http://mygony.com)
* 2006. 7. 10
* dependent on prototype.js (http://prototype.conio.net)
*/

var Textarea = Class.create();
Textarea.prototype = {
.initialize : function(obj) {
..this._obj = $(obj);
..this._fwidth = 0;
..this._fheight = 0;
..this._minRows = parseInt(this._obj.rows); // minimum size

..if (isNaN(this._minRows)) this._minRows = 5;

..Event.observe(this._obj, 'focus', this.init.bind(this));
..Event.observe(this._obj, 'keydown', this.onKeydown.bindAsEventListener(this));
..Event.observe(this._obj, 'keyup', this.onKeyup.bindAsEventListener(this));
.},
.init : function() {
..if (this._fwidth != 0) return;
..var container = document.createElement('SPAN');
..$(container).setStyle({
...'visibility' : 'hidden',
...'padding' : '0px',
...'fontSize' : this._obj.style.fontSize==''?'9pt':this._obj.style.fontSize
...});

..document.body.appendChild(container);
..container.innerHTML = 'a'; // for width of 1 byte

..this._fwidth = container.offsetWidth;
..this._fheight = container.offsetHeight;

..document.body.removeChild(container);
.},
.getBytes : function(str) {
..var code,bytes = 0;
..var len = str.length;

..for(var i=0; i < len; i++) {
...code = str.charCodeAt(i);
...if (code > 128) bytes += 2;
...else if (code > 63 && code < 91) bytes += 1.5;
...else bytes += 1;
..}

..return bytes;
.},
.onKeydown : function(event) {
..if (event.keyCode == Event.KEY_RETURN || (event.ctrlKey && event.keyCode == 86)) {
...// enter key or Ctrl+V
...this.fitSize();
..}
.},
.onKeyup : function(event) {
..var k = event.keyCode;
..if (k < 65 || (k > 90 && k < 97) || (k > 122 && k < 127)) {
...this.fitSize();
..}
.},
.fitSize : function() {
..var str = this._obj.value + ' ';
..var strings = str.split(/\n/g);
..var bpl = Math.floor(this._obj.offsetWidth / this._fwidth); // bytes per line
..var lines = 0;

..for(var i=0; i < strings.length; i++) {
...if (this.getBytes(strings[i]) < bpl) {
....lines++;
...} else {
....lines += Math.ceil(this.getBytes(strings[i])/bpl);
...}
..}

..lines += 2;
..if (lines < this._minRows) {
...this._obj.rows = this._minRows;
..} else {
...this._obj.rows = lines;
..}

..this._obj.focus();
.}
}
[/code]

예제는 아래 링크를 클릭하세요(예고없이 사라질 수 있습니다. 제가 잘 날려먹어서...ㅠ_ㅠ)
http://funnyfog.net/textarea.html

아... 그리고... 말 안해도 IE, FF에 잘~ 호환되는 거는 아시죠? ^^

[PHP] 배열의 활용

내가 생각하는 PHP는 배열의 언어이다.
내부 소스를 들여다보지는 않았지만, 본 사람의 말에 의하면 내부적으로는 클래스 마저도 배열로 처리하고 있다고 하니 말 다한거나 마찬가지다(실제로 PHP 코딩할 때는 배열로 처리한다).

그래서인지 PHP에 있는 함수중에는 유난히 배열관련 함수가 많다.
PHP의 함수 인덱스 분류중 어느 섹션보다도 배열관련 함수가 많으며, 따라서 이들을 잘 활용한다면 코딩량을 확 줄일 수 있을 뿐더러 보다 직관적인 코드를 작성할 수 있다.

※주의 : 이 팁은 필자의 코딩스타일을 설명한 글이므로, 일반적이지도 않고 절대적이지도 않습니다. 자신에게 맞는 코딩스타일을 찾는 것이 가장 중요하며 거기에 도움이 되고자 하는 것일뿐입니다. ^^

1. enum타입과 유효성 검사
C, C++등의 언어에 있는 enum은 특정 타입에 미리 정해둔 몇가지 값 이외의 다른 값을 사용할 수 없도록 한다. 입력값에 잘못된 값이 오는 일도 없을 뿐더러 내부적으로는 정수형을 쓰면서도 실제 코딩시에는 사람이 이해하기 편한 형태로 쓸 수 있기때문에 편하게 사용할 수 있다. 비록 PHP에는 이런 enum 타입이 없지만, define 등으로 비슷하게 사용할 수 있다.
[code type=php]
<?php
$i = 0;
define('ALLOW_NONE', $i++);
define('ALLOW_MEMBER', $i++);
define('ALLOW_ALL', $i++);

$allow_type = array(ALLOW_NONE, ALLOW_MEMBER, ALLOW_ALL);

. . . .

. . . .

. . . .
// 유효성 검사
// 권한 허용의 값이 올바르지 않으면 [허용안함]으로 지정한다.
if (!in_array($allow_value, $allow_type)) $allow_value = ALLOW_NONE;
?>[/code]

꼭 enum형처럼 사용할 필요는 없다. 아래처럼 입력값에 대한 유효성검사의 용도로 써도 된다.

[code type=php]
<?php
$allow_search_type = array('name','user_id','title','content');
// 전달된 검색 타입이 올바르지 않을 경우 [제목검색]으로 지정한다.
if (!in_array($_GET['s_type'], $allow_search_type)) $_GET['s_type'] = 'title';
?>[/code]


2. OR 비교연산 대용
위와 같은 방법으로 OR 연산을 대신해서 사용할 수도 있다.
[code type=php]if ($val == 'test' || $val == 'question' || $val == 'answer')
.echo 'OK';[/code]

위와 같은 코드는

[code type=php]if ( in_array($val, array('test','question','answer')) )
.echo 'OK';[/code]

와 같이 변경할 수 있다. 위와 같이 코딩하게되면 또 다른 값을 추가할 때 코딩해야할 양이 더 많을 뿐만 아니라 값이 여기저기 나누어져있어 가독성에서도 보기가 힘들지만 아래와 같은 코딩을 하면 쉼표와 값을 입력해주는 것만으로도 새로운 조건을 추가할 수 있다. 또한 AND 와 OR가 복합적으로 연결되어있어 가독성이 어려운 코드에서도 보다 나은 가독성을 보장해줄 수 있다.

3. 일괄 적용
간단한 경우를 생각해보자. 출력할 문자열들에 대해서 htmlspecialchars 라는 함수를 적용시키고 싶다고 하자. 우선 보통이라면 다음과 같이 코딩할 수도 있다.
[code type=php]
$text_a = htmlspecialchars($text1);
$text_b = htmlspecialchars($text2);
$text_c = htmlspecialchars($text3);
$text_d = htmlspecialchars($text4);
$text_e = htmlspecialchars($text5);
[/code]
이것을 배열을 이용해서 코딩하면 다음과 같이 표현할 수 있다.
[code type=php]
$text_arr = array($text1, $text2, $text3, $text4, $text5);
list($text_a, $text_b, $text_c, $text_d, $text_e) = array_map('htmlspecialchars', $text_arr);
[/code]
물론, 아래쪽의 코딩이 함수를 몇번 더 거치기 때문에 효율이 떨어진다고 반박하는 사람도 있을 것이다. 하지만, 여기에 값이 더 추가되거나 변경된다고 할 경우 혹은 함수를 하나 더 적용해야할 경우를 생각해본다면, 유지보수라는 측면에서는 충분히 이득이 있다. 게다가 직접 테스트해보지는 않았으나 이런 식의 사용을 한 프로세스에서 수천번씩 하는 것도 아닌 이상, 성능에의 손실은 거의 없다고 보아도 될 것이다.

구글의 오픈소스 호스팅

구글이 Sourceforge 와 같은 오픈소스 호스팅 서비스를 시작했습니다. 구글다운 상당히 단순한 UI를 보여주고, 역시 다른 서비스와 마찬가지로 gmail 로 통합되는 구글 계정만 있다면 즉시 사용할 수 있습니다.

Google code
등록만 되어있다면 누구나 프로젝트를 개설할 수 있는데, 상당히 단순한 형태의 정보만을 요구합니다.

Google code

sf 의 잦은 다운과 느린 속도에 불만이 많았는지 /. 에서는 반기는 분위기라고 합니다. ^^
Subversion 과 Issue Tracker 정도의 단순한 기능만 있지만 사실 이거면 충분하지 않나 싶습니다. 일단 검색속도면에서는 sf보다 훨씬 좋네요. 구글쪽에서는 소스포지와 경쟁할 생각이 없다고는 하지만 그건 구글이 결정하기 보다는 사용자들이 결정하게 될 것 같습니다.

Page 1 of 512345