12

I have a menu like this:

    <ul id="menu" class="undecorated"> 
        <li id="menuHome"><a href="/">Home</a> </li> 
        <li id="menuAbout"><a href="/Usergroup/About">About</a> </li> 
        <li id="menuArchives"><a href="/Usergroup/Archives">Archives</a> </li> 
        <li id="menuLinks"><a href="/Usergroup/Links">Links</a> </li> 
    </ul> 

Is there a simple way that I can use jquery to re-order elements? I'm imagining something like this:

$('#menuAbout').moveDown().moveDown()

But any other way of achieving this is appreciated.

meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
George Mauer
  • 117,483
  • 131
  • 382
  • 612

3 Answers3

33

It's actually not that hard. JQuery almost gets you there by itself with the insertBefore and insertAfter methods.

function moveUp($item) {
    $before = $item.prev();
    $item.insertBefore($before);
}

function moveDown($item) {
    $after = $item.next();
    $item.insertAfter($after);
}

You could use these like

moveDown($('#menuAbout'));

and the menuAbout item would move down.

If you wanted to extend jQuery to include these methods, you would write it like this:

$.fn.moveUp = function() {
    before = $(this).prev();
    $(this).insertBefore(before);
};

$.fn.moveDown = function() {
    after = $(this).next();
    $(this).insertAfter(after);
};

and now you can call the functions like

$("#menuAbout").moveDown();
Black
  • 18,150
  • 39
  • 158
  • 271
villecoder
  • 13,323
  • 2
  • 33
  • 52
  • Why do you use $variable for each variable, rather than just variable? Not that it’s invalid syntax — it’s just superfluous. – Jeremy Visser Sep 28 '09 at 10:03
  • 11
    True. But it also reminds me that I'm dealing with a jQuery object versus a regular variable/DOM object. – villecoder Sep 30 '09 at 13:36
5

No native prototypal methods, but you can make one easily:

$.fn.moveDown = function() {
    return this.each(function() {
        var next = $(this).next();
        if ( next.length ) {
            $(next).after(this);
        } else {
          $(this).parent().append( this );
        }
    })
}

$('#menuAbout').moveDown().moveDown()

This uses jQuery.prototype.after

meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
  • 1
    You can implement a moveUp by copying the function and replacing 'after' with 'before' and 'append(this)' with 'prepend(this)'. – meder omuraliev Sep 28 '09 at 02:34
1

You can also use display: flex on the parent then you can use order

function reset()
{
  jQuery("#a").css("order", 10);
  jQuery("#b").css("order", 20);
  jQuery("#c").css("order", 30);
}

function reorder1()
{
  jQuery("#a").css("order", 30);
  jQuery("#b").css("order", 20);
  jQuery("#c").css("order", 10);
}

function reorder2()
{
  jQuery("#a").css("order", 30);
  jQuery("#b").css("order", 10);
  jQuery("#c").css("order", 20);
}
#main { display: flex; }
#a { color: red; }
#b { color: blue; }
#c { color: green; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main">
    <div id="a">Foo</div>
    <div id="b">Bar</div>
    <div id="c">Baz</div>
</div>

<button onclick="reset()">Reset</button>
<button onclick="reorder1()">Reorder 1</button>
<button onclick="reorder2()">Reorder 2</button>
Black
  • 18,150
  • 39
  • 158
  • 271