본문 바로가기

WEB_Programming/Ajax

script.aculo.us의 Drag 'n' Drop 패키지 이용하기

대부분의 인기있는 웹 2.0 인터페이스는 기능은 드래그 앤 드롭일 것이다. 운이 좋게도 script.aculo.us는 drag and drop기능을 강력하게 제공해 주고 있다.


script.aculo.us의 드래깅 기능을 이용하여, 드래그앤 드롭을 수행할 모듈을 정의할 수 있다. script.aculo.us를 로딩하기 위해서는 최소한으로 다음의 내용이 들어가야한다.

<script type="text/javascript" src="/javascript/prototype.js">
</script>
<script type="text/javascript" src="/javascript/scriptaculous.js?load=effects,dragdrop">
</script>

Dragging Things Around:

scriptaculous를 이용하면 드래그 가능한 아이템을 매우 간단하게 만들 수 있다. 이것은 단지 Draggable클래스의 인터페이스를 생성하는 것만으로도 충분히 수행된다. 그리고 드래그 가능한 엘리먼트를 정의할 수 있다.

Draggable Syntax:

new Draggable( element, options );

첫번째 파라미터는 엘리먼트를 드래그할때 이용될 id값을 지정하는 것이며, 엘리먼트를 참조할경우 사용된다. 두번째 파라미터는 엘리먼트가 드래그를 수행할때 어떠한 행동을 취할 것인가에 대한 옵션 값이다.

Draggable Options:

드래그 가능한 객체를 생성할 때 다음과 같은 옵션을 이용할 수 있다.

OptionDescriptionExamples
reverttrue로 설정되면, 드래그가 끝났을때 원래 위치를 반환해준다. 또한 revertdffect콜백을 지정했을 경우 드래그 오퍼레이션이 끝나는 시점에 메소드를 호출하게 된다. 기본적인 값은 false이다.
Example
snap이동시 특정한 그리드 영역에 스냅된 형식으로 드래그 된다. 만약 false라고 지정된 경우(기본값) 스냅이나 이동에 제약이 걸리지 않는다. 만약 정수형 x값이 지정되면 x 픽셀의 그리드에 스냅되어 드래그 될 것이다. 만약 array[x, y]로 수직 드래깅을 할 경우 x픽셀 그리드에 스냅되며, 수직으로 y픽셀에 스냅된다. 이 함수도 Function(x, y, draggable)로 함수 기능을 지정하여 array[x, y]값을 반환할 수 있다.
Example
zindexCSS의 Z인덱스를 지정한다. 이것은 드래그 오퍼레이션을 수행하는 동안에 적용된다. 기본값으로 Z인덱스 값은 1000으로 지정된다.
Example
ghosting이값은 드래그하는동안 클론된 모양으로 드래그가 가능하게 할 것인지 지정한다. 원래 위치를 떠나서 드롭되기까지 클론을 만들어 이동 시킨다. 기본값은 false이다.
Example
constraint드래그 가능한 방향을 제한하도록 할때 이용할 수 있다. 수평이나 수직으로 지정이 가능하며 기본값은 null이고, 이것은 자유롭게 이동이 가능함을 나탄내다.
Example
handle드래그 오퍼레이션이 시작할 핸들을 지정할때 유용하다. 기본값으로 엘리먼트가 소유한 핸들로 지정된다.
Example
starteffect드래그가 시작될때 엘리먼트에 호출될 이펙트를 지정한다. 기본값으로 투명도를 0.2초내 0.2로 설정한다.
Example
reverteffect드래그가 복귀된 경우에 호출될 엘리먼트의 이펙트를 지정한다. 기본값으로 원래 이미지로 부드러운 슬라이드 형식으로 복귀한다. 이값은 revert가 true로 지정된 경우에만 수행된다.
Example
endeffect드래깅이 끝나는 시점에서 엘리먼트에 호출될 효과를 지정한다 기본값으로 엘리먼트의 투명도를 1.0으로 0.2초내 수행된다.
Example

Callback Options:

추가적으로 옵션 파라미터에 다음과 같은 콜백 함수를 지정할 수 있다.

FunctionDescriptionExamples
onStart드래그가 시작되었을때 호출된다.
Example
onDrag마우스가 이동되는 동안 반복적으로 호출된다. 만약 마우스 포지션이 이전 호출에서 변화가 일어난 경우를 말한다.
Example
changeonDrag에서만 호출된다.
Example
onEnd드래그가 끝이났을때 호출된다.
Example

예외적으로 "change"콜백은, 2개의 파라미터를 수용한다. Draggable object와 mouse event 객체가 그것이다.

Draggable Example:

이제 5개의 엘리먼트를 드래그 가능하도록 지정할 것이다. 3개의 <div>엘리먼트, <img>엘리먼트, 그리고 <span>엘리먼트를 이용한다. 이 3개의 서로다른 <div>엘리먼트의 목적은 엘리먼트의 시작 포지션이 고정되어 있든지, 상대적인 값이든지, 절대적인 값이든지 무시하고 드래그를 수행하는 행동에 영향받지 않도록 하는데 있다.
<html>
<head>
<title>Draggables Elements</title>
<script type="text/javascript" src="/javascript/prototype.js"></script>
<script type="text/javascript" src="/javascript/scriptaculous.js"></script>

<script type="text/javascript">
// Take all the elements whatever you want to make Draggable.
var elements = [
'normaldiv',
'relativediv',
'absolutediv',
'image',
'span'
];
// Make all the items drag able by creating Draggable objects
window.onload = function() {
elements.each(
function(item) {
new Draggable(item, {});
}
);
}
</script>

</head>
<body>
<div id="normaldiv">
This is a normal div and this is dragable.
</div>

<div id="relativediv" style="position: relative;">
This is a relative div and this is dragable.
</div>

<div id="absolutediv" style="position: absolute;">
This is an absolute div and this dragable.
</div>
<br />
<img id="image" src="/images/scriptaculous.gif"/>

<p>Let part <span id="span" style="color: blue;">
This is middle part</span> Yes, only middle part is dragable.</p>
</body>

더욱더 이해를 돕기 위해서 Try it yourself을  실행해보면서 상단의 내용에 대한 옵션을 이해할 수 있을 것이다.

Dropping Dragged Things:

엘리먼트가 드롭 타겟에 들어갔을때 all()메소드가 호출된다.

Droppable 네임스페이스는 2개의 중요한 메소드를 가지고 있으며 add()는 드롭 타겟을 생성하고, remove()는 drop타겟을 제거하는데 이용된다.

Droppables Syntax:

여기 add()메소드를 이용하여 drop 타겟을 생성하는 구문이다. add()메소드는 첫번째 파라미터로 전달된 영역으로 타겟 지점으로 삼도록 한다. 두번째 파라미터는 옵션을 지정하는 것이다.

Droppables.add( element, options );

그리고 remove() 구문은 더욱 간단하다. remove()메소드를 이용하여 타겟으로 전달되는 행동을 제거할 수 있다.

Droppables.remove(element);

Droppables Options:

드래그 객체를 생성할때 다음과 같은 옵션을 지정할 수 있다.

OptionDescriptionExamples
HoverclassCSS 클래스의 이름으로 드롭이 활성화 될 때 엘리먼트를 추가할 수 있도록 기본값은 null이다. 즉, 이값은 해당 엘리먼트 위로 드래그 가능하도록 지정할지에 대한 내용이다.
Example
AcceptCSS클래스에 지정된 문자열의 배열값이나, 문자열이다. 하나 혹은 이상의 CSS클래스를 드롭 가능한 객체가 가질 것인지 설정한다. 즉, 어떠한 엘리먼트가 드롭가능하고, 어떠한 엘리먼트가 가능하지 않은지에 대해서 지정이 가능하다.
Example
ContainmentSpecifies an element, or array of elements, that must be a parent of a draggable item in order for it to be accepted by the drop target. By default, no containment constraints are applied.
Example
OverlapIf set to 'horizontal' or 'vertical' the droppable will only react to a Draggable if its overlapping by more than 50% in the given direction. Used by Sortables and discussed in next chapter. 
greedyIf true (default), stops processing hovering other droppables under the draggable won't be searched.Example

Callback Options:

Additionally, you can use any of the following callback functions in the options parameter :

FunctionDescriptionExamples
onHoverSpecifies a callback function that is activated when a suitable draggable item hovers over the drop target. Used by Sortables and discussed in next chapter. 
onDropSpecifies a callback function that is called when a suitable draggable element is dropped onto the drop target.Example

Droppables Example:

엘리먼트의 처음 부분은 이전의 예제에서와 유사하게 Prototypes의 $A()를 이용하여 모든 <img>엘리먼트의 리스트를 드래그 가능한 엘리먼트 리스트로 만들고 있다.
<html>
<head>
<title>Drag and Drop Example</title>
<script type="text/javascript"
src="/javascript/prototype.js"></script>
<script type="text/javascript"
src="/javascript/scriptaculous.js"></script>

<script type="text/javascript">
window.onload = function() {
// Make all the images draggables from draggables division.
$A($('draggables').getElementsByTagName('img')).each(
function(item) {
new Draggable(
item,
{
revert: true,
ghosting: true
}
);
}
);

Droppables.add(
'droparea',
{
hoverclass: 'hoverActive',
onDrop: moveItem
}
);
// Set drop area by default non cleared.
$('droparea').cleared = false;
}
// The target drop area contains a snippet of instructional
// text that we want to remove when the first item
// is dropped into it.
function moveItem( draggable,droparea){
if (!droparea.cleared) {
droparea.innerHTML = '';
droparea.cleared = true;
}
draggable.parentNode.removeChild(draggable);
droparea.appendChild(draggable);
}
</script>
<style type="text/css">
#draggables {
width: 172px;
border: 3px ridge blue;
float: left;
padding: 9px;
}
#droparea {
float: left;
margin-left: 16px;
width: 172px;
border: 3px ridge maroon;
text-align: center;
font-size: 24px;
padding: 9px;
float: left;
}
.hoverActive {
background-color: #ffffcc;
}
#draggables img, #droparea img {
margin: 4px;
border:1px solid red;
}
</style>
</head>
<body>
<div id="draggables">
<img src="/images/html.gif"/>
<img src="/images/css.gif"/>
<img src="/images/xhtml.gif"/>
<img src="/images/wml_logo.gif"/>
<img src="/images/javascript.gif"/>
</div>

<div id="droparea">
Drag and Drop Your Images in this area
</div>
</body>
</html>

To understand it in better way you can Try it yourself with different options discussed in above table.