jquery.mobile-1.2.0.js


jquery mobile (현재 1.2.0 버젼)에서 터치와 관련되어 제공되는 기본 이벤트는 다음과 같다.


touchstart, touchmove, touchend, tap, taphold, swipe, swipeleft, swiperight, scrollstart, scrollstop


이중에 swipeleft 와 swiperight 이벤트는 터치를 좌우로 할 경우 발생하는 이벤트인데, 기본 jquery mobile 에서는 위 아래에 대한 이벤트가 없다. 따라서, jquery mobile 소스를 다음과 같이 변경하면 swipeup 과 swipedown 을 직접 구현하여 작성할 수 있다.


jquery.mobile-1.2.0.js 파일을 다음과 같이 수정한다.


다음 소스를 찾아서

$.each( ( "touchstart touchmove touchend " +

"tap taphold " +

"swipe swipeleft swiperight " +

"scrollstart scrollstop" ).split( " " ), function( i, name ) {


$.fn[ name ] = function( fn ) {

return fn ? this.bind( name, fn ) : this.trigger( name );

};


// jQuery < 1.8

if ( $.attrFn ) {

$.attrFn[ name ] = true;

}

});


다음과 같이 바꾼다.


$.each( ( "touchstart touchmove touchend " +

"tap taphold " +

"swipe swipeleft swiperight swipeup swipedown" +

"scrollstart scrollstop" ).split( " " ), function( i, name ) {


$.fn[ name ] = function( fn ) {

return fn ? this.bind( name, fn ) : this.trigger( name );

};


// jQuery < 1.8

if ( $.attrFn ) {

$.attrFn[ name ] = true;

}

});


또 다음 소스를 찾아서 

$.each({

scrollstop: "scrollstart",

taphold: "tap",

swipeleft: "swipe",

swiperight: "swipe"

}, function( event, sourceEvent ) {


$.event.special[ event ] = {

setup: function() {

$( this ).bind( sourceEvent, $.noop );

}

};

});


다음과 같이 바꾼다.

$.each({

scrollstop: "scrollstart",

taphold: "tap",

swipeleft: "swipe",

swiperight: "swipe",

swipeup: "swipe",

swipedown: "swipe"

}, function( event, sourceEvent ) {


$.event.special[ event ] = {

setup: function() {

$( this ).bind( sourceEvent, $.noop );

}

};

});


마지막으로 다음 소스를


$this.bind( touchMoveEvent, moveHandler )

.one( touchStopEvent, function( event ) {

$this.unbind( touchMoveEvent, moveHandler );


if ( start && stop ) {

if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&

Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold && Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {

start.origin.trigger( "swipe" )

.trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );

}

}

start = stop = undefined;

});


다음과 같이 바꾼다.

$this.bind( touchMoveEvent, moveHandler )

.one( touchStopEvent, function( event ) {

$this.unbind( touchMoveEvent, moveHandler );


if ( start && stop ) {

var x = Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ), 

y = Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ), 

callback = '';

if ( stop.time - start.time < $.event.special.swipe.durationThreshold) {

if(x > 30 && y < 75) {

callback = ( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );

}else if( x < 75 && y > 30 ) {

callback = start.coords[1] > stop.coords[1] ? "swipeup" : "swipedown";

}

}

if(callback) start.origin.trigger( "swipe" ).trigger( callback );

}

start = stop = undefined;

});


이글은 http://forum.jquery.com/topic/add-swipe-up-down-to-jquerymobile-1-0-1-my-method 이 글에서 참조되었다.

Dojo Toolkit 이 제공하는 위젯들을 굉장히 쓸만한다.
대표적으로 사용되는 위젯들은 dijit.form 위젯들인데, Textbox, Date, Time 등 폼에 관련된 많은 것들이 깔끔하고 편하다. 예전에 동적으로 Tree 를 생성하는 글을 작성한 바있는데, 이번엔 정적/동적 및 동적으로 만들어진 widjet 을 prototype 으로 다루는 방법에 대해서 설명해보겠다. 물론... 이 글을 쓸만한 가치가 없을 정도로 쉽다.

1. 동적으로 위젯 생성하기
스크립트 로드는 당연한 일이므로 작성하지 않는다.
동적이든, 정적이든 해당 위젯을 임포트해야한다.
여기선 버튼을 예로 들어보겠다.

{{{
// import dojo class
dojo.require("dijit.form.Button");

// create object
var button = new dijit.form.Button('clickMeButton', {
label:'눌러주세요',
onClick:function() {
alert('Thank you, touch me.^^');
}
});
}}}

// append document
$('buttons').appendChild(button.domNode); // 이게 중요하다.
// button 자체는 dojo 에서 몇개의 element 감싸버리기 때문에 모든 dijit widjet 을 특정 엘리먼트에 포함시키려 한다면 domNode 속성을 이용하여야한다.

<div id="buttons">
</div>

2. 정적으로 추가하기
정적으로 추가하는 것은 더욱 쉽다.

// import
dojo.require("dijit.form.Button");
dojo.require("dojo.parser"); // 정적 파싱은 이 부분이 필요하다.

<div id="buttons">
<button id="clickMeButton" dojoType="dijit.form.Button" onClick="alert(Thank you, touch me);">날 클릭해줘요</button>
</div>

3. 왠만하면 정적으로 추가하는게 보기도 편하고 좋다.
그러나 ajax 를 이용한다든지 하여서 동적으로 페이지를 인클루드하면 도조 파싱이 이미 끝난지라 소용이 없다.
따라서 로딩을 다 한후에는 다시 파싱을 할 필요가 있다.

다음 예제는 prototype.js 의 Ajax 기능을 이용하여 buttons 레이어에 동적으로 페이지를 로드한 후, dojo 파싱을 하는 예제다.
new Ajax.Updater($('buttons'), "/button.tpl", {
                onComplete:function(request) {
                    dojo.parser.parse(dojo.byId('buttons'));
                }
            });

야호! 이제 도조랑 프로토타입으로 못할 짓이 없다!
prototype.js 와 script.aculo.us 로 가장 아주 간단한 drag & drop 을 구현해보겠다.
라이브러리는 다음 사이트에서 내려받을 수 있다.
prototype.js : http://prototypejs.org
scriptaculous.js : http://script.aculo.us

1. 우선. 라이브러리를 로드한다.

<script type="text/javascript" src="${CONTEXT }/lib/prototype.js"></script>

<script type="text/javascript" src="${CONTEXT }/lib/scriptaculous/scriptaculous.js? effects,dragdrop"></script>



2. 드래그 가능한 아이템을 객체 생성(instant화) 시킨다.
이것만으로 화면에서는 해당 아이템이 드래그 되는걸 확인할 수 있다. 오오!


new Draggable($('DRAG_ITEM_ID')); // DRAG_ITEM_ID 라는 id 를 가진 element

 
그러나, 대개 이렇게 id 마다 지정은 안할 테고 뭉탱구리로 드래그 가능한 아이템을 등록할거다.

$$('.draggable').each(function(item) {

  new Draggable(item);

});


자, 이제 'draggable' 이라는 클래스를 가지는 모든 element 가 드래그 가능하게 되었다.


3. 특정한 드래그 가능한 아이템을 특정 구역에 떨구었을(drop) 경우, 액션을 취하고 싶다면 다음을 추가한다.
여기서 accept 속성은 받아들일 아이템의 클래스명이다.

Droppables.add('shopping_cart', {

  accept: 'product',

  onDrop: function(element) {

    alert(element.innerHTML);

  }

});


이제 shopping_cart 라는 id 를 가진 element 위에 product 클래스를 가진 element 을 드랍시키면 그 내용이 출력된다.

아래는 이 예제를 테스트할 수 있는 전문이다.

<html>

<head>

<title>File Upload Exmaple Using Prototype Javascript</title>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>DND Test</title>

<script type="text/javascript" src="${CONTEXT }/lib/prototype.js"></script>

<script type="text/javascript" src="${CONTEXT }/lib/scriptaculous/scriptaculous.js?dragdrop"></script>

<script type="text/javascript">

document.observe("dom:loaded", function() {

       // drop 영역 구현

       Droppables.add('shopping_cart', {

             accept: 'product',

             onDrop: function(element) {

                    alert(element.innerHTML);

             }

       });

      

       // drag item 등록

       $$('.draggable').each(function(item) {

             new Draggable(item);

       });

});

</script>

<style type="text/css">

#shopping_cart {width:200px;height:200px;border:4px solid red;}

.product {border:2px solid blue;display:inline;}

</style>

</head>

<body>

 

<div id="shopping_cart">

       <h2>여기는 쇼핑 카트입니다. 제품을 올려놓으세요</h2>

</div>

 

<div id="products">

       <div class="product draggable">제품1</div>

       <div class="product draggable">제품2</div>

       <div class="product draggable">제품3</div>

</div>

 

</body>

</html>





프로토타입팀과 타큘러스에게 감사를. ㅎ



문서 내 전체 폰트 변경 스크립트를 만들어봤다.
prototype.js 기반이고, body 태그를 제외한 하위 태그는 고정 사이즈가 아닌 비율로 된 폰트 사이즈를 사용해야한다.
즉, font-size:9pt, 12px, .. 등은 사용하지 않아야하며,
font-size:1.0em, medium, large, 125% 등을 사용해야한다.
나는 em 을 주로 사용한다.
참고로 12px(9pt)의 기본 em 사이즈는 0.75em 이다.

사용법.

<body>

  <span onclick="FontResizer.increase();">Size Up!</span>

  <span onclick="FontResizer.decrease();">Size Down!</span>

</body>


/**

 * Document Font Resizer

 * resize document fonts by font-size of body tag

 * @author Pyun Hyun-Jang (kernel8086@gmail.com)

 */

var FontResizer = {

       ratio:0.25, // increase,descrease ratio

       _list:null,

       _index:0,

       _init:function(s, h) {

             FontResizer._list = new Array();

             FontResizer._list[0] = h;

             FontResizer._index = 0;

             FontResizer._list[FontResizer._index] = s;

       },

       _findRoot:function(){

             return $$('body')[0];

       },

       /**

        * increase font size

        */

       increase:function() {

             var s = FontResizer._findRoot().getStyle('font-size');

             var h = s.substr(0, s.indexOf("px"));

             var resize = Math.round(h * (1 + FontResizer.ratio));

             resize += "px";

             if(FontResizer._list == null) {

                    FontResizer._init(s, h);

             }else {

                    if(FontResizer._list[FontResizer._index + 1]) {

                           resize = FontResizer._list[FontResizer._index +1];

                    }else {

                           FontResizer._list[FontResizer._index] = s;

                    }

             }

             FontResizer._index ++;

             FontResizer._findRoot().setStyle({'fontSize':resize});

       },

       /**

        * decrease font size

        */

       decrease:function() {

             var s = FontResizer._findRoot().getStyle('font-size');

             var h = s.substr(0, s.indexOf("px"));

             var resize = Math.round(h * (1 - FontResizer.ratio));

             resize += "px";

             if(FontResizer._list == null) {

                    FontResizer._init(s, h);

             }else {

                    if(FontResizer._list[FontResizer._index- 1]) {

                           resize = FontResizer._list[FontResizer._index -1];

                    }else {

                           FontResizer._list[FontResizer._index] = s;

                    }

             }

             FontResizer._index--;

             FontResizer._findRoot().setStyle({'fontSize':resize});

       }

}

요즘 prototype 관련 글에 prototype.js 올바르게 사용하자라는 글이 돌아다닌다.
대부분 맞는것이기에 하다.
그러나. 객체지향적인것도 좋기야 하지만, 가장 중요한건 얼마나 명시적으로 다가오냐이다.

이벤트 등록에 관해서 그 부분이 두드러진다.

소스 여기저기서 객체마다 observe 하는게 나을까.
Event 구역에서 다 등록하는게 나을까. 흠

..
$('a').observe('click', function(...));
..
$('b').observe('click', function(...));
..
$('c').observe('click', function(...));
..

vs

Event.observe('a', 'click', function(...));
Event.observe('b', 'click', function(...));
Event.observe('c', 'click', function(...));

Event 글자가 튀어서 그런지 몰라도 Event 가 낫단말이지..

그리고 그 무엇보다도 prototype.js 1.6.3 버젼에서 element.observe 함수는 언제나 동적하지 않는다.
IE 에서 동적으로 생성된 element 에 observe 를 실행하면 오류가 난다.
FF에서는 잘되지만.

var item = Builder.node('span', {className:'button'}, name);

var item = new Element('span', {className:'button'}).update(name);

item.observe('click', func); // ie에서 오류

Event.observe(item, 'click', func); // ok


특정 부분에 대해 ajax 로 내용(e.g. HTML 조각)을 받아와 변경하는 방법이다.
prototype.js 를 사용했다. 매우 간단하다.

/**

 * @param container* Ajax 로부터 넘어온 text 결과를 반영할 element

 * @param url* 읽어드릴 url       

 * @param ajax 호출시 넣어줄 option object

 * @author 편현장(slothink)

 */

new Ajax.Updater(container, url, [,options]);


매우 간단하다. 그저 url 읽어와서 container 에 집어넣기만 하면된다.
container 는 dom element 의 id 값을 넣어주도 되고, $() 함수를 이용하여 element 확장한 오브젝트를 넣어줘도 된다.
아래에 예제를 포함했다.

var params = $H();

params.set('code', code);

new Ajax.Updater('detailProperty', '<c:url value="/document/contents.type.tpl" />', {

       method: 'get',

       parameters:params.toQueryString(), // serialize

       });

 


DojoToolkit.org 의 가이드북에 제공된 방법은 정적인 방법이다. [이전 글 참조]
(<div >박스에 설정해놓고 문서 로딩시에 트리를 구성하는 방식)

이제 지금 동적 트리 구성하기에 대해서 설명하겠다.
문서 찾기 힘들어서, 소스 분석을 해야했다니..쩝-_-;

1. 트리 구성에 필요한 라이브러리(?)를 불러들인다. dojo.require
2. 데이타 저장소를 구현한다. 예제로 든 소스는 json 을 출력하는 url 이다.
3. 모델을 생성하고, 기본 트리 설정 및 저장소를 설정한다.
4. 트리를 생성하며, 이전에 생성한 모델을 등록하며, 트리조작에 대한 옵션을 설정한다.
model 을 제외하고는 모두 옵션이다.
5. 만들어진 트리를 문서에 등록한다.
6. 등록한 트리를 실행하여, 실제 데이타를 가져와 화면을 구성한다.


<script language="javascript" someProperty="text/javascript">

// 1. Load Tree

dojo.require("dojo.data.ItemFileReadStore");

dojo.require("dijit.Tree");

 

dojo.addOnLoad(function(){         

       // 2. create data store

       var myStore = new dojo.data.ItemFileReadStore({url:'<c:url value="/category/struct.json" />'});           

       // 3. store 및 tree 설정

       var myModel = new dijit.tree.ForestStoreModel({

             store: myStore,

             //query: {type:'continent'},

             rootId: "__temp_id__",

             rootLabel: "트리",

             childrenAttrs: ["children"]

       });

      

       // 4. create Tree

       var tree = new dijit.Tree({

             model: myModel, /* 필수 */

             showRoot :false,

             getIconClass : function(item) {

                    if(item && this.model.store.isItem(item)) {

                           if(this.model.store.hasAttribute(item, "type")) {

                                 return  this.model.store.getValue(item, "type");

                           }

                    }

                    return;

             },

             getLabelClass : function(item) {

                    if(item && this.model.store.isItem(item)) {

                           if(this.model.store.hasAttribute(item, "type")) {

                                 return  this.model.store.getValue(item, "type");

                           }

                    }

                    return;

             },

             onClick : function(item) {

                    if(item && this.model.store.isItem(item)) {

                           alert(this.model.store.getValue(item, "id"));

                    }

             }

       });

      

       // 5. 문서에 등록하기      

           

       dojo.body().appendChild(tree.domNode); // dojo style

       // $('viewTree').insert({'top':tree.domNode}); // prototype.js style. 나는 dojo toolkit 보다 prototype.js 를 더 선호한다.

       // 6. 트리 실행

       tree.startup();

});

</script>


다음에는 동적으로 자식을 생성해보겠다. 언제 할련지는..-_-;;
복잡한 dojo 같으니. 그냥 prototype.js 로 내 트리를 만들어버릴까?



prototype.js 의 event 부분에 대한 설명을 보았다면, 이미 알고 있는것이겠다만(사실 프로토타입은 이런 글 남겨서 기록하기엔 너무 쉽다 =ㅅ=;) 마우스의 현재 좌표 얻는 방법을 알아보고자 한다.

1. 마우스의 현재 좌표를 알기 위해서는 우선 이벤트를 발생시킨다.


Event.observe('btOpen', 'click', getCordinatesByEvent);

Event.observe('btOver', 'over', getCordinatesByEvent);


이 소스는
btOpen 의 id 를 갖는 엘리먼트를 클릭할 경우 getCordinatesByEvent 객체(Function)를 실행한다.
btOver 의 id 를 갖는 엘리먼트 위에 마우스를 올릴경우 getCordinatesByEvent 객체(Function)를 실행한다.

2. 발생시킨 이벤트로부터 x, y 좌표를 얻는다.

function getCordinatesByEvent(event) {

       var cordinates = {

             x:event.pointerX(),

             y:event.pointerY()

       };

}


브라우저 종류마다 event 로부터 좌표값을 얻는것은 상이하다. 따라서 prototype.js 에서 prototype 된 함수를 이용해 동일한 결과를 얻을 수 있다.




파이어폭스 3 이전 버젼을 사용할 때는 문제가 안되었던 부분인데 파이어폭스3를 사용하면서, 파이어폭스가 강제로 캐싱을 하고 있는것을 발견했다.
response 에서 더욱 적절하게 no-cache 를 적용할 수 있으면 좋겠지만, 아직 그것에 대해서 정확하게 해결하지 못했다. (파이어폭스 1,2는 잘되지만)
여하튼, 파이어폭스 3를 이용하여 개발하는 입장에서 변경된 소스가 즉각 변경되지 않는다는것은 매우 곤란했다.
그래서 ie 에서처럼 항상 페이지 리로드 옵션을 주려고 하는데 설정에서 아무리 찾아도 찾을 수가 없지 않은가?


이제 고민을 풀어보자.후후

1. 캐시 파일 제거하기
주소창에 about:cache 를 친다.
캐시 저장된 위치가 드러난다.
여기서 들어가서 삭제하면 된다.

2.캐싱 기능 끄기
주소창에 about:config 를 친다.
엄청나다. 이래서 설정에 없었던 것이다.
여기에서서 browser.cache.disk.enable;true 항목과 browser.cache.memory.enable;true 항목을 toggle 시켜서 false 로 변경한다.


대몬이라봐야 별거 없다.
1. 그저 PeriodicalExecuter 인스턴스를 생성하여, 일정시간(초단위) 마다 콜백함수를 호출하는 것뿐이다.
2. 그다음 실행.

구현 : prototype.js 1.6 버젼
이 예제는 0.1 초마다 'navi' 엘리먼트를 특정 위치에 재고정시키는 스크립트이다.

var navi = $('navi');

var daemon = new PeriodicalExecuter(function() {

    var want = 0; // for offset

    var top = navi.getStyle('top').replace("px", '');

    top = new Number(top);

    var toTop = navi.viewportOffset().top;

    if(toTop < 0) {

        toTop = top + toTop * -1;

    }else if(toTop > 0) {

        toTop = top - toTop;

    }else {

        toTop = top;

    }

    toTop += want;

    navi.setStyle('top:'+toTop+'px');  

    }, 0.1);

daemon.execute();


트리 위젯에서 노드를 선택할 경우에 기본적으로 나타나는 스타일은 span 의 dotted 속성 뿐이다.
따라서 각 노드에 클래스 지정을 한 경우 알아보기가 쉽지 않다. 더불어 이전 글에서 구현한 트리 탐색 기능의 경우 검색은 되었는데 도대체 뭔지 알아보는 것은 더 어렵다-_-;;

고로 이번엔 포커스가 잡힐 경우, 스타일을 변경하는 방법을 설명하고자 한다.

엄밀히 말하면 스타일을 변경하는 것이 아니라, 포커싱이 될 경우 스타일 클래스를 추가하고, 포커스 아웃(블러)가 될 경우, 추가한 클래스를 해제 시키는 것이다.

변경할 소스의 위치는 아래와 같다.

dojo/dijit/Tree.js

변경할 메써드는 dijit.Tree 클래스의 blurNode, _onTreeFocus 다.


_onTreeFocus: function(evt){
        var node = dijit.getEnclosingWidget(evt.target);
        if(node != this.lastFocused){
            this.blurNode();
        }
        var labelNode = node.labelNode;
        // set tabIndex so that the tab key can find this node
        labelNode.setAttribute("tabIndex", "0");
        dojo.addClass(labelNode, "dijitTreeLabelFocused"); // 이 스타일은 tundra.css 에 정의되어있다. tundra를 사용한다면..
        dojo.addClass(labelNode, "treeEntryFocus"); // 이곳에 원하는 클래스를 지정한다.
        this.lastFocused = node;
    },

blurNode: function(){
        // summary
        //    Removes focus from the currently focused node (which must be visible).
        //    Usually not called directly (just call focusNode() on another node instead)
        var node = this.lastFocused;
        if(!node){ return; }
        var labelNode = node.labelNode;
        dojo.removeClass(labelNode, "dijitTreeLabelFocused");
        dojo.removeClass(labelNode, "treeEntryFocus"); // 이곳에 제거할 클래스를 지정한다.
        labelNode.setAttribute("tabIndex", "-1");
        this.lastFocused = null;
    },
...

그러나. 이것보다 더 쉬운 방법은..
.tundra .dijitTreeLabelFocused 스타일 클래스를 오버라이딩 하는것이다!

왜 진작에 스타일이 있을거라고 생각하지않고 소스를 탐색했는지.-_ㅜ;


3번의 글을 거쳐, 트리 위젯에 대해 소개 및 추가 기능을 구현해보았다.
더 필요한 기능이 있을려나..?

dojotoolkit 에서 지원하는 tree dijit 의 기본 구현으로는 특정 노드를 검색하지 못한다.
이것의 구현은 트리를 상속받아 각각의 엔트리에 패스를 입력하며, 상위로부터 패스를 따라 expand 하는 방식으로 구현할 수 있다.

1. 트리 생성시 패스 정보를 기억하는 트리 구현
dojo/dijit/Tree.js

dojo.declare(
 "AdvancedTree",
 dijit.Tree,
{
 path: '',
 getPath: function (node, separator) {
  var path = separator;
  do {
   path = separator + this.tree.store.getIdentity(node.item) + path;
   node = node.getParent();
  } while ('dijit._TreeNode' == node.declaredClass);
  return path;
 },
 expander: function (node)
 {
  if (node.declaredClass == 'dijit._TreeNode') {
   dojo.connect(node, 'addChild', this, 'expander');
  }
  var nodePath = this.getPath(node, '/');
  if ((this.path.substr(0, nodePath.length) == nodePath) && node.isFolder) {
   this._controller._expand(node);
  }
 },
 addChild: function ()
 {
  dijit.Tree.prototype.addChild.apply(this, arguments);
  this.expander(arguments[0], 1);
 }
});

2. 검색


function focusTo(parent, findPath) {
 if(findPath != undefined && findPath != null) {
  var paths = findPath.split("/");
  var findId = paths[1];
  var startOffset = findPath.indexOf("/", 1);
  var findChildPath = null;
  if(startOffset > 0) {
   findChildPath = findPath.substr(startOffset);
  }
 
  contentsTree._expandNode(parent);
  var children = parent.getChildren();
  for (var j = 0; j < children.length; j++) {
   var child = children[j];
   if(findId == child.item.id) {
    contentsTree.focusNode(child);
   
    if(findChildPath != null) {
     focusTo(child, findChildPath);
    }
   }
  }
 }
}

3. 호출

focusTo(contentsTree, toPath);
// focustTo(contentsTree, '/1/234/523');


트리 화면 표현은 이전 글(slothink.tistory.com/24)과 동일하다. 다만 dojoType 속성을 dijit.Tree 가 아니라, AdvancedTree 를 구현하면 된다.


..그나저나 도조 한글 포럼은 없는것인가? 힘들군하;

  1. 2008.03.20 14:14

    비밀댓글입니다

    • BlogIcon slothink 편현장 2008.03.23 00:57 신고

      오. 첫번째 코멘트입니다.
      이 감격..ㅠㅠ
      너무너무 기쁘군요 감사합니다 ㅋ

      저와 같이 괴로워 하시는 분이 계셨군요!
      더 글을 쓸 맛이 납니다. 더 많이 연구해서 올려야겠어요 ㅎ

      지금의 과제는 포커싱입니다.
      이걸로 노드 찾기는 잘 되는데..
      점선으로 포커스 맞춰주는건 티가 안나서 영 잘 안보인다는;;

      종종 들러주세요^^

  2. BlogIcon ^.^ 2009.04.11 22:51 신고

    저도 올리신글 가끔 읽고있는 독자(?) 인데~~...
    글들이 은근 재밌하다고나 할까..~~
    그럼 좋은글 부탁드려요..~~~

prototype.js 라이브러리를 이용하면, 문자열은 상속되어져 evalJSON 이라는 메서드가 추가된다.
이 메서드를 호출 하는 것으로 json 형식의 텍스트 문자열을 json 객체로 변환시킬 수 있다.
예를 들면 아래와 같다.

var text = "{data:[{id:1,value:2},{id:2,value:2}]";
var json = text.evalJSON();
alert(json.data[0].id);

그러나 문자열 데이타에 대해서 json 문자열이라는 것이 확신이 없을 경우, 메서드에 true 파라미터를 추가한다. Ajax를 통한 예제는 다음과 같다.
var form = $('viewForm');
   form.action = '<c:url value="/ipis/is_view/lock.json" />';
   form.request({
       method: 'post',
       enctype: "application/x-www-form-urlencoded",
       requestHeaders: {Accept: 'application/json'},
       onComplete: function(transport){
           var json = transport.responseText.evalJSON(true);
           if(json.data.result == "true") {
              document.location.reload();
           } else {
               alert(json.data.err.code + json.data.drr.message);
           }
       }
   });

prototype.js 를 이용하여 ajax 기법을 사용하는 방법을 소개해보자 한다.
prototype.js 에선 Ajax.Update 등 여러가지 방법이 있지만, 다 알필요는 없지 않은가?
내가 주로 사용하는 2가지 방법을 설명했다.

참고1. prototpye.js 에선 문서내 id 를 가진 오브젝트를 찾는 $ 유틸리티 함수를 제공한다.
참고2. xml2json 라이브러리는 xml 문서를 json 으로 변환시켜준다. (더 자세히)

1. form 안의 값들을 ajax 에 의해 전송하기
var form = $('categoryForm');
form.action = '<c:url value="/category/update.xml" />';
form.request({
    method: 'post',
    enctype: "application/x-www-form-urlencoded",
    onComplete: function(transport){
        var xml = transport.responseText;
        var json = xml2json.parser(xml);
        if(json.data.result == "true") {
            alert("success"}
        else {
            alert("error");
        }
    }
});


2. 파라미터를 집적 입력하여, 호출하기

var no = $('categoryForm').no.value;
new Ajax.Request('<c:url value="/category/delete.xml" />', {
    parameters: {"no": no},
    requestHeaders: {Accept: 'text/xml'},
    onSuccess: function(transport){
        var xml = transport.responseText;
        var json = xml2json.parser(xml);
        if(json.data.result == "true") {
             alert("삭제하였습니다");
         }else {
             alert("error");
         }
    }
});

dojo toolkit 버젼은 0.4, 1.0등이 있으며, api 방식이 상이하다.
앞으로의 dojo toolit 설명은 1.0 기준으로 작성한다.


트리 위젯 추가하기

  1. dojo 스크립트를 로드한다.
    <script type="text/javascript" src="<c:url value="/inc/dojo/dojo/dojo.js" />" djConfig="parseOnLoad: true"></script>
  2. Tree 구성에 필요한 라이브러리를 로드한다.
    <script>
    dojo.require("dojo.data.ItemFileReadStore");
    dojo.require("dijit.Tree");
    dojo.require("dojo.parser");
    </script>
  3. css 로드
    <style type="text/css">
        @import "<c:url value="/inc/dojo/dijit/themes/tundra/tundra.css" />";
        @import "<c:url value="/inc/dojo/dojo/resources/dojo.css" />";
    </stye>
  4. <body>에 트리 위젯 엘리먼트 추가
    <div dojoType="dojo.data.ItemFileReadStore"
         url="tree.json" jsid="categoryData" />
    <div dojoType="dijit.Tree" store="categoryData" labelAttr="name" label="카테고리" />
  5. 데이타 저장소(ie. jsid:categoryData) 트리의 구조는 다음과 같다.
    1. 데이타는 json 으로 작성되어야 한다
    2. 루트 속성으로 identifer 값과 label 값을 지정한다.
      identifier 는 트리 요소의 고유 키로 사용되며 유니크해야한다.
      label 은 트리 표현시 각 요소의 표현될 이름으로 사용된다.
      이것에 대해 json 데이타의 어떤 속성과 매핑되는지 기술해야하는 것이다.
    3. 루트는 items 배열을 가지며 그 자식으로 실제 트리 구성 요소를 입력한다.
    4. 트리 구성 요소의 자식들은 children 이란 이름을 가지며, 자식 또한 배열이어야한다.
    { label: 'name',
      identifier: 'name',
       items: [
         { name:'Fruit', type:'category'},
         { name:'Cinammon', type: 'category',
           children: [
              { name:'Cinammon Roll', type:'poptart' },
              { name:'Brown Sugar Cinnamon', type:'poptart' },
              { name:'French Toast', type:'poptart' }
           ]
         },
         { name:'Chocolate', type: 'category'}
      ]
    }

클릭 이벤트

<div dojoType="dijit.Tree" store="categoryData" labelAttr="name" label="카테고리">
 <script type="dojo/method" event="onClick" args="item">
  alert(categoryData.getLabel(item)); // 이름 얻기
  alert(categoryData.getValue(item, "id")); // 기타 다른 속성 얻기, 식별자외에도 가능함
 </script>
</div>

클래스 변경

<div dojoType="dijit.Tree" store="categoryData" labelAttr="name" label="카테고리">
 <script type="dojo/method" event="getLabelClass" args="item">
  if (item != null && categoryData.getValue(item, "type") == 'category') {
   return categoryData.getValue(item, "type");
        }else {
      return "dir";
   }
   </script>
</div>
2가지 방법이 존재한다.
1. 문자열 직접 입력(Text, URL 선택)
2. select 하여 copy (실제로 마우스로 선택하여 ctrl + c 와같은 효과를 보인다)

1. 문자열 직접 입력 방법
window.clipboardData.setData("Text","저장된 글");
msdn 링크 : http://msdn2.microsoft.com/en-us/library/ms536744.aspx
이 방법은 ie 에서만 사용 가능하다

2. select 하여 copy 방법
<script language="javascript" type="text/javascript">
    function copy_select(s){
         var doc = document.body.createTextRange();
         doc.moveToElementText(document.all(s));
         doc.select();
         doc.execCommand('copy');
         alert('배너 소스가 클립보드로 카피되었습니다. ^^; Ctrl + V로 문서에 바로 붙여넣기 하시면 됨니다.');

    }
</script>

<body id=[##_tb_address_##] onclick="javascript:copy_select('[##_tb_address_##]')">
akakakakadkfjad;fafasd;fasdfadadf
</body>

+ Recent posts