reorder on attr

by sanford

HTML

<button id="reorder">reorder</button>
<div id="contents">
    <div class="interlope">int a</div>
    <div data-originalindex="3" tabindex="1">lor 3</div>
    <div data-originalindex="1" tabindex="2">em 1</div>
    <div data-originalindex="4" tabindex="3" >ip 4</div>
    <div class="interlope">int b</div>
    <div data-originalindex="2"><div class="decorator"></div>man 2</div>
</div>

CSS

body { background: wheat; font-family: Verdana; font-size: 14px; }
div { 
    height: 100px;
    width: 100px; 
    background: purple;
    color: tan;
    text-align: center;
}
div#contents { 
    height: 448px; 
    background: transparent;
}
div#contents div {
    margin-bottom: 12px;
    line-height: 100px;
    position: relative;
    overflow: hidden;
}
div#contents div.decorator {
    height: 36px; width: 48px;
    background: white;
    opacity: .5;
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
    position: absolute;
    top: -2px;
    left: 90px;
}
div#contents div:hover div.decorator {
    opacity: 1;
}
.interlope { 
    background: lightgreen; 
    height: 20px; 
    line-height: 20px !important; 
    color: darkgray;
}
:focus { outline: red solid 3px; }

JavaScript

console.log('----');

Element.implement({
    orderElementsByAttribute: function ( attr, selector, ignoreEmpty ) {
        attr = attr || 'data-originalindex';
        selector = selector || '[' + attr + ']';
        ignoreEmpty = ignoreEmpty || true;

        var els = selector 
            ? this.getElements(selector)
            : this.getChildren();
        var slots = [], skips = [];
        
        Array.each(els,function(itm,idx){
            if ( ignoreEmpty && !itm.get(attr) ) { 
                skips.push( idx );
            } else {
                var slot = itm.getPrevious() != itm.getPrevious(selector)
                    ? itm.getPrevious()
                    : null;
                slots.push( slot );
            }
        });
        Array.each(skips,function(itm,idx){
            els.splice(itm-idx,1);
        });

        els.sort( compareAttrAsInt.bind(attr) ); // using EO to pass arg
        
        Array.each(els,function(itm,idx){
            var goAfter = slots[idx] 
                || els[idx-1] 
                || this;
            var relation = goAfter != this 
                ? 'after' 
                : 'top';
            // console.log(itm.get('text'),goAfter.get('text'),relation);
            itm.inject(goAfter, relation);
            itm.get('tabIndex') > 0
                ? itm.set('tabIndex',idx+1)
                : null;
        }.bind(this));
        
        function compareAttrAsInt (a,b) {
            var attr = this.toString(); /* we are using the EO for 3rd param */
            return a.get(attr) > b.get(attr);
        }
    }
});

$('reorder').addEvent('click',function(){
    $('contents').orderElementsByAttribute();
});