Select to view content in your preferred language

Sorting Table

2462
7
07-27-2010 07:51 AM
DanPajak
Occasional Contributor
Does any one know how to sort a table in javascript.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
<br>
<img src="http://addressfinder.palatine.il.us/Legend.jpg">
<a href="http://www.palatine.il.us/">
<center><img src="http://www.palatine.il.us/images/logo-txt.gif" border="0"></center>
</a>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7" />
    <title>Village of Palatine Address Finder</title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/1.5/js/dojo/dijit/themes/tundra/tundra.css">
    <script type="text/javascript"

src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.5"></script>
    <script type="text/javascript">
      dojo.require("esri.tasks.find");

      var find, params;
      function init() {
esri.hide(dojo.byId('loading'));
        find = new esri.tasks.FindTask("http://vopdb4/ArcGIS/rest/services/Address_Finder/Address_Finder/MapServer");
        params = new esri.tasks.FindParameters();
        params.layerIds = [0];
        params.searchFields = ["Full_Address","GIS_Key","PIN","Owner_Name","Occupant_Name"];
      }

      function doFind(event) {
esri.show(dojo.byId('loading'));
        params.searchText = dojo.byId("searchText").value;
        find.execute(params, showResults);
      }

      function showResults(results){
esri.hide(dojo.byId('loading'));
    var result, attribs;
    var s = ["<table border=\"10\"><thead><tr style=\"background-color:#A6D785;\"><td nowrap><font size=2.5><b>Full Address</font></td><td nowrap><font size=2.5><b>GIS Key</font></td><td nowrap><font size=2.5><b>PIN#</font></td><td nowrap><font size=2.5><b>Owner</font></td><td nowrap><font size=2.5><b>Owner Address</font></td><td nowrap><font size=2.5><b>Owner City</font></td><td nowrap><font size=2.5><b>Owner State</font></td><td nowrap><font size=2.5><b>Owner ZIP</font></td><td nowrap><font size=2.5><b>Owner Date</font></td><td nowrap><font size=2.5><b>Update Date</font></td><td nowrap><font size=2.5><b>Occupant</font></td><td nowrap><font size=2.5><b>Occupant Phone# 1</font></td><td nowrap><font size=2.5><b>Occupant Phone# 2</font></td><td nowrap><font size=2.5><b>In Village</font></td><td nowrap><font size=2.5><b>Active</font></td></tr></thead><tbody id=\"states\">"];
    for (var i = 0, il = results.length; i < il; i++) {
   result = results;
   attribs = result.feature.attributes;
  

if (attribs.Active === "N") {
    s.push("<tr style=\"background-color:#F28282;\"><td nowrap><font size=2.5> " + attribs.Full_Address + "</font></td><td nowrap><font size=2.5>" + attribs.GIS_Key + "</font></td><td nowrap><font size=2.5>" + attribs.PIN + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Address + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_City + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_State + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_ZIP + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Date + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Update + "</font></td><td nowrap><font size=2.5>" + attribs.Occupant_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone1 + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone2 + "</font></td><td nowrap><font size=2.5>" + attribs.Village + "</font></td><td nowrap><font size=2.5>" + attribs.Active + "</font></td></tr>");
    }
else if (attribs.Village === "N") {
    s.push("<tr style=\"background-color:#BDBDBD;\"><td nowrap><font size=2.5> " + attribs.Full_Address + "</font></td><td nowrap><font size=2.5>" + attribs.GIS_Key + "</font></td><td nowrap><font size=2.5>" + attribs.PIN + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Address + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_City + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_State + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_ZIP + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Date + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Update + "</font></td><td nowrap><font size=2.5>" + attribs.Occupant_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone1 + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone2 + "</font></td><td nowrap><font size=2.5>" + attribs.Village + "</font></td><td nowrap><font size=2.5>" + attribs.Active + "</font></td></tr>");
    }
else {
          s.push("<tr><td nowrap><font size=2.5> " + attribs.Full_Address + "</font></td><td nowrap><font size=2.5>" + attribs.GIS_Key + "</font></td><td nowrap><font size=2.5>" + attribs.PIN + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Address + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_City + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_State + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_ZIP + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Date + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Update + "</font></td><td nowrap><font size=2.5>" + attribs.Occupant_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone1 + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone2 + "</font></td><td nowrap><font size=2.5>" + attribs.Village + "</font></td><td nowrap><font size=2.5>" + attribs.Active + "</font></td></tr>");
   }

  }
 
  s.push("</tbody></table>");
  dojo.byId("tbl").innerHTML = s.join("");
}   
      dojo.addOnLoad(init);
    </script>

  </head>
  <body class="tundra">
<br>
<center>Find by Address, GIS Key, PIN#, Owner, or Occupant:  <input type="text" id="searchText" size="40" value="" />
<input type="submit" value="Find" onclick="doFind()" /></center>
<br>
    <center><div id="loading"><img src="http://help.arcgis.com/en/webapi/javascript/arcgis/demos/map/images/loading.gif" /></div>
    <div id="tbl"></div></td center>
<center><div id="tbl"></div>

  </body>
</html>
0 Kudos
7 Replies
TerryGiles
Occasional Contributor III
Javascript arrays have a sort() method that can be used to sort your data.  You might need to do it before constructing the html table but should be helpful.  See https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/sort for discussion on how it works.  Below is some code I've used before to sort results from an Identify task within a table cell.


         //inside of a switch statement looking at the layer name returned
         
         case 'Subdivision':
            tcell.innerHTML = "<span style='font-weight:bold'>Subdivision History (Name and Number, sorted most recent to oldest):</span>";
            tcell.innerHTML += "<br> <span style='font-style:italic'>For reference only - not to be relied upon as a legal search of the property.</span><br>";

            //need to loop thru all of the idResults that are sub history
            //date, name, docname, annsubid
            var featcount = 0;

            while (idResults.layerName == 'Subdivision') {
              featval = idResults.feature.attributes['SUBDATE'];
              sortlist[featcount] = new Array(2);
              sortlist[featcount][0] = new Date(featval).valueOf(); //get date in ms for sorting 
              sortlist[featcount][1] = "<a href='http://myserver/" + idResults.feature.attributes['LINK'] + "' target='_blank'>" + idResults.feature.attributes['NAME'] + " (" + idResults.feature.attributes['ID'] + ")</a><br>";

              featcount += 1;
              
            }

            
            //sort descending
            sortlist.sort(numbersort);
            for (var z = 0, iz = featcount; z < iz; z++) {
              tcell.innerHTML += sortlist[1];
            }
            break;
            
 //after the switch statement...add the cell to a table row and add that to the table above an existing row
   
 trow.appendChild(tcell);
    dojo.byId('tblbody').insertBefore(trow,dojo.byId('rowSummary'));        

// here's the basic function I used to sort numbers.  note it's taking in arrays

    function numbersort(a, b) {
      //sort the 1st element in 2 arrays descending
      //used to sort subs, agreements, PUD docs, etc...
      return b[0] - a[0]; 
    }

0 Kudos
DanPajak
Occasional Contributor
What section of my code would be the ideal area to add this example in?
0 Kudos
TerryGiles
Occasional Contributor III
You might try putting another for... loop above your existing one that builds a 2D array w/ the field you want to sort on in the 1st item and the full attributes of the associated feature in the second  -

sortlist = [];
for (var i = 0, il = results.length; i < il; i++) {
  result = results;
  attribs = result.feature.attributes;

  sortlist = new Array(2);
  sortlist[0] = attribs.PIN; //which ever field you want to sort on 
  sortlist[1] = attribs;
}
sortlist.sort(numbersort); 

//now run your existing for loop but at the top reset attribs = sortlist[1]
for (var i = 0, il = results.length; i < il; i++) {

attribs = sortlist[1];


if (attribs.Active === "N") {
s.push("<tr style=\"background-color:#F28282;\"><td nowrap><font size=2.5> " + attribs.Full_Address + "</font></td><td nowrap><font size=2.5>" + attribs.GIS_Key + "</font></td><td nowrap><font size=2.5>" + attribs.PIN + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Address + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_City + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_State + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_ZIP + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Date + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Update + "</font></td><td nowrap><font size=2.5>" + attribs.Occupant_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone1 + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone2 + "</font></td><td nowrap><font size=2.5>" + attribs.Village + "</font></td><td nowrap><font size=2.5>" + attribs.Active + "</font></td></tr>");
}
else if (attribs.Village === "N") {
s.push("<tr style=\"background-color:#BDBDBD;\"><td nowrap><font size=2.5> " + attribs.Full_Address + "</font></td><td nowrap><font size=2.5>" + attribs.GIS_Key + "</font></td><td nowrap><font size=2.5>" + attribs.PIN + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Address + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_City + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_State + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_ZIP + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Date + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Update + "</font></td><td nowrap><font size=2.5>" + attribs.Occupant_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone1 + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone2 + "</font></td><td nowrap><font size=2.5>" + attribs.Village + "</font></td><td nowrap><font size=2.5>" + attribs.Active + "</font></td></tr>");
}
else {
s.push("<tr><td nowrap><font size=2.5> " + attribs.Full_Address + "</font></td><td nowrap><font size=2.5>" + attribs.GIS_Key + "</font></td><td nowrap><font size=2.5>" + attribs.PIN + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Address + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_City + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_State + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_ZIP + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Date + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Update + "</font></td><td nowrap><font size=2.5>" + attribs.Occupant_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone1 + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone2 + "</font></td><td nowrap><font size=2.5>" + attribs.Village + "</font></td><td nowrap><font size=2.5>" + attribs.Active + "</font></td></tr>");
}

}




Give it a try and let me know if it works for you.  Also, you have 2 Divs in your body with the id of "tbl" and an extra </td> tag.
0 Kudos
DanPajak
Occasional Contributor
i tried the code but no table pops up after the search.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
<br>
<img src="http://addressfinder.palatine.il.us/Legend.jpg">
<a href="http://www.palatine.il.us/">
<center><img src="http://www.palatine.il.us/images/logo-txt.gif" border="0"></center>
</a>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7" />
    <title>Village of Palatine Address Finder</title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/1.5/js/dojo/dijit/themes/tundra/tundra.css">
    <script type="text/javascript"

src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.5"></script>
    <script type="text/javascript">
      dojo.require("esri.tasks.find");

      var find, params;
      function init() {
esri.hide(dojo.byId('loading'));
        find = new esri.tasks.FindTask("http://vopdb4/ArcGIS/rest/services/Address_Finder/Address_Finder/MapServer");
        params = new esri.tasks.FindParameters();
        params.layerIds = [0];
        params.searchFields = ["Full_Address","GIS_Key","PIN","Owner_Name","Occupant_Name"];
      }

      function doFind(event) {
esri.show(dojo.byId('loading'));
        params.searchText = dojo.byId("searchText").value;
        find.execute(params, showResults);
      }

      function showResults(results){
esri.hide(dojo.byId('loading'));
    var result, attribs;
    var s = ["<table border=\"10\"><thead><tr style=\"background-color:#A6D785;\"><td nowrap><font size=2.5><b>Full Address</font></td><td

nowrap><font size=2.5><b>GIS Key</font></td><td nowrap><font size=2.5><b>PIN#</font></td><td nowrap><font size=2.5><b>Owner</font></td><td nowrap><font

size=2.5><b>Owner Address</font></td><td nowrap><font size=2.5><b>Owner City</font></td><td nowrap><font size=2.5><b>Owner State</font></td><td nowrap><font

size=2.5><b>Owner ZIP</font></td><td nowrap><font size=2.5><b>Owner Date</font></td><td nowrap><font size=2.5><b>Update Date</font></td><td nowrap><font

size=2.5><b>Occupant</font></td><td nowrap><font size=2.5><b>Occupant Phone# 1</font></td><td nowrap><font size=2.5><b>Occupant Phone# 2</font></td><td

nowrap><font size=2.5><b>In Village</font></td><td nowrap><font size=2.5><b>Active</font></td></tr></thead><tbody id=\"states\">"];
    sortlist = [];
for (var i = 0, il = results.length; i < il; i++) {
  result = results;
  attribs = result.feature.attributes;

  sortlist = new Array(2);
  sortlist[0] = attribs.Full_Address; //which ever field you want to sort on
  sortlist[1] = attribs;
}
sortlist.sort(numbersort);

//now run your existing for loop but at the top reset attribs = sortlist[1]
for (var i = 0, il = results.length; i < il; i++) {

attribs = sortlist[1];


if (attribs.Active === "N") {
s.push("<tr style=\"background-color:#F28282;\"><td nowrap><font size=2.5> " + attribs.Full_Address + "</font></td><td nowrap><font size=2.5>" +

attribs.GIS_Key + "</font></td><td nowrap><font size=2.5>" + attribs.PIN + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Name + "</font></td><td

nowrap><font size=2.5>" + attribs.Owner_Address + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_City + "</font></td><td nowrap><font size=2.5>" +

attribs.Owner_State + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_ZIP + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Date +

"</font></td><td nowrap><font size=2.5>" + attribs.Owner_Update + "</font></td><td nowrap><font size=2.5>" + attribs.Occupant_Name + "</font></td><td

nowrap><font size=2.5>" + attribs.Occ_Phone1 + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone2 + "</font></td><td nowrap><font size=2.5>" +

attribs.Village + "</font></td><td nowrap><font size=2.5>" + attribs.Active + "</font></td></tr>");
}
else if (attribs.Village === "N") {
s.push("<tr style=\"background-color:#BDBDBD;\"><td nowrap><font size=2.5> " + attribs.Full_Address + "</font></td><td nowrap><font size=2.5>" +

attribs.GIS_Key + "</font></td><td nowrap><font size=2.5>" + attribs.PIN + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Name + "</font></td><td

nowrap><font size=2.5>" + attribs.Owner_Address + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_City + "</font></td><td nowrap><font size=2.5>" +

attribs.Owner_State + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_ZIP + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Date +

"</font></td><td nowrap><font size=2.5>" + attribs.Owner_Update + "</font></td><td nowrap><font size=2.5>" + attribs.Occupant_Name + "</font></td><td

nowrap><font size=2.5>" + attribs.Occ_Phone1 + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone2 + "</font></td><td nowrap><font size=2.5>" +

attribs.Village + "</font></td><td nowrap><font size=2.5>" + attribs.Active + "</font></td></tr>");
}
else {
s.push("<tr><td nowrap><font size=2.5> " + attribs.Full_Address + "</font></td><td nowrap><font size=2.5>" + attribs.GIS_Key + "</font></td><td nowrap><font

size=2.5>" + attribs.PIN + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Address +

"</font></td><td nowrap><font size=2.5>" + attribs.Owner_City + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_State + "</font></td><td nowrap><font

size=2.5>" + attribs.Owner_ZIP + "</font></td><td nowrap><font size=2.5>" + attribs.Owner_Date + "</font></td><td nowrap><font size=2.5>" +

attribs.Owner_Update + "</font></td><td nowrap><font size=2.5>" + attribs.Occupant_Name + "</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone1 +

"</font></td><td nowrap><font size=2.5>" + attribs.Occ_Phone2 + "</font></td><td nowrap><font size=2.5>" + attribs.Village + "</font></td><td nowrap><font

size=2.5>" + attribs.Active + "</font></td></tr>");
}

}
 
  s.push("</tbody></table>");
  dojo.byId("tbl").innerHTML = s.join("");
}   
      dojo.addOnLoad(init);
    </script>

  </head>
  <body class="tundra">
<br>
<center>Find by Address, GIS Key, PIN#, Owner, or Occupant:  <input type="text" id="searchText" size="40" value="" />
<input type="submit" value="Find" onclick="doFind()" /></center>
<br>
    <center><div id="loading"><img src="http://help.arcgis.com/en/webapi/javascript/arcgis/demos/map/images/loading.gif" /></div>
    <div id="tbl"></div></td center>
<center><div id="tbl"></div>

  </body>
</html>
0 Kudos
TerryGiles
Occasional Contributor III
Is the sort working?  After you call s.join(""), what's in s?  Can you take the content of s at this poitn and copy/paste it in another blank html file & have it display?  Does dojo.byId("tbl") return a valid DOM node?
0 Kudos
DanPajak
Occasional Contributor
The code above is not working.  There are no error showing on the page.  When i do the search it returns nothing but with no errors. So it must be something small that i am missing for this to work. The s join "" is refering to s.push and its content between " ".  As for the dojo.byId("tbl")  it has to be there to interact with arcserver and its search functionality.
0 Kudos
TerryGiles
Occasional Contributor III
What kind of environment are you developing in?  If you're using Visual Web Developer or something similar, can you put a break point in the code at s.push("</tbody></table>") and then execute s.join in the immediate window to see what s contains?  Is it valid HTML?

Another good debugging option is to use Firebug.  Do you have firefox and the firebug extension installed on your machine?  Try adding a few console.log() statements in the code to make sure the whole thing is running & to narrow down where the problem is. 

My question regarding if dojo.byId returning the correct DOM node  - since the html you posted has 2 divs with the same ID, I'm wondering what dojo.byId returns - my guess would be either the 1st one it finds or an error but I'm not sure which...

If the 1st for loop is working correctly and the sort is returning a valid array, then the problem might be in constructing the array s.  There are a lot of embedded quotes and opening and closing tags, one of which could be missing & difficult to find.  Instead of building the table as text, have you considered creating it using some of the DOM methods like createElement and appendChild and using CSS to apply all of the fonts and colors?  Here's a small sample of how you could use that instead -

       //make new row & cell to add layer info to
        trow = document.createElement('tr');
        tcell = document.createElement('td');
        
        
         //apply alternating style to the row - rowodd and roweven are classes in a CSS file with different background colors so the table has alternating row colors

        //NOTE - IE has issues w/ setting class have to work around by using non-standard className
        //see http://webbugtrack.blogspot.com/2007/08/bug-242-setattribute-doesnt-always-work.html
        if (rowcount % 2 == 0) {
          if (dojo.isIE) {trow.setAttribute("className","rowodd");  }
          else { trow.setAttribute("class", "rowodd"); }
        }
        else {
          if (dojo.isIE) { trow.setAttribute("className", "roweven"); }
          else { trow.setAttribute("class", "roweven"); }
        }
        
        
        //use data from the featureset attributes to fill the innerHTML of the tcell here.....
        //tcell.innerHTML = "name: " + attribs[NAME] ;
        
        
         trow.appendChild(tcell);
          
         //now append that row to a tablebody - in this case one that already exists..
         dojo.byId('tblbody').appendChild(trow);
         
         //example of inserting above the existing bottom row instead of appending..
         //dojo.byId('tblbody').insertBefore(trow,dojo.byId('rowBtmRow'));

          //increment rowstyle counter
          rowcount += 1;
        
0 Kudos