Skip to content

Commit

Permalink
Fix sort - change name to sortElements as per this comment - http://j…
Browse files Browse the repository at this point in the history
  • Loading branch information
padolsey committed Jun 25, 2010
1 parent 58a36b1 commit 5f06ec5
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*/_notes
35 changes: 35 additions & 0 deletions sortElements/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
sort
---

The sort plugin is a very basic low-level element sorting function that allows you to sort DOM elements with a custom comparator (similar to `Array.prototype.sort`).

Assuming the following markup:

<ul>
<li>Banana</li>
<li>Carrot</li>
<li>Apple</li>
</ul>

You could sort the items alphabetically like so:

$('li').sort(function(a, b){
return $(a).text() > $(b).text() ? 1 : -1;
});

That would result in:

<ul>
<li>Apple</li>
<li>Banana</li>
<li>Carrot</li>
</ul>

It also let's you specify what element will be sorted. The current collection's elements will be those referred to as `a` and `b` on each call of the comparator, but you might not want those elements to be the ones to move. E.g. you might want it to be a parent. For example, when sorting a table column, you would sort by the `<td>` elements, but the elements you actually want to move within the DOM are the `<tr>` (each `<td>`'s parent):

$('td').sort(myComparator, function(){
// Return a reference to the desired element:
return this.parentNode;
});

See more info here: [http://james.padolsey.com/javascript/sorting-elements-with-jquery/](http://james.padolsey.com/javascript/sorting-elements-with-jquery/).
104 changes: 104 additions & 0 deletions sortElements/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Sort plugin for jQuery</title>
</head>
<body>

<h1>Demo</h1>

<p>Click on the headers (fruit/quantity).</p>

<table>
<thead>
<tr>
<th>Fruit</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td>Grape</td>
<td>15</td>
</tr>
<tr>
<td>Apple</td>
<td>4</td>
</tr>
<tr>
<td>Banana</td>
<td>88</td>
</tr>
<tr>
<td>Orange</td>
<td>11</td>
</tr>
<tr>
<td>Melon</td>
<td>21</td>
</tr>
<tr>
<td>Tomato</td>
<td>36</td>
</tr>
</tbody>
</table>

<button>Click to sort the list below</button>

<ul>
<li>Lamborghini</li>
<li>Farrari</li>
<li>Masarati</li>
<li>Aston Martin</li>
<li>Porche</li>
</ul>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="jquery.sort.js"></script>
<script>
var th = jQuery('th'),
li = jQuery('li'),
inverse = false;

th.click(function(){

var header = $(this),
index = header.index();

header
.closest('table')
.find('td')
.filter(function(){
return $(this).index() === index;
})
.sort(function(a, b){

a = $(a).text();
b = $(b).text();

return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;

}, function(){
return this.parentNode;
});

inverse = !inverse;

});

$('button').click(function(){
li.sort(function(a, b){
return $(a).text() > $(b).text() ? 1 : -1;
});
});
</script>

</body>
</html>
69 changes: 69 additions & 0 deletions sortElements/jquery.sortElements.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* jQuery.fn.sortElements
* --------------
* @author James Padolsey (http://james.padolsey.com)
* @version 0.11
* @updated 18-MAR-2010
* --------------
* @param Function comparator:
* Exactly the same behaviour as [1,2,3].sort(comparator)
*
* @param Function getSortable
* A function that should return the element that is
* to be sorted. The comparator will run on the
* current collection, but you may want the actual
* resulting sort to occur on a parent or another
* associated element.
*
* E.g. $('td').sortElements(comparator, function(){
* return this.parentNode;
* })
*
* The <td>'s parent (<tr>) will be sorted instead
* of the <td> itself.
*/
jQuery.fn.sortElements = (function(){

var sort = [].sort;

return function(comparator, getSortable) {

getSortable = getSortable || function(){return this;};

var placements = this.map(function(){

var sortElement = getSortable.call(this),
parentNode = sortElement.parentNode,

// Since the element itself will change position, we have
// to have some way of storing it's original position in
// the DOM. The easiest way is to have a 'flag' node:
nextSibling = parentNode.insertBefore(
document.createTextNode(''),
sortElement.nextSibling
);

return function() {

if (parentNode === this) {
throw new Error(
"You can't sort elements if any one is a descendant of another."
);
}

// Insert before flag:
parentNode.insertBefore(this, nextSibling);
// Remove flag:
parentNode.removeChild(nextSibling);

};

});

return sort.call(this, comparator).each(function(i){
placements[i].call(getSortable.call(this));
});

};

})();

0 comments on commit 5f06ec5

Please sign in to comment.