powered by Google

Sortable list in less than 50 lines of code

Posted on 12. May 2007 · Comments [2]
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.

Like this post? Subscribe to the RSS feed!
2 comments so far

Hi!
I recently (yesterday) found your site, and it's been really interesting to look at your various projects - nice work!

A quick note about the sortable list: I've found that a JavaScript error occurs (at least with WinXP/IE6) when one drags an item too far (so the mouse pointer is outside the page), releases the mouse button and then brings the mouse pointer back in over the page. The next time the mouse is clicked, there is a JavaScript error.

Anyway, again: I really like what you've done with your various web projects!

/Carl

Hi,

Nice example.. But it wont work for more data.. For example, if the li tag contains a div tag with more lines of html code it seems not working..

Regards
Binoy

Post a comment
Commenting on this post has expired.
© 2000-2009 amix. Powered by Skeletonz.