Search code examples
jquerysortingappendclonedetach

Detach, sort and reattach at the original position


I have the following HTML:

<div id="01" class="visible" data-owner="b"></div>
<div id="02" class="notvisible" data-owner="c"></div>
<div id="03" class="visible" data-owner="x"></div>
<div id="06" class="notvisible" data-owner="a"></div>
<div id="08" class="notvisible" data-owner="b"></div>

I want to group and filter the visible different rows into owner groups:

<div class="group" data-user-group="x">
  <div id="03" class="visible" data-owner="x"></div>
</div>
<div class="group" data-user-group="b">
  <div id="01" class="visible" data-owner="b"></div>
</div>

The jQuery Code for this works great:

function groupTheVisible() {
  $('div.group').each(function() {
    dataAnchor = $(this).attr('data-user-group');
    $('div.visible[data-owner="' + dataAnchor + '"]').detach().prependTo($(this));
  }  
}

function regroupTheVisible() {
  // ?
}

How can I group the visible rows back on the correct position in the original list? Thanks in advance!


Solution

  • It will be easier if your first list is located within a container, because in the extreme case that list could get empty and then the script needs to know where to create it again.

    So, I will assume a container div with id "basket".

    The snippet below also has some text in the div elements, so that the output shows what is happening.

    function groupTheVisible() {
        $("div.group").each(function() {
            var dataAnchor = $(this).attr("data-user-group");
            $('div.visible[data-owner="' + dataAnchor + '"]').prependTo(this);
        });
    }
    
    function regroupTheVisible() {
        $("div.group > div").each(function() {
            var dataId = $(this).attr("id");
            var $before = $("#basket > div").filter(function() {
                return $(this).attr("id") < dataId;
            });
            if ($before.length) {
                $before.last().after(this);
            } else {
                $("#basket").prepend(this);
            }
        });
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="basket">
        <div id="01" class="visible" data-owner="b">01-B-Visible</div>
        <div id="02" class="notvisible" data-owner="c">02-C-NotVisible</div>
        <div id="03" class="visible" data-owner="x">03-X-Visible</div>
        <div id="06" class="notvisible" data-owner="a">06-A-NotVisible</div>
        <div id="08" class="notvisible" data-owner="b">08-B-NotVisible</div>
    </div>
    
    <hr>
    
    <div class="group" data-user-group="x"></div>
    <div class="group" data-user-group="b"></div>
    
    <button onclick="groupTheVisible()">Group the Visible</button>
    <button onclick="regroupTheVisible()">Regroup the Visible</button>

    NB: Make sure to declare your variables with var (or let, const) to avoid that they become global variables.

    NB2: As you move elements, it is not really necessary to call detach on them.