Sortable list in less than 50 lines of code

The upcoming AJS version 4.0 will feature a reimplementation of drag and drop (AJS.dnd). This implementation of drag and drop is less than 100 lines of code.

100 lines of clean JavaScript code!

The main idea in my approach is that people can use AJS.dnd to build their own interfaces, it basically provides a bare-bone where browser issues are solved. There is no drop-zones and no sortable lists, but yet, you can implement these things using a few lines of JavaScript.

I have implemented sortable list (old example) in less that 50 lines of code:

Sortable = AJS.Class({
    current_replacer: null,

    init: function(items) {
        this.li_items = items;
        AJS.bindMethods(this);
    },

    onStart: function() {
        var root = AJS.dnd.current_root;
        var old_pos = AJS.$AP(root);

        var replacer = this.current_replacer = AJS.LI();

        AJS.setHeight(replacer, root.offsetHeight - 2); //2 for border
        AJS.setClass(replacer, root.className);
        AJS.addClass(replacer, 'drop_item');

        AJS.insertAfter(replacer, root);

        AJS.setOpacity(root, 0.5);
        root.style.position = 'absolute';
        AJS.setTop(root, old_pos.y);
    },

    onDrag: function() {
        var root = AJS.dnd.current_root;
        var current_replacer = this.current_replacer;
        
        AJS.map(this.li_items, function(drop_zone) {
            if(drop_zone != root) {
                var d_z_top = AJS.$AP(drop_zone).y;
                var d_z_middle = d_z_top + (drop_zone.offsetHeight/2);

                var d_e_top = AJS.$AP(root).y;
                var d_e_bottom = d_e_top + root.offsetHeight;

                if(d_e_bottom > d_z_middle && d_e_top < d_z_top)
                    AJS.insertAfter(current_replacer, drop_zone);
                if(d_e_top < d_z_middle && d_e_top > d_z_top) 
                    AJS.insertBefore(current_replacer, drop_zone);
            }
        });
    },

    onEnd: function() {
        var root = AJS.dnd.current_root;

        AJS.resetOpacity(root);
        root.style.position = '';

        AJS.insertBefore(root, this.current_replacer);
        AJS.removeElement(this.current_replacer);
        this.current_replacer = null;
    }
});

One uses the above code like this:

var li_items = AJS.$bytc('li', null, AJS.$('list'));
var sortable = new Sortable(li_items);

AJS.map(li_items, function(item) {
    AJS.dnd.dragAble(item, {move_x: false,
                            on_start: sortable.onStart,
                            on_drag: sortable.onDrag,
                            on_end: sortable.onEnd});
});

Stay tuned :)

Update: I just started to use AJS 4.0 on Todoist.

Announcements · Code · JavaScript 12. May 2007
© Amir Salihefendic. Powered by Skeletonz.