Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Javascript to sort html table based on values in a column

Posted on 2009-03-31
19
520 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
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

I've been trying to accomplish this for a while and it just struck me yesterday how to accomplish this task. I have done searches all over the internet looking for ways to email pages from my applications and finally I have done it!!! Every single s…
JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
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…

808 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