Solved

Javascript to sort html table based on values in a column

Posted on 2009-03-31
19
515 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
 
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

In this article, we'll look how to sort an Array in JavaScript, including the more advanced techniques of sorting a collection of records either ascending or descending on two or more fields. Basic Sorting of Arrays First, let's look at the …
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
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…

757 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now