-3

I have written the following code that displays a table of 4 columns on ajax success. I wish to sort this table based on the 4 columns. I tried doing it using some readymade .js files available online, but didn't succeed. How can I achieve the requirement?

function Success(data)
{
    var obj;
    obj=JSON.parse(data);
    document.write("<html><head><title>Browser Service</title></head>");
    **document.write("<script type='text/javascript', src='sorttable.js'>
    <\/script>");**
    document.write("<body bgcolor=#E0DCDC>");
    document.write("<div id=example-table>");
    document.write("<h2 align=center>Browser Version Details</h2>");
    document.write("<table class='**sortable**', border-collapse=collapse, 
    width=60%, border=1px solid #ddd, align=center>");
    document.write("<tr bgcolor=#209D9D>");
    document.write("<th height=50>");
    document.write("Name");
    document.write("</th>");
    document.write("<th height=50>");
    document.write("Number1");
    document.write("</th>");
    document.write("<th height=50>");
    document.write("Number2");
    document.write("</th>");
    document.write("<th height=50>");
    document.write("Number3");
    document.write("</th>");
    document.write("</tr>");
    document.write("<br>");

    for(i=0; i<obj.length; i=i+4)
    {
        document.write("<tr bgcolor=#ffffff>"); 
        document.write("<td align=center>");    
        document.write(obj[i]);
        document.write("</td>");    
        document.write("<td align=center>");    
        document.write(obj[i+1]);
        document.write("</td>");
        document.write("<td align=center>");    
        document.write(obj[i+2]);
        document.write("</td>");
        document.write("<td align=center>");    
        document.write(obj[i+3]);
        document.write("</td>");
        document.write("</tr>");    
    }

    document.write("</table>");
    document.write("</div>");
    document.write("</body></html>");
}

</script>

I have added a readily available sorttable.js file to achieve the purpose. I followed the link: https://www.kryogenix.org/code/browser/sorttable/

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
myna
  • 5
  • 4

1 Answers1

2

I felt like helping you out because I remember trying to create markup for tables and it can be tedious.

Some pointers:

  • try to keep your code dry ("don't repeat yourself") - so using loops can minimise the amount of code you need to write.
  • I created all the markup in one string in a reusable function and then attach it to the page rather than writing it out incrementally.
  • I've used CSS to style the table rather than inline styling which is very difficult to maintain.
  • I've attached event listeners to the th elements so that when you click on different columns, the data is sorted and then the markup is remade via a function. Note that because the markup changes, you then have to reattach the event listeners to the th elements so that you can sort by another column if you like.

I put some random data in for illustrative purposes.

var arr_data = [
  {
    "Name"   : "A",
    "Number1": 34,
    "Number2": 354,
    "Number3": 2
  },
    {
    "Name"   : "B",
    "Number1": 4356,
    "Number2": 45,
    "Number3": 57
  },
    {
    "Name"   : "C",
    "Number1": 9389,
    "Number2": 435,
    "Number3": 345
  },
    {
    "Name"   : "D",
    "Number1": 3,
    "Number2": 34,
    "Number3": 5645
  }
];


function buildTable( arr_data ){

  var html = '<table><thead><tr>';
  for( var key in arr_data[0] ){
    html += '<th>' + key + '</th>';
  }
  html += '</tr></thead><tbody>';
  
  arr_data.forEach(function(item){
    html += '<tr>';
    for( var prop in item ){
      html += '<td>' + item[prop] + '</td>';
    }
    html += '</tr>';
  });
  
  html += '</tbody></table>';
  return html;
}

(function init(){
  document.getElementsByClassName( 'table' )[0].innerHTML = buildTable( arr_data );
  attachEventListeners();
})();

function attachEventListeners(){
  var headers = document.getElementsByTagName( 'th' );
  for( var i = 0; i< headers.length; i++){
    var header = headers[i];
    header.addEventListener( 'click', function( event ){
      arr_data.sort( dynamicSort( this.innerHTML ) );
      document.getElementsByClassName( 'table' )[0].innerHTML = buildTable( arr_data );
      attachEventListeners();
    });
  }
}

// borrowed from https://stackoverflow.com/questions/1129216/sort-array-of-objects-by-string-property-value-in-javascript
function dynamicSort(property) {
  var sortOrder = 1;
  if(property[0] === "-") {
    sortOrder = -1;
    property = property.substr(1);
  }
  return function (a,b) {
    var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
    return result * sortOrder;
  }
}
table {
  border: 1px solid #dddddd;
  width: 60%;
  border-collapse: collapse;
}

thead tr {
  background-color: #209d9d;
  cursor: pointer;
}

thead tr th:hover {
  background-color: #1c8d8d;
}

tr {
  height: 50px;
}

th,
td {
  text-align: center;  
}
<div class="table"></div>
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
sauntimo
  • 1,531
  • 1
  • 17
  • 28
  • what if my array looks like this: var arr_data = [ A, B, C, D, E, F, G, H ]; and and I want to display this data in 4 columns(2 rows)? – myna Jul 20 '17 at 13:58
  • I don't understand, what is your data? if each number in the data array is the same field, you shouldn't display it in different columns in the data because that will confuse anyone looking at the table. If each number in the array *does not* represent the same field, then your data structure is poor and you should consider using an array of objects as I have in my example. I can write a function that will split your array up, but you should understand that what you're currently asking for doesn't make much sense. – sauntimo Jul 20 '17 at 13:58
  • var arr_data = [ A, 1, 2, 3, E, 3, 4, 4 ]; My data doesn't have a key. It just has values. – myna Jul 20 '17 at 13:59
  • assuming that the numbers are properties of the letters, you should structure this data as an array of objects `[ { "name" : "A", "number1" : 1, "number2" : 2, "number3" : 3 },{ "name" : "E", "number1" : 3, "number2" : 4, "number3" : 4} ]` - it doesn't make sense to have objects and their properties on the same level. – sauntimo Jul 20 '17 at 14:01
  • I'm actually retrieving the data from a text file, that looks like: A 1 2 3 E 3 4 4 – myna Jul 20 '17 at 14:01
  • Here's a function to format your arrays in to a usable array of objects, which you can then combine with my code above: https://jsfiddle.net/sauntimo/9e0rfo0g/ – sauntimo Jul 20 '17 at 14:14