Domanda

I'm trying to insert div containers with class names into a box with other containers by defining class with numbers.

I'm able to get the following to work correctly as long as the markup is already in chronoligical order:

http://play.meyouand.us/140418-rearrange/rearrange4a.html

However if the markup order is in a mixed or reversed chronological order, the function doesn't position the div containers in the exact position (because the function I'm using is before()):

http://play.meyouand.us/140418-rearrange/rearrange4b.html

I'm currently stuck on how to solve this because I'm not sure if I should use the strategy of pre-sorting the boxes first, or if there's an existing jQuery function that can just place the div containers exactly where I need them which would make it an ideal and simple solution. Any thoughts on strategy or methodology will be helpful!

jQuery so far... - http://jsfiddle.net/foomarks/qM27z/2/

$('[class*=order-]').each(function() {

        /* 1. Split the classes to get an array */      
        var cl = $(this).prop('class').split(/\s+/);
        var clNumber = cl.map( function(val){
            if (val.indexOf('order-') !== -1) {  //find the match
            return val.replace( /^\D+/g, '')  // return back the number
            }
        });
        console.log("clNumber: " + clNumber[1]);

        /* 2. Presort boxes */
            /* Strategy A 
               . If this clNumber is greater than the next .order- box, append it after 
               . else do nothing 
            */

            /* Strategy B
               . Sort the array
               . then .append() the output
               . this may not work within the .each function because of sequencing
            */

        /* 3. Use the insert number to reposition */
        $(this).insertBefore('.box:nth-child('+ clNumber[1] + ')');    
    });
È stato utile?

Soluzione

My solution is this:

  1. stop using classes to store variables; that's what data- attributes are for.
  2. loop over the elements to be moved, creating an array of {element,order} pairs
  3. sort the pairs into proper order
  4. loop over the pairs doing the insert.

Working demo: http://jsfiddle.net/qM27z/3/

var tomove =
    $('[data-order]').map(function() {
        return { element: this, order: $(this).data("order") };
    }).get().sort(function(a,b) { return a.order-b.order; });

$.each(tomove, function(i, tm) {
    $(tm.element).insertBefore('.container .box:nth-child('+tm.order+')')
});

Altri suggerimenti

I have a feeling there's a cleaner way to do this, but this works:

jsFiddle example

var ary1 = $('div[class*="order-"]');
var ary2 = $('div.container div.box');
var total = ary1.length + ary2.length;
$('.container').empty();
for (var i = 1; i <= total; i++) {
    var match = false;
    ary1.each(function () {
        var cl = $(this).prop('class').split(/\s+/);
        var clNumber = cl.map(function (val) {
            if (val.indexOf('order-') !== -1) { //find the match
                return val.replace(/^\D+/g, '') // return back the number
            }
        });
        if (clNumber[1] == i) {
            $(this).appendTo('.container');
            match = true;
        }
    })
    if (!match) $('<div class="box">Box</div>').appendTo('.container')
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top