0

I've got a problem with Mootools Fx.Sort.

<ul id="list">
   <li>One</li>
   <li>Two</li>
</ul>

Javascript:

mySort = new Fx.Sort($$('ul#list>li'));

I can add more elements to the list:

$('list').adopt(new Element('li', { text: 'Three' }));

But the run-time created list elements, obviously, are not considered by Fx.Sort instance and they cannot be sorted with the others.

Is there a way to add them to the existing Fx.Sort? Or the only thing is to replace mySort with a new instance every time I add an element at run-time?

lorenzo-s
  • 16,603
  • 15
  • 54
  • 86

2 Answers2

1

Taking a look at the Fx.Sort instance, there are some attributes that you can modify according to your needs:

console.log(new Fx.Sort($$('ul#list>li'));

This is how I would do it (not tested):

var mySort = new Fx.Sort($$('ul#list>li'));
var newElement = new Element('li', { text: 'Three' });
$('list').adopt(newElement);
mySort.elements.include(newElement);
mySort.subjects.include(newElement);

// Order of elements
var orderSize = mySort.currentOrder.length;
mySort.currentOrder[orderSize] = orderSize;

However, it's modifying the internal mechanism of Mootools More FX.Sort, so it may not work.

ldiqual
  • 15,015
  • 6
  • 52
  • 90
  • 1
    I see. So, if no other solution can be found, I will try to implement a `addElement` method directly into `Fx.Sort` (using `Class.implement`) following your suggestions. Thank you. – lorenzo-s Jan 18 '12 at 22:15
  • I think that's a clean way to do it. However, it's a bad idea concerning modularity: if mootools devs change drastically the internal system, your implementation won't work anymore. In this case, I'd prefer just to restrict myself to the documentation, so reinstantiate Fx.Sort everytime I add an element. – ldiqual Jan 18 '12 at 22:19
  • _“if mootools devs change drastically the internal system, your implementation won't work anymore”_ — Well, that's precisely the definition of an **unclean** way to do something, to me ;) – MattiSG Jan 19 '12 at 07:34
  • @lorenzo-s that is the right approach - i did that very thing yesterday - `Implemented` an `.adopt(el, pos)` - though there are certain difficulties associated with updating domorder (`rearrangeDOM()`) and `currentOrder` being serialized from elements etc. The fact is, elements is a collection and the injection needs to trigger a reorder - which is trickier than expected. If you want the code I produced, give us a shout. BTW, look at this I did a while back for a fun alternative to Fx.Sort - http://jsfiddle.net/dimitar/ZwMUH/ :) – Dimitar Christoff Jan 19 '12 at 10:18
  • @DimitarChristoff Yes, I'm interested in. Thank you Dimitar. Unfortunately I need rearrangeDOM() to work too (the user has to sort some divs containing multiple inputs, the DOM order is important when form is sent). – lorenzo-s Jan 19 '12 at 10:27
  • @DimitarChristoff So... Can I have that implemented method, Dimitar? :P – lorenzo-s Jan 19 '12 at 20:06
1

right - it's trickier to keep it compatible with implementations of the Fx.Sort and keep it sorting as it should etc, here's a working example whereby any of the items being clicked goes to the top and then expands:

http://jsfiddle.net/dimitar/FcN32/

specific to you:

Fx.Sort.implement({

    adopt: function(el, pos) {
        if (!this.element)
            this.element = this.elements[0] && this.elements[0].getParent();

        var len = this.currentOrder.length;
        pos = (pos !== null && typeof pos === 'number')
            ? this.currentOrder.contains(pos) ? pos : len
            : len;


        this.elements.include(el);
        if (pos === len) {
            // don't care, attach to bottom.
            el.inject(this.element);
            this.currentOrder.push(this.elements.indexOf(el));
        }
        else {
            // we are injecting at a particular place in the order
            el.inject(this.elements[pos], "before");
            var newOrder = this.currentOrder.slice(0, pos) || [];
            newOrder.push(this.elements.indexOf(el));
            this.currentOrder = newOrder.combine(this.currentOrder.slice(pos));
        }
        if (el.getStyle('position') == 'static') el.setStyle('position', 'relative');                              
        this.rearrangeDOM();
    }

});

this is being called like instance.adopt(someel, <optional pos>) where pos is a numeric position in the list. if omitted, it will append to tail. hope it helps...

Dimitar Christoff
  • 26,147
  • 8
  • 50
  • 69