2

This question is related to this question, but I have another issue which I need some help with. I would like to be able to group my divs into two groups - both sorted. The sorting already works, but how do I seperate my dovs up into two groups? The container divs in group 2 contains an element with class="anotherGroup".

the markup is this:

<div class="container">
  <div class="terminal" data-price="195">
      <h3>195</h3>
  </div>
  195 - I should come in 2nd in group 1 which is displayed first.
</div>

<div class="container">
  <div class="terminal" data-price="220">
      <h3>220</h3>
  </div>
  220 - I should come in 3rd in group 1 which is displayed first.
</div>

<div class="container">
  <div class="terminal" data-price="740">
      <h3>740</h3>
  </div>
  740 - I should come in 2nd in group 2 which is displayed last.
  <div class="anotherGroup">Group 2</div>
</div>

<div class="container">
  <div class="terminal" data-price="140">
      <h3>140</h3>
  </div>
  140 - I should come in 1st in group 2 which is displayed last.
  <div class="anotherGroup">Group 2</div>
</div>

<div class="container">
  <div class="terminal" data-price="130">
      <h3>130</h3>
  </div>
  130 - I should come in 1st in group 1 which is displayed first.
</div>

Script:

$('.terminal').sort(function (a, b) {
  return $(a).data('price') - $(b).data('price');
}).map(function () {
  return $(this).closest('.container');
}).each(function (_, container) {
  $(container).parent().append(container);
});

Fiddle here.

The final result should be:

130
195
220
140
740

Where 140 and 740 belong in a group of their own because they contain an element with the classname "anotherGroup". Hope this makes sense. Any help is very much appreciated.

Community
  • 1
  • 1
Meek
  • 3,086
  • 9
  • 38
  • 64

2 Answers2

1

You can dynamicaly add another data- with the group :

// attr() required for dynamic data-xxx
$('.terminal').attr('data-group', 'Group 1'); 
$('.anotherGroup').each(function(el) {
    $(this).prev('.terminal').attr('data-group', $(this).html());
});
// Result : <div class="terminal" data-price="140" data-group="Group 2">

And use a concatenation of data-group and data-price to compare your elements :

$('.terminal').sort(function (a, b) {
    var atxt = $(a).data('group')+$(a).data('price');
    var btxt = $(b).data('group')+$(b).data('price');
    return atxt.toLowerCase().localeCompare(btxt.toLowerCase());
}).map(function () {
    return $(this).closest('.container');
}).each(function (_, container) {
    $(container).parent().append(container);
});

Updated JsFiddle

Note : this will work for any group if you keep an alphabetical order ("Group 2", "Group 3"...)

zessx
  • 68,042
  • 28
  • 135
  • 158
1

This can be achieved using insertAfter:

var _count = 0;
$('.terminal').sort(function (a, b) {
    return $(a).data('price') - $(b).data('price');
}).map(function () {
    return $(this).closest('.container');
}).each(paint);

function paint(_, container) {
    if ($(container).children('.anotherGroup')[0]) {
        $(container).parent().append(container);
    } else {
        var next = paint.next;
        if (next) {
            $(container).insertAfter(next);
        } else {
            $(container).parent().prepend(container);
        }
        paint.next = container;
    }
};

Working Fiddle

Mr_Green
  • 40,727
  • 45
  • 159
  • 271