Solved

Javascript to sort html table based on values in a column

Posted on 2009-03-31
19
519 Views
Last Modified: 2012-05-06
Here's a small challenge for a Javascript Guru.
I would like function to dynamically reorder <tr> nodes in a <tbody> container detailed as below.

function reOrder(tb,ci1,ci2,ci3){
  ...experts code here
  }

parameters
tb : <tbody> node
ci1 : column index (1-based) Primary Sort Colum (If zero, don't sort)
ci2 : column index (1-based) Secondary Sort Column (If zero, don't sort)
ci3 : column index (1-based) Tertiary Sort Column (If zero, don't sort)
ord: 1=ascending sort, 2=descending sort

My table would be formatted like:
<table>
     <tr>
          <td onclick=""reOrder(myTBody,1,0,0);">ID</td>
          <td onclick=""reOrder(myTBody,2,3,1);">Name</td>
          <td onclick=""reOrder(myTBody,3,2,1);">DOB</td></tr>"
     </tr>
     <tbody id="myTBody">
         <tr>
            <td sortvalue="0000001">1</td>
            <td sortvalue="Peter">Peter</td>
            <td sortvalue="19750119">19/01/1975</td>
          </tr>
           <tr>
              <td sortvalue="0000002">2</td>
              <td sortvalue="Mark">Mark</td>
              <td sortvalue="19880731">31/07/1988</td>
           </tr>
            <tr>
                <td sortvalue="0000003">3</td>
                <td sortvalue="Jane">Jane</td>
                <td sortvalue="19600201">01/02/1960</td>
            </tr>
     </tbody>
</table>

Please note, I would like to sort on the sortvalue property of each td node rather than the value displayed.
0
Comment
Question by:mildurait
  • 11
  • 5
  • 3
19 Comments
 
LVL 41

Expert Comment

by:HonorGod
ID: 24035437

Title: custom javascript sorting using generic function
 URL: http://www.codeproject.com/useritems/custom_javascript_sorting.asp
0
 
LVL 11

Author Comment

by:mildurait
ID: 24035617
Thanks HonorGod

Are you able to translate into the format in my question?
function reOrder(tb,ci1,ci2,ci3){
  ...experts code here
  }

0
 
LVL 41

Expert Comment

by:HonorGod
ID: 24035695
I have been trying... it is quite challenging... :-)
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 15

Expert Comment

by:fsze88
ID: 24035709
okey try this
<table>
     <tr>
          <td onclick="reOrder('myTBody',1,0,0);">ID</td>
          <td onclick="reOrder('myTBody',2,3,1);">Name</td>
          <td onclick="reOrder('myTBody',3,2,1);">DOB</td></tr>
     </tr>
     <tbody id="myTBody">
         <tr ordernum=1>
            <td sortvalue="0000001">1</td>
            <td sortvalue="Peter">Peter</td>
            <td sortvalue="19750119">19/01/1975</td>
          </tr>
           <tr ordernum=2>
              <td sortvalue="0000002">2</td>
              <td sortvalue="Mark">Mark</td>
              <td sortvalue="19880731">31/07/1988</td>
           </tr>
            <tr ordernum=3>
                <td sortvalue="0000003">3</td>
                <td sortvalue="Jane">Jane</td>
                <td sortvalue="19600201">01/02/1960</td>
            </tr>
     </tbody>
</table>
 
<script type="text/javascript">
var trTagsArray = new Array();
function initTBody(){
  var tbodytag = document.getElementById("myTBody");
  var tbodytagChilds = tbodytag.childNodes
  var i = 0;
  for (i=0;i<tbodytagChilds.length;i++){
    if (tbodytagChilds[i].nodeName == "TR"){
      trTagsArray.push(tbodytagChilds[i]);
    }
  }
 
}
function reOrder(tbodyid,o1,o2,o3){
  var tbodytag = document.getElementById(tbodyid);
  var tbodytagChilds = tbodytag.childNodes
  var i = 0;
  
  while (tbodytagChilds.length > 0){
    tbodytag.removeChild(tbodytagChilds[0]);
  }
  
  for (i=0;i<trTagsArray.length;i++){
    if (trTagsArray[i].attributes['ordernum'].value == o1){
      tbodytag.appendChild(trTagsArray[i]);
    }
  }
  for (i=0;i<trTagsArray.length;i++){
    if (trTagsArray[i].attributes['ordernum'].value == o2){
      tbodytag.appendChild(trTagsArray[i]);
    }
  }
  for (i=0;i<trTagsArray.length;i++){
    if (trTagsArray[i].attributes['ordernum'].value == o3){
      tbodytag.appendChild(trTagsArray[i]);
    }
  }
}
 
initTBody();
</script>

Open in new window

0
 
LVL 11

Author Comment

by:mildurait
ID: 24035712
<Here's a small challenge for a Javascript Guru.>
I thought so ;-)
Do you think it's possible?
0
 
LVL 11

Author Comment

by:mildurait
ID: 24035733
@fsze88

Great start: looks like you are headed in the right direction, however this is the outcome i am getting.

<ID Sort> - Missing records 2 and 3
ID Name DOB
1 Peter 19/01/1975

<Name Sort>  Should be Jane, Mark, Peter
ID Name DOB
2 Mark 31/07/1988
3 Jane 01/02/1960
1 Peter 19/01/1975

<DOB Clicked> Should be 01/02/1960, 31/07/1988, 19/01/1975
ID Name DOB
3 Jane 01/02/1960
2 Mark 31/07/1988
1 Peter 19/01/1975

0
 
LVL 15

Expert Comment

by:fsze88
ID: 24035771
mildurait,
1)
I sorted the order by
          <td onclick="reOrder('myTBody',1,0,0);">ID</td>
          <td onclick="reOrder('myTBody',2,3,1);">Name</td>
          <td onclick="reOrder('myTBody',3,2,1);">DOB</td></tr>
ID: 1,0,0, Name : 2,3,1, DOB: 3,2,1
that's not what you are looking for?
2)
you want sorted by td attributes?
            <td sortvalue="0000001">1</td>
            <td sortvalue="Peter">Peter</td>
            <td sortvalue="19750119">19/01/1975</td>
if yes (case 2), what is ID: 1,0,0, Name : 2,3,1, DOB: 3,2,1 stand for?
THANKS!
0
 
LVL 11

Author Comment

by:mildurait
ID: 24035807
Id like my function to sort by values held in the sortvalue attribute of the <td>
eg
<td sortvalue="0000001">1</td>                         Sort on 0000001
<td sortvalue="Peter">Peter</td>                        Sort on Peter      
<td sortvalue="19750119">19/01/1975</td>      Sort on 19750119

ci1, ci2, ci1
In this case
reOrder(myTBody,1,0,0) should sort by column 1 (ID)
reOrder(myTBody,2,3,1) should sort by column 2 (Name) then Column 3 (DOB) then column (1) ID
reOrder(myTBody,3,2,1) should sort by column 3 (DOB) then Column 2 (Name) then column (1) ID
0
 
LVL 11

Author Comment

by:mildurait
ID: 24035813
If you add another few records to the table, you will be able to test your secondary and tertiary sorts

            <tr>
              <td sortvalue="0000004">4</td>
              <td sortvalue="Mark">Mark</td>
              <td sortvalue="19711212">12/12/1971</td>
           </tr>
           <tr>
              <td sortvalue="0000005">5</td>
              <td sortvalue="Andrew">Andrew</td>
              <td sortvalue="19711212>12/12/1971</td>
           </tr>
          <tr>
              <td sortvalue="0000006">6</td>
              <td sortvalue="Andrew">Andrew</td>
              <td sortvalue="19711212>12/12/1971</td>
           </tr>

0
 
LVL 11

Author Comment

by:mildurait
ID: 24035817
@HonorGod
How is your brew coming along?
0
 
LVL 11

Author Comment

by:mildurait
ID: 24035913
@fsze88
Do you have a clearer understanding of what I'm chasing?
0
 
LVL 15

Expert Comment

by:fsze88
ID: 24035929
yes, I understood!
this is approaching your answer....
Please, try it first and let me know any enchancement.
Note : I may goto lunch, but I will back soon..
<table>
     <tr>
          <td onclick="reOrder('myTBody',1,0,0);">ID</td>
          <td onclick="reOrder('myTBody',2,3,1);">Name</td>
          <td onclick="reOrder('myTBody',3,2,1);">DOB</td></tr>
     </tr>
     <tbody id="myTBody">
         <tr ordernum=1>
            <td sortvalue="0000001">1</td>
            <td sortvalue="Peter">Peter</td>
            <td sortvalue="19750119">19/01/1975</td>
          </tr>
           <tr ordernum=2>
              <td sortvalue="0000002">2</td>
              <td sortvalue="Mark">Mark</td>
              <td sortvalue="19880731">31/07/1988</td>
           </tr>
            <tr ordernum=3>
                <td sortvalue="0000003">3</td>
                <td sortvalue="Jane">Jane</td>
                <td sortvalue="19600201">01/02/1960</td>
            </tr>
     </tbody>
</table>
 
<script type="text/javascript">
var trTagsArray = new Array();
 
function initTBody(){
  var tbodytag = document.getElementById("myTBody");
  var tbodytagChilds = tbodytag.childNodes
  var i = 0;
  for (i=0;i<tbodytagChilds.length;i++){
    if (tbodytagChilds[i].nodeName == "TR"){
      trTagsArray.push(tbodytagChilds[i]);
    }
  }
}
 
 
function reOrder(tbodyid,o1,o2,o3){
  var tbodytag = document.getElementById(tbodyid);
  var tbodytagChilds = tbodytag.childNodes
  var i = 0;
  var smallestSortValue = "ZZZZZZZZZZ";
  var smallestIndex;
  var tempArray = new Array().concat(trTagsArray);
  
  while (tbodytagChilds.length > 0){
    tbodytag.removeChild(tbodytagChilds[0]);
  }
  
  while (tempArray.length > 0){
    smallestSortValue = "ZZZZZZZZZZ";
    for (i=0;i<tempArray.length;i++){
      if (getSortValue(tempArray[i],o1) < smallestSortValue){
        smallestSortValue = getSortValue(tempArray[i],o1);
        smallestIndex = i;
      }
    }
    tbodytag.appendChild(tempArray[smallestIndex]);
    tempArray.splice(smallestIndex,1);
    
  }  
 
}
 
function getSortValue(trTag,tagIndex){
  var trTagChilds = trTag.childNodes;
  var indexedTdTag;
  var numTdTag = 0;
  var j=0;
  for (j=0;j<trTagChilds.length;j++){
    if (trTagChilds[j].nodeName == "TD"){
      ++numTdTag;
      if (tagIndex == numTdTag){
        indexedTdTag = trTagChilds[j];
        break;
      }
    }
  }
  return indexedTdTag.attributes['sortvalue'].value;
}
 
initTBody();
</script>

Open in new window

0
 
LVL 15

Accepted Solution

by:
fsze88 earned 500 total points
ID: 24036901
sorted all 2,3,1
<table>
     <tr>
          <td onclick="reOrder('myTBody',1,0,0);">ID</td>
          <td onclick="reOrder('myTBody',2,3,1);">Name</td>
          <td onclick="reOrder('myTBody',3,2,1);">DOB</td></tr>
     </tr>
     <tbody id="myTBody">
         <tr ordernum=1>
            <td sortvalue="0000001">1</td>
            <td sortvalue="Peter">Peter</td>
            <td sortvalue="19750119">19/01/1975</td>
          </tr>
            <tr ordernum=3>
                <td sortvalue="0000004">4</td>
                <td sortvalue="Jane">Jane</td>
                <td sortvalue="19760201">01/02/1976</td>
            </tr>
           <tr ordernum=2>
              <td sortvalue="0000002">2</td>
              <td sortvalue="Mark">Mark</td>
              <td sortvalue="19880731">31/07/1988</td>
           </tr>
            <tr ordernum=3>
                <td sortvalue="0000003">3</td>
                <td sortvalue="Jane">Jane</td>
                <td sortvalue="19600201">01/02/1960</td>
            </tr>
     </tbody>
</table>
 
<script type="text/javascript">
var trTagsArray = new Array();
 
function initTBody(){
  var tbodytag = document.getElementById("myTBody");
  var tbodytagChilds = tbodytag.childNodes
  var i = 0;
  for (i=0;i<tbodytagChilds.length;i++){
    if (tbodytagChilds[i].nodeName == "TR"){
      trTagsArray.push(tbodytagChilds[i]);
    }
  }
}
 
 
function reOrder(tbodyid,o1,o2,o3){
  var tbodytag = document.getElementById(tbodyid);
  var tbodytagChilds = tbodytag.childNodes;
  var splicedTrTag;
  var oValue;
  var i = 0;
  var smallestSortValue = "ZZZZZZZZZZ";
  var smallestIndex;
  var tempArray = new Array().concat(trTagsArray);
  var tempArray2 = new Array();
  
  while (tbodytagChilds.length > 0){
    tbodytag.removeChild(tbodytagChilds[0]);
  }
 
 
 
  for (var k=3;k>=1;k--){
    oValue = eval("o" + k);
    while (tempArray.length > 0){
      smallestSortValue = "ZZZZZZZZZZ";
      for (i=0;i<tempArray.length;i++){
        if (getSortValue(tempArray[i],oValue) < smallestSortValue){
          smallestSortValue = getSortValue(tempArray[i],oValue);
          smallestIndex = i;
        }
      }
      tbodytag.appendChild(tempArray[smallestIndex]);
      splicedTrTag = tempArray[smallestIndex];
      tempArray.splice(smallestIndex,1);
      tempArray2.push(splicedTrTag);
    }  
    
    tempArray = new Array().concat(tempArray2);
    tempArray2 = new Array();
  }
 
}
 
function getSortValue(trTag,tagIndex){
  var trTagChilds = trTag.childNodes;
  var indexedTdTag;
  var numTdTag = 0;
  var j=0;
  var returnValue = "";
  for (j=0;j<trTagChilds.length;j++){
    if (trTagChilds[j].nodeName == "TD"){
      ++numTdTag;
      if (tagIndex == numTdTag){
        indexedTdTag = trTagChilds[j];
        break;
      }
    }
  }
  
  try{
    returnValue = indexedTdTag.attributes['sortvalue'].value;
  }catch(err){
    returnValue = "";
  }
  
  return returnValue;
}
 
initTBody();
</script>

Open in new window

0
 
LVL 11

Author Comment

by:mildurait
ID: 24037461
@fsze88
I must say brilliant work my friend.
Just when I am working with a recordset of say 1000 rows, it's a bit tardy and invokes script cancellation dialog in IE.
Any suggestions to make it work faster?
0
 
LVL 11

Author Closing Comment

by:mildurait
ID: 31565133
Works brilliantly for tables of 100 rows.
With a small tweek to the initBody function I was able to get the code to work with multiple tbody containers on the one page.
Thanks, I could not have done this by myself!
0
 
LVL 15

Expert Comment

by:fsze88
ID: 24037744
try this, this should be a bit faster.. But a bit....
it is bubble sort technology... If you still want it to be faster, try another methods (insertion sort,Quicksort,Comb sort,Cocktail sort .....)
http://en.wikipedia.org/wiki/Bubble_sort
Thanks for your appreciate
<table>
     <tr>
          <td onclick="reOrder('myTBody',1,0,0);">ID</td>
          <td onclick="reOrder('myTBody',2,3,1);">Name</td>
          <td onclick="reOrder('myTBody',3,2,1);">DOB</td></tr>
     </tr>
     <tbody id="myTBody">
         <tr ordernum=1>
            <td sortvalue="0000001">1</td>
            <td sortvalue="Peter">Peter</td>
            <td sortvalue="19750119">19/01/1975</td>
          </tr>
            <tr ordernum=3>
                <td sortvalue="0000004">4</td>
                <td sortvalue="Jane">Jane</td>
                <td sortvalue="19760201">01/02/1976</td>
            </tr>
           <tr ordernum=2>
              <td sortvalue="0000002">2</td>
              <td sortvalue="Mark">Mark</td>
              <td sortvalue="19880731">31/07/1988</td>
           </tr>
            <tr ordernum=3>
                <td sortvalue="0000003">3</td>
                <td sortvalue="Jane">Jane</td>
                <td sortvalue="19600201">01/02/1960</td>
            </tr>
     </tbody>
</table>
 
<script type="text/javascript">
var trTagsArray = new Array();
 
function initTBody(){
  var tbodytag = document.getElementById("myTBody");
  var tbodytagChilds = tbodytag.childNodes
  var i = 0;
  for (i=0;i<tbodytagChilds.length;i++){
    if (tbodytagChilds[i].nodeName == "TR"){
      trTagsArray.push(tbodytagChilds[i]);
    }
  }
}
 
 
function reOrder(tbodyid,o1,o2,o3){
  var tbodytag = document.getElementById(tbodyid);
  var tbodytagChilds = tbodytag.childNodes;
  var splicedTrTag;
  var oValue;
  var i = 0;
  var smallestSortValue = "ZZZZZZZZZZ";
  var smallestIndex;
  var tempArray = new Array().concat(trTagsArray);
  var tempArray2 = new Array();
  var sortValue="";
  while (tbodytagChilds.length > 0){
    tbodytag.removeChild(tbodytagChilds[0]);
  }
 
 
 
  for (var k=3;k>=1;k--){
    oValue = eval("o" + k);
    while (tempArray.length > 0){
      smallestSortValue = "ZZZZZZZZZZ";
      for (i=0;i<tempArray.length;i++){
        sortValue = getSortValue(tempArray[i],oValue);
        if (sortValue < smallestSortValue){
          smallestSortValue = sortValue;
          smallestIndex = i;
        }
      }
//      tbodytag.appendChild(tempArray[smallestIndex]);
      splicedTrTag = tempArray[smallestIndex];
      tbodytag.appendChild(splicedTrTag);
      tempArray.splice(smallestIndex,1);
      tempArray2.push(splicedTrTag);
    }  
    
    tempArray = new Array().concat(tempArray2);
    tempArray2 = new Array();
  }
 
}
 
function getSortValue(trTag,tagIndex){
  var trTagChilds = trTag.childNodes;
  var indexedTdTag;
  var numTdTag = 0;
  var j=0;
  var returnValue = "";
  for (j=0;j<trTagChilds.length;j++){
    if (trTagChilds[j].nodeName == "TD"){
      ++numTdTag;
      if (tagIndex == numTdTag){
        indexedTdTag = trTagChilds[j];
        break;
      }
    }
  }
  
  try{
    returnValue = indexedTdTag.attributes['sortvalue'].value;
  }catch(err){
    returnValue = "";
  }
  
  return returnValue;
}
 
initTBody();
</script>

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
ID: 24038249
Nicely done.
0
 
LVL 11

Author Comment

by:mildurait
ID: 24038285
@HonorGod.
Yeah... pretty cool hey.
Heh just wanted to say appreciate you putting Jesus out there mate - well done!
0
 
LVL 11

Author Comment

by:mildurait
ID: 24038377
@fsze88
I am going to open up another question, asking for quicksort method of sorting the array.
Might be another easy 500 points for you.
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Avoid defining the variables in the global scope; trying to define them in a local function scope. Because:   • Look-up is performed every time a variable is accessed.   • Variables are resolved backwards from most specific to least specific scope…
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question