We help IT Professionals succeed at work.

Javascript to sort html table based on values in a column

mildurait
mildurait asked
on
647 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.
Comment
Watch Question

HonorGodSoftware Engineer
CERTIFIED EXPERT

Commented:

Title: custom javascript sorting using generic function
 URL: http://www.codeproject.com/useritems/custom_javascript_sorting.asp
CERTIFIED EXPERT

Author

Commented:
Thanks HonorGod

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

HonorGodSoftware Engineer
CERTIFIED EXPERT

Commented:
I have been trying... it is quite challenging... :-)
CERTIFIED EXPERT

Commented:
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

CERTIFIED EXPERT

Author

Commented:
<Here's a small challenge for a Javascript Guru.>
I thought so ;-)
Do you think it's possible?
CERTIFIED EXPERT

Author

Commented:
@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

CERTIFIED EXPERT

Commented:
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!
CERTIFIED EXPERT

Author

Commented:
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
CERTIFIED EXPERT

Author

Commented:
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>

CERTIFIED EXPERT

Author

Commented:
@HonorGod
How is your brew coming along?
CERTIFIED EXPERT

Author

Commented:
@fsze88
Do you have a clearer understanding of what I'm chasing?
CERTIFIED EXPERT

Commented:
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

CERTIFIED EXPERT
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
CERTIFIED EXPERT

Author

Commented:
@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?
CERTIFIED EXPERT

Author

Commented:
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!
CERTIFIED EXPERT

Commented:
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

HonorGodSoftware Engineer
CERTIFIED EXPERT

Commented:
Nicely done.
CERTIFIED EXPERT

Author

Commented:
@HonorGod.
Yeah... pretty cool hey.
Heh just wanted to say appreciate you putting Jesus out there mate - well done!
CERTIFIED EXPERT

Author

Commented:
@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.

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.