Dojo [펌] 7. DOJO D&D(drag and drop)

황제낙엽 2009.03.11 07:22 조회 수 : 42 추천:137

sitelink1  
sitelink2  
sitelink3  
extra_vars4  
extra_vars5  
extra_vars6  
http://blog.naver.com/rediblue/120036914971

// Dojo 라이프러리 임포트

<script language = "JavaScript" type = "text/javascript" src = "dojo-0.4.2-ajax/dojo.js"></script>

<script type = "text/javascript" language = "JavaScript">
  //<![CDATA[

            // D&G할 오른쪽 , 왼쪽 리스트

            var groupsList;
            var entitlementsList;

               

            // dojo D&D 패키지를 로드한다.
            dojo.require("dojo.dnd.*");

       

           // 애니메이션 효과를 위한 dojo lfx 패키지를 로드한다.

            dojo.require("dojo.lfx.*");

            dojo.require("dojo.html.*");

           

            // LI 객체가 D&D 이벤트 상태일 때 객체의 이미지를 보이지 않게한다.

            // 삭제하지 않는 이유는 객체가 D&D 되서 옮겨질 것인지 취소해서 원래의 리스트로

            // 돌아갈지 확실 하지 않기때문이다.

            function setImgVisibility( node, visibility ) {

               dojo.lang.forEach( node.getElementsByTagName("img"), function ( child ) {

                                                                                                                 child.style.visibility = visibility;

                                                                                                }

                                         );

            }

            

            // D&D 가 완료될 경우 객체에 있는 이미지를 삭제한다.

            function removeIcons( node ) {

               while ( dojo.dom.getFirstChildElement( node, "img" ) ) {

                     var img = node.firstChild;

                     if ( img.src.indexOf( "Lock" ) > -1 ) {

                        dojo.event.disconnect( img, "onclick", lockEntitlement );

                     }

                     if ( img.src.indexOf( "Delete" ) > -1 ) {

                        dojo.event.disconnect( img, "onclick", removeEntitlement );

                     } node.removeChild( img );

               }

            }

 

            // 파라미터로 넘겨진 ID 와 Action를 통하여 이미지 객체를 생성한다.

            function createImageNode( id, action ) {

               var img = document.createElement("img");

               img.src = "media/" + action + ".jpg";

               img.alt = id;

               img.id = action + " " + id; return img;

            }

 

            // 오른쪽 리스트에 LI 객체가 추가될때 락 , 삭제 이미지를 추가하는 함수

            function decorateElement( node ) {

              

                // Dojo dom 패키지를 통하여 LI 객체에 이미지가 있는지 검사한 후 없다면 이미지를 추가한다.

               if ( !dojo.dom.getFirstChildElement( node, "img" ) ) {

                    var lockImg = createImageNode( node.id, "Lock" );

                    lockImg.style.marginRight = "16px";

                    node.insertBefore( lockImg, node.childNodes[0] );

        

                    // 추가한 이미지에 Onclick시 수행할 이벤트 핸들러를 등록한다.

                    dojo.event.connect( lockImg, "onclick", lockEntitlement );

                    var deleteImg = createImageNode( node.id, "Delete" );

                    node.insertBefore( deleteImg, node.childNodes[0] );

                    dojo.event.connect( deleteImg, "onclick", removeEntitlement );

                 }

              }

 

            // 삭제 이미지에  Onclick 이벤트가 발생될 때 실행되는 함수로 LI 객체의 이미지를 제거하고

            // 에니메이션 효과를 발생 시킨다.

            function removeEntitlement( event ) {

               alert( "Add code to animate removal of entitlement" );

                var imgAltTag = event.target.alt;

                dojo.debug( "Processing removeEntitlement() for " + event.target.alt);

               

                // dojo forEach문을 통하여 오른쪽 리스트의 LI객체를 검색하면 Loof를 실행한다.

                // 이미지가 생성될때 ID와 노드의 ID를 같이 하였기 때문에 alt를 비교하여 선택된 아이콘의 LI객체를

                // 선택한 후 객체의 이미즈를 삭제하고 이미지 효과를 발생시킨다.

                dojo.lang.forEach( entitlementsList.getElementsByTagName("li"), function ( liNode ) {

                                                                                                                if ( liNode && liNode.id == imgAltTag ) {

                                                                                                                    removeIcons( liNode );

                                                                                                                    animateMove( liNode, event);

                                                                                                                }

                                                                                                             }

                 );

             }

           

            // 애니메이션 효과를 설정하는 함수로 오른쪽의 X버튼이 클릭되었을때

            // 왼쪽으로 리스트가 날아가는 에니메이션 효과를 설정한다.

            function animateMove( liNode, mouseEvent ) {

               dojo.debug( "Processing animateMove()");

             

               // 에니메이션 효과를 추가할 영역을 설정하는 데 여기서는

               // 화면 전체에 효과를 주기 위하여 container div를 가져온다.

               var displayArea = dojo.byId("container");

                    

               // 에니매이션 효과를 시작할 위치로 오른쪽 리스트의 선택된 li 객체의 위치를 지정한다..

               var startPosition = new Array( dojo.html.getAbsolutePosition(liNode).x, dojo.html.getAbsolutePosition(liNode).y );

 

               // 에니매이션 효과가 끝나는 위치로 왼쪽 리스트의 UL 객체의 위치를 지정한다.

               // 이 위치는 UL 객체내에 LI객체가 없을 경우를 가정한다.

               var endPosition = new Array( dojo.html.getAbsolutePosition(groupsList).x,

                                                         dojo.html.getAbsolutePosition(groupsList).y );

 

               // 왼쪽 UL객체내에 LI객체가 있다면 애니메이션 효과각 끝나는 위치를 리스트의 가장 마지막으로 정한다.

               var liNodes = groupsList.getElementsByTagName("li");

               if ( liNodes && liNodes.length > 0 ) {

                   var targetNode = liNodes[ liNodes.length - 1 ];

                   endPosition = new Array( dojo.html.getAbsolutePosition(targetNode).x,

                                                        dojo.html.getAbsolutePosition(targetNode).y )

                }

       

               // 에니매이션효과를 시작점 과 끝점을 통하여 지정한다. 

               var line = new dojo.lfx.Line( startPosition, endPosition );

                

               // 에니매이션 객체를 생성하고 효과의 지속 시간을  0.5초로 시작점 과 끝점을 지나는 데 걸리도록 지정한다. 

               var anim = new dojo.lfx.Animation( 500, line );

              

               // 에니매이션 효과에 사용될 노드를 선언한다. 

               var node;


 

               // 에니매이션 객체에 이벤트가 발생될때 에니메이션의 시작 액션을 지정한다.

               // 오른쪽에서 왼쪽으로 객체가 날아가는 액션은 단순히 날아갈 객체를

               // 이벤트가 일어나는 리스트를 포함하는  div에다 추가해 주면된다.

               // 날아가는 객체는 선택된 리스트 객체이기 때문에 LI 객체를 복사 해서 사용한다.

               // 스타일까지 복사되지 않기때문에 똑같은 스타일을 지정하고 오른쪽 리스트에서 객체를 삭제한다.

              dojo.event.connect(anim, "onBegin", function(e) {

                                                                                     dojo.debug("Processing onBegin");

                                                                                      node =liNode.cloneNode( true );

                                                                                      node.className = "grayBox";

                                                                                      node.style.position = "absolute";

                                                                                      node.style.width = "19em";

                                                                                      displayArea.appendChild( node );                          

                                                                                      entitlementsList.removeChild( liNode );

                                                                                      }

                                          );

 

               // 이벤트가 발생하는 0.5초 동안 객체는  onAnimate 이벤트를 발생 시킨다.

               // 이때 변화하는 좌표들의 배열을 파라미터로 함수를 호출하는데 이 이벤트를 통하여

               // 복사한 이벤트 객체의 위치를 변화시켜 에니메이션 효과를 발생시킨다.

              dojo.event.connect(anim, "onAnimate", function(e) {

                                                                             node.style.top = e[1] + "px"; node.style.left = e[0] + "px";

                                                                       }

                                         );

              // 애니메이션 객체의 이벤트가 끝날때 onEnd 이벤트가 호출되는데 이 때 실행한 에니메이션 효과를

              // 위해 사용된 객체를 삭제하고 외쪽 리스트에 객체를 추가한다.

              dojo.event.connect(anim, "onEnd", function(e) {

                                                                                   dojo.debug("Processing onEnd");

                                                                                   displayArea.removeChild( node );

                                                                                   groupsList.appendChild( liNode );

                                                                                  }

                                          );

               // 지금까지 설정된 에니메이션을 작동시킨다.

               anim.play(); }


            function init ()
            {
              dojo.debug("Processing init()", "INFO");

 

              //Dojo Dom 객체를 이용하여 리스트를 가져와 객체를 초기화 한다.            
              entitlementsList = dojo.byId("selectedEntitlementNames");
              groupsList = dojo.byId("availableGroupNames");
              dojo.debug("Initialization complete");
             
               dojo.debug( "Initializing Drag-and-drop" );

 

              // 오른쪽 매뉴에 드롭이 완료될 경우 아이콘을 추가하기 위해  declear 매소드를 통해 HtmlDropTarget를 확장한 후 

              // onDrop 매소드는 드럽이 완료될 경우 true를 드럽이 취소될 경우 false를 리턴하도록 오버라이드 한다.

             dojo.declare("my.dojo.lab.dnd.HtmlDropTarget",dojo.dnd.HtmlDropTarget,{

                                 onDrop: function(e) {

                                                              if ( dojo.dnd.HtmlDropTarget.prototype.onDrop.apply(this, arguments)){

                                                                    decorateElement( e.dragObject.domNode );

                                                                    return true;

                                                               }

                                                               return false;

                                               }

                                  }

               );

 

               // D&D를 실행할 객체를 지정하고 객체의 아이템 타입을 지정한다.

               // 타입의 이름은 지정하고 싶은 이름을 지정한다.
               var lefthandDropTarget = new dojo.dnd.HtmlDropTarget( groupsList, [ "entitlementType" ] );

 

               //Dojo의 for문을 통하여 리스트객체의 li객체가 있는 만큼 반복하며 함수를 호출한다.
               dojo.lang.forEach( groupsList.getElementsByTagName("li"), function ( child )
                 {

                     // 포함된 li객체를 d&d형식의 "entitlementType"라는 이름을 가진 객체로 변환한다. 
                     var dragSource = new dojo.dnd.HtmlDragSource( child, "entitlementType" );

 

                     // d&d 아이템의 스타일 클래스를 지정한다.
                     dragSource.dragClass = "grayBox";

 

                     // d&d 아이템의 d&d 시작과 끝에 호출될 이벤트 핸들러를 등록한다.
                     dojo.event.connect(dragSource, "onDragStart", function(e){ dojo.debug( "Processing onDragStart()" ); });
                     dojo.event.connect(dragSource, "onDragEnd", function(e){ dojo.debug( "Processing onDragEnd()" ); });

 

                     // 오른쪽 LI 객체가 드래그될때는 이미지가 보이지 않도록 설정한다.

                     dojo.event.connect( dragSource, "onDragStart", function(e) {

                                                                                            e.target.style.width = "19em";

                                                                                            setImgVisibility( e.target, "hidden" );

                                                                                          }

                                                 );

                    

                     // D&D에서 왼쪽 리스트로 옮겨가지 않을 경우 객체의 아이콘을 다시 보이도록 한다.

                     dojo.event.connect( "after", dragSource, "onDragEnd", function(e)

                     {

                       dojo.lang.forEach( entitlementsList.getElementsByTagName("li"),function ( liNode )

                       {

                          setImgVisibility( liNode, "visible" );

                         });

                      });
                 }

               );

 

                // D&D를 실행할 객체를 지정하고 객체않의 아이템들의 타입을 지정한다.

                // 타입의 이름은 지정하고 싶은 이름을 지정한다.

               var righthandDropTarget = new dojo.dnd.HtmlDropTarget( entitlementsList, [ "entitlementType" ] );
              
               // 패이지가 처음 로드되었을때는 오른쪽 타겟의 ul객체는 비어있기 때문에  li 객체에 오퍼레이션을

               // 등록할 수 없다. 그렇기 때문에 타겟이 비어있을 경우 노드를 추가해 준다.  

               // 이벤트가 등록되는 부분이 li 객체가 아니고 이를 포함하고 있는 ul객체인 것을 주의해야 한다.

               // 이것의 의미는 이 이벤트가 발동되는 것은 li객체가 사이가 아니라 ui와 li 사이에 객체가 추가 되었을때

               // 즉 리스트의 제일 처음이나 마지막에 추가되어 ui과 li의 경계를 이루게될때 호출된다는 의미이다.

               // 이럴 경우 이 이벤트 핸들러가 작동하고 리스트 d&d의 중복 등록은 막아준다.
               dojo.event.connect( new dojo.dnd.HtmlDropTarget( dojo.byId( "rightDiv" ), [ "entitlementType" ] ), "onDrop", 

                                            function(e){

                                                            // 오른쪽 리스트에 객체가 추가될 경우 아이콘을 추가한다.

                                                            decorateElement( e.dragObject.domNode ); 
                                                            entitlementsList.appendChild( e.dragObject.domNode );
                                                             return true;
                                                             }

                                          );

 

                dojo.event.connect( new dojo.dnd.HtmlDropTarget( dojo.byId( "leftDiv" ), [ "entitlementType" ] ), "onDrop",

                                            function(e){

                                                             // 왼쫄 리스트에 객체가 추고될 경우 아이콘을 제거한다.

                                                             removeIcons( e.dragObject.domNode );
                                                             groupsList.appendChild( e.dragObject.domNode );
                                                             return true;
                                                             }

                                             );
            }

            dojo.addOnLoad(init);

            //]]>
        </script>
 <body>
<div id="container">
    <div id="header"><h1>Edit Entitlements for Carrie Sutherland</h1></div>
    <div id="leftDiv">
    <h3>Available Entitlements</h3>
    <ul id = "availableGroupNames" class="grayBox">
      <li id = "ServiceRequestAdmin"> Service Request Admin </li>
      <li id = "ServiceRequestReader"> Service Request Reader </li>
      <li id = "ServiceRequestEditor"> Service Request Editor </li>
      <li id = "ServiceRequestLevel1Approver"> Service Request Level-1 Approver </li>
      <li id = "ServiceRequestLevel2Approver"> Service Request Level-2 Approver </li>
      <li id = "ServiceRequestLevel3Approver"> Service Request Level-3 Approver </li>
    </ul>
  </div>
  <div id="rightDiv">
    <h3>Selected Entitlements</h3>
    <ul id = "selectedEntitlementNames" class="grayBox" ></ul>
  </div>

    <div id="centerDiv">
    </div>
    <div id="footer">Ajax Code Camp - Dojo Toolkit Advanced Lab</a></div>
    <div id = "logArea" style = "font-size: small; color: green; font-family: courier, serif, monospace">
    </div>
</div>
</body>
</html>