Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move list item to top of unordered list using jQuery

Tags:

jquery

Lets say i have the following unordered list

<ul>  <li><a>Hank</a></li>  <li><a>Alice</a></li>  <li><a>Tom</a></li>  <li><a>Ashlee</a></li> </ul> 

What im looking for is when i click on Tom, that it moves (animated and without dragging) to the top of the list (index 0).

Ive considered jquery sortable, but i cant find a way to activate the moving part programmatically.

like image 649
Fabian Avatar asked Oct 26 '09 17:10

Fabian


2 Answers

Found this even neater:

$('li').on('click', function() {     $(this).parent().prepend(this); });​ 

Live example

like image 157
jacktheripper Avatar answered Sep 19 '22 13:09

jacktheripper


I came up with a solution that seems to work pretty well. It's a proof of concept, so you'll probably have to modify it a bit to work better for your specific case. Also, I only tested it in Firefox, but I don't see any reason why this wouldn't work in all the browsers. Anyway, here it is:

<script type="text/javascript">   $(document).ready(function() {     $('li').click(function() {       // the clicked LI       var clicked = $(this);        // all the LIs above the clicked one       var previousAll = clicked.prevAll();        // only proceed if it's not already on top (no previous siblings)       if(previousAll.length > 0) {         // top LI         var top = $(previousAll[previousAll.length - 1]);          // immediately previous LI         var previous = $(previousAll[0]);          // how far up do we need to move the clicked LI?         var moveUp = clicked.attr('offsetTop') - top.attr('offsetTop');          // how far down do we need to move the previous siblings?         var moveDown = (clicked.offset().top + clicked.outerHeight()) - (previous.offset().top + previous.outerHeight());          // let's move stuff         clicked.css('position', 'relative');         previousAll.css('position', 'relative');         clicked.animate({'top': -moveUp});         previousAll.animate({'top': moveDown}, {complete: function() {           // rearrange the DOM and restore positioning when we're done moving           clicked.parent().prepend(clicked);           clicked.css({'position': 'static', 'top': 0});           previousAll.css({'position': 'static', 'top': 0});          }});       }     });   }); </script>  <ul>  <li><a>Hank</a></li>  <li><a>Alice</a></li>  <li><a>Tom</a></li>  <li><a>Ashlee</a></li> </ul> 

It calculates the difference in offsets between the clicked LI and first LI and moves the clicked one up to the top by setting its position to relative and animating the top property. Similarly, it calculates how much space was left behind by the clicked LI and moves all the previous ones down accordingly. When it's done with the animations, it rearranges the DOM to match the new order and restores the positioning styles.

Hope that helps!

like image 29
No Surprises Avatar answered Sep 21 '22 13:09

No Surprises