Copyright © tutorialspoint.com

script.aculo.us Sorting Elements

previous next


Advertisements

Many times you need to provide the user with the ability to reorder elements (such as items in a list) by dragging them.

Without drag and drop, reordering can be a nightmare but script.aculo.us provides extended reordering support out of the box through the Sortable class. The element to become Sortable is passed to the create() method in the Sortable namespace:

A Sortable consists of item elements in a container element. When you create a new Sortable, it takes care of the creation of the corresponding Draggables and Droppables.

To use script.aculo.us's Sortable capabilities, you'll need to load the dragdrop module, which requires the effects module also. So your minimum loading for script.aculo.us will look like this:


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

Sortable Syntax:

Here is the syntax of the create() method to create a sortable items. The create() method takes the id of a container element and sort them out based on the passed options.

 Sortable.create('id_of_container',[options]);

Use Sortable.destroy to completely remove all event handlers and references to a Sortable created by Sortable.create.

NOTE: A call to Sortable.create implicitly calls on Sortable.destroy if the referenced element was already a Sortable. Here is simple syntax to call destroy function.

Sortable.destroy( element );

Sortable Options:

You can use or more of the following options while creating your Sortable object.

OptionDescription
tagSpecifies the type of the elements within the sortable container that are to be sortable via drag and drop. Defaults to 'li'.
onlySpecifies a CSS class name, or array of class names, that a draggable item must posses in order to be accepted by the drop target. This is similar to the accept option of Draggable. By default, no class name constraints are applied.
overlapOne of false, horizontal or vertical. Controls the point at which a reordering is triggered. Defaults to vertical.
constraintOne of false, horizontal or vertical. Constrains the movement of dragged sortable elements. Defaults to vertical.
containmentEnables dragging and dropping between Sortables. Takes an array of elements or element-ids. Important note: To ensure that two way dragging between containers is possible, place all Sortable.create calls after the container elements.
handleSame as the Draggable option of the same name, specifying an element to be used to initiate drag operations. By default, each element is its own handle.
hoverclassSpecifies a CSS class name to be applied to non-dragged sortable elements as a dragged element passes over them. By default, no CSS class name is applied.
ghostingSimilar to the Draggable option of the same name, if true, this option causes the original element of a drag operation to stay in place while a semitransparent copy of the element is moved along with the mouse pointer. Defaults to false. This option does not work with IE.
dropOnEmptyIf true, allows sortable elements to be dropped onto an empty list. Defaults to false.
scrollIf the sortable container possesses a scrollbar due to the setting of the CSS overflow attribute, this option enables auto-scrolling of the list beyond the visible elements. Defaults to false.
scrollSensitivityWhen scrolling is enabled, adjust the point at which scrolling is triggered. Defaults to 20.
scrollSpeedWhen scrolling is enabled, adjust the scroll speed. Defaults to 15.
treeIf true, enables sorting with sub-elements within the sortable element. The default is false.
treeTagIf the tree option is enabled, specifies the container element type of the subelement whose children take part in the sortable behavior. Defaults to 'ul'.

You can provide the following callbacks in the options parameter:

OptionDescription
onChangeA function that will be called upon whenever the sort order changes while dragging. When dragging from one Sortable to another, the callback is called once on each Sortable. Gets the affected element as its parameter.
onUpdateA function that will be called upon the termination of a drag operation that results in a change in element order.

Sorting Examples:

This demo has been verified to work in IE 6.0. It also works in the latest version of Firefox.

<html>
<head>
<title>Sorting 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() {
       Sortable.create('namelist',{tag:'li'});
   }
</script>

<style type="text/css">
li { cursor: move; }

</style>
</head>
<body>

<p>Drag and drop list items to sort them out</p>

<ul id="namelist">
   <li>Physics</li>
   <li>Chemistry</li>
   <li>Maths</li>
   <li>Botany</li>
   <li>Sociology</li>
   <li>English</li>
   <li>Hindi</li>
   <li>Sanskrit</li>
</ul>

</body>
</html>

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

Note the usage of tag:'li'. Similar way you can sort following list of images available in <div>:

<html>
<head>
<title>Sorting 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() {
       Sortable.create('imagelist',{tag:'div'});
   }
</script>

<style type="text/css">
   div { cursor: move; }
   img { border: 1px solid red; margin:5px; }
</style>
</head>
<body>

<p>Drag and drop list images to re-arrange them</p>

<div id="imagelist">
   <div><img src="/images/wml_logo.gif" alt="WML Logo" /></div>
   <div><img src="/images/javascript.gif" alt="JS" /></div>
   <div><img src="/images/html.gif" alt="HTML" /></div>
   <div><img src="/images/css.gif" alt="CSS" /></div>
</div>

</body>
</html>

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

Serializing the Sortable Elements:

The Sortable object also provides a function Sortable.serialize() to serialize the Sortable in a format suitable for HTTP GET or POST requests. This can be used to submit the order of the Sortable via an Ajax call.

Serialize Syntax:

Sortable.serialize(element, options);

Serialize Options:

You can use or more of the following options while creating your Sortable object.

OptionDescription
tagSets the kind of tag that will be serialized. This will be similar to what is used in Sortable.create.
nameSets the name of the key that will be used to create the key/value pairs for serializing in HTTP GET/POST format. So if the name were to be xyz the query string would look like:

xyz[]=value1&xyz[]=value2&xyz[]=value3

Where the values are derived from the child elements in the order that they appear within the container.

Serialize Examples:

In this example, the output of the serialization will only give the numbers after the underscore in the list item IDs.

To try, leave the lists in their original order, press the button to see the serialization of the lists. Now, re-order some elements and click the button again.

<html>
<head>
<title>Sorting 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() {
       Sortable.create('namelist',{tag:'li'});
   }
   function serialize(container, name){
      $('display').innerHTML =
      'Serialization of ' + $(container).id + ' is: <br/><pre>' +
      Sortable.serialize( container,{ name:name} ) + '</pre>';
   }
</script>

<style type="text/css">
li { cursor: move; }

</style>
</head>
<body>

<p>Drag and drop list items to sort them out properly</p>

<ul id="namelist">
   <li id="list1_1">Physics</li>
   <li id="list1_2">Chemistry</li>
   <li id="list1_3">Maths</li>
   <li id="list1_4">Botany</li>
   <li id="list1_5">Sociology</li>
   <li id="list1_6">English</li>
</ul>

<p>Click following button to see serialized list which can be
passed to backend script, like PHP, AJAX or CGI</p>
<button type="button" value="Click Me" 
           onclick="serialize('namelist', 'list')"> Serialize
</button>

<div id="display" style="clear:both;padding-top:32px"></div>

</body>
</html>

To understand it in better way you can Try it yourself.

Moving Items between Sortables:

Following is the example showing how to move items from one list to another list.

<html>
<head>
<title>Sorting 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() {
       Sortable.create('List1', 
       {containment: ['List1','List2'], dropOnEmpty: true});
       Sortable.create('List2', 
       {containment: ['List1','List2'], dropOnEmpty: true});
   }
</script>

<style type="text/css">
li { cursor: move; }
ul {
   width: 88px;
   border: 1px solid blue;
   padding: 3px 3px 3px 20px;
}

</style>
</head>
<body>

<p>Drag and drop list items from one list to another list</p>

<div style="float:left">
<ul id="List1">
   <li>Physics</li>
   <li>Chemistry</li>
   <li>Maths</li>
   <li>Botany</li>
</ul>
</div>

<div style="float:left;margin-left:32px">
<ul id="List2">
   <li>Arts</li>
   <li>Politics</li>
   <li>Economics</li>
   <li>History</li>
   <li>Sociology</li>
</ul>
</div>

</body>
</html>

Note that the containment option for each container lists both containers as containment elements. By doing so, we have enabled the child elements to be sorted not only within the context of their parent, but this also enables them to be moved between the two containers.

We set dropOnEmpty to true for both lists. To see the effect this option has on that list, move all the elements from one list into other so that one list is empty. You will find that it is allowing to drop element on empty list.

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

Binding to Ajax:

Of course, onUpdate is a prime candidate for triggering Ajax notifications to the server, for instance when the user reorders a to-do list or some other data set. Combining Ajax.Request and Sortable.serialize makes live persistence simple enough:

<html>
<head>
<title>Sorting 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() {
       Sortable.create('List' , {
          onUpdate: function() {
            new Ajax.Request('file.php' , {
	      method: "post",
              parameters: {data:Sortable.serialize('List')}
            });
          }
       });
   }
</script>

<style type="text/css">
li { cursor: move; }
ul {
   width: 88px;
   border: 1px solid blue;
   padding: 3px 3px 3px 20px;
}

</style>
</head>
<body>

<p>When you will change the order, AJAX Request 
will be made automatically.</p>

<div style="float:left">
<ul id="List">
   <li id="List_1">Physics</li>
   <li id="List_2">Chemistry</li>
   <li id="List_3">Maths</li>
   <li id="List_4">Botany</li>
</ul>
</div>

</body>
</html>

Sortable.serialize creates a string like: List[]=1&List[]=2&List[]=3&List[]=4 where the numbers are the identifier parts of the list element ids after the underscore.

Now we need to code file.php which will parse posted data as parse_str($_POST['data']); and you can do whatever you want to do with this sorted data.

To learn more about AJAX, please go through our simple Ajax Tutorial.


previous next

Copyright © tutorialspoint.com