A simple reorder list in Ext JS

I’ve been using Ext JS for quite some time now, and I must say, I love it.

There is quite good support for drag’n'drop here, but it lacks one thing; the precious reorder list.
An example of such can be found here

Since doing the google didn’t return anything like this I ended up implementing it my self.

I started out with the example given here, but this only implements basic d’n'd of elements, not the reordering.
So with the following html:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="../lib/ext/resources/css/ext-all.css" temp_href="../lib/ext/resources/css/ext-all.css">
<script type="text/javascript" src="../lib/ext/adapter/ext/ext-base.js" temp_src="../lib/ext/adapter/ext/ext-base.js">
</script>
<script type="text/javascript" src="../lib/ext/ext-all-debug.js" temp_src="../lib/ext/ext-all-debug.js">
</script>
<script type="text/javascript" src="custom.js" temp_src="custom.js">
</script>
<script type="text/javascript">Ext.onReady(Tutorial.dd.init, Tutorial.dd);
</script>
<title>Custom Drag & Drop Tutorial</title>
<style type="text/css">

.dd-item {
height: 18px;
border: 1px solid #a0a0a0;
background-color: #c4d0ff;
vertical-align: middle;
cursor: move;
padding: 2px;
z-index: 1000;
}

.dd-ct .dd-item {
margin: 2px;
width:200px;
}

.dd-proxy {
opacity: 0.4;
-moz-opacity: 0.4;
filter: alpha( opacity = 40 );
}
</style>
</head>
<body>
<div class="dd-ct" id="dd1-ct">
<div class="dd-item" id="dd1-item1">
Item 1.1
</div>
<div class="dd-item" id="dd1-item2">
Item 1.2
</div>
<div class="dd-item" id="dd1-item3">
Item 1.3
</div>
</div>
</body>
</html>

and the following Javascript in index.js:

Ext.BLANK_IMAGE_URL = '../lib/ext/resources/images/default/s.gif';
Ext.namespace('Tutorial');
Ext.override(Ext.dd.DDProxy, {
startDrag: function(x, y){
var dragEl = Ext.get(this.getDragEl());
var el = Ext.get(this.getEl());
dragEl.applyStyles({
border: '',
'z-index': 2000
});
dragEl.update(el.dom.innerHTML);
dragEl.addClass(el.dom.className + ' dd-proxy');
},
onDragEnter: function(e, targetId){
var target = Ext.get(targetId);

if (target.dd instanceof Ext.dd.DDProxy) {
this._target = target;
this.updateTargetPosition();
}
},
updateTargetPosition: function(){
var _box = this._target.getBox();
this._crossOver = {
x: (this._target.getLeft() + (_box.width / 2)),
y: (this._target.getTop() + (_box.height / 2))
}
},
onDragOver: function(e, targetId){
if (this._target) {
var el = Ext.get(this.getEl());
if (el.id != this._target.id) {
if (this._placement == "before") {
el.insertBefore(this._target);
}
else {
el.insertAfter(this._target);
}
this.updateTargetPosition();
var xy = e.getXY();
this._placement = (xy[1] < this._crossOver.y) ? "before" : "after";
}
}
},
endDrag: function(){
var el = Ext.get(this.getEl());
el.applyStyles({
position: '',
width: ''
});
this._target = null;
this._placement = null;
this._crossOver = null;
}
});

Tutorial.dd = function(){
return {

init: function(){
var dz1 = new Ext.dd.DropZone('dd1-ct', {
ddGroup: 'group'
});

var dd11 = Ext.get('dd1-item1');
dd11.dd = new Ext.dd.DDProxy('dd1-item1', 'group');
var dd12 = Ext.get('dd1-item2');
dd12.dd = new Ext.dd.DDProxy('dd1-item2', 'group');
var dd13 = Ext.get('dd1-item3');
dd13.dd = new Ext.dd.DDProxy('dd1-item3', 'group');

}
};
}
();

we suddenly have what we need.
For now this only supports non-floating block elements, but I will extend it to also support floats.

UPDATE 1
This demo is now available at http://kinsey.no/examples/reorderlist/

UPDATE 2
I now have a version supporting float ready and will publish this when I have the time.
There is also a reorderview available using a reading and updating from a standard datastore.

Tags: , ,

This entry was posted on Tuesday, July 29th, 2008 at 16:12 and is filed under programming, Uncategorized. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

  • Daniel

    Thank you so much for this post! I needed the same thing as you and you saved me a lot of time

  • Daniel

    Thank you so much for this post! I needed the same thing as you and you saved me a lot of time