Mike Resoli
Mike Resoli

Reputation: 967

Merging javascript objects into HTML table

I have two javascript objects, the contents of which came from these two HTML tables.

enter image description here

Each pre-merge table now has it's own object. The object is structured as follows:

enter image description here

The first array element within the object contains the column headers from the pre-merge tables, and the array elements following that contain the <tr> data from each table.

Is it possible to merge these two objects together to produce one HTML table? As you can see the in the pre-merge tables the x-value is shared between both, meaning it is common between the two objects too. I thought there may be a way of comparing these values, and then populating the table, but I'm not sure how.

I would like the merged table to look like the following:

x-value: common dates shared between objects columns: data from each of the pre-merge tables with their headers

enter image description here

Here is my code (you can also see it on this CodePenHere):

$(document).ready(function(){
  gatherData();
  results();
});

function gatherData(){
  data = [];

  tables = $('.before').find('table');

  $(tables).each(function(index){
    table = [];

    var headers = $(this).find('tr:first');
    var headerText = [];
    headerText.push($(headers).find('td:nth-child(1)').text());		
    headerText.push($(headers).find('td:nth-child(2)').text());
    table.push(headerText)
    $(this).find('tr').each(function(index){
      var rowContent = [];
      if (index != 0){
        $(this).find('td').each(function(index){
          rowContent.push($(this).text());
        })
      }
      table.push(rowContent)
    })

    data.push({table: table})
  });

  console.log(data)
}

function results(){
  var results = $('.after1').find('thead');

  $(results).append("<th>" + data[0].table[0][0] + "</th>");

  for (i in data){
    $(results).append("<th>" + data[i].table[0][1] + "</th>");
    var b = data[i].table.length;
    for (a = 2; a < b; a++){
      console.log(data[i].table[a][0] + " || " + data[i].table[a][1])
    }
  }
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

<div class="container">
  <h1 class="page-header">Formatter.js</h1>
</div>
<div class="container before">
  <h3>Before</h3>
  <table border=1 cellspacing=0 cellpadding=0 alignment="" class="a" id="3">
    <tbody>
      <tr>
        <td>x-value</td>
        <td>Operational Planned</td>
      </tr>
      <tr>
        <td>09/11/2015</td>
        <td>0</td>
      </tr>
      <tr>
        <td>10/11/2015</td>
        <td>0</td>
      </tr>
      <tr>
        <td>11/11/2015</td>
        <td>66358</td>
      </tr>
      <tr>
        <td>12/11/2015</td>
        <td>65990</td>
      </tr>
      <tr>
        <td>13/11/2015</td>
        <td>55993</td>
      </tr>
      <tr>
        <td>14/11/2015</td>
        <td>0</td>
      </tr>
      <tr>
        <td>15/11/2015</td>
        <td>0</td>
      </tr>
    </tbody>
  </table>
  <table border=1 cellspacing=0 cellpadding=0 alignment="" class="a" id="3">
    <tbody>
      <tr>
        <td>x-value</td>
        <td>Something Else</td>
      </tr>
      <tr>
        <td>09/11/2015</td>
        <td>0</td>
      </tr>
      <tr>
        <td>10/11/2015</td>
        <td>0</td>
      </tr>
      <tr>
        <td>11/11/2015</td>
        <td>2552</td>
      </tr>
      <tr>
        <td>12/11/2015</td>
        <td>86234</td>
      </tr>
      <tr>
        <td>13/11/2015</td>
        <td>33623</td>
      </tr>
      <tr>
        <td>14/11/2015</td>
        <td>0</td>
      </tr>
      <tr>
        <td>15/11/2015</td>
        <td>0</td>
      </tr>
    </tbody>
  </table>

  <hr>
</div>
<div class="container after">
  <h3>After</h3>
  <table class="table after1">
    <thead>
    </thead>
    <tbody>
    </tbody>
  </table>
</div>

Upvotes: 0

Views: 1156

Answers (1)

As I understand your issue, you want to merge the tables by the key values in coloumn x-value.

Here is how I would do it:

  1. Collect data from each table into a dictionary with coloumn x-value as key
  2. Save values for each key as array.

The main part is collecting the data in the dictionary. Here is the part:

var table = {
  header: [],
  data: {}
};

$(this).find('tr').each(function(index) {
  // ignore first row
  if (index === 0) return true;

  // read all data for row
  var rowData = [];
  $(this).find('td').each(function() {
    var value = $(this).text();
    rowData.push(value);
  });

  // key value for dictionery
  var key = rowData[0];

  // add value to array in dictionary if existing or create array
  if(table.data[key]) {
    table.data[key].push(rowData[1]);
  } else {
    table.data[key] = [rowData[1]];
  }
});

By using a simple javascript object as a dictionary we create properties on the fly, just like a dictionary.

See the plunker for the full script. I've written comments on the different parts to make the functionality clear. Let me know if anything is unclear.

As a note on your code. You can use multiple arguments in the jQuery selector to make your selections simpler, so this (see note below)

tables = $('.before').find('table');

can become this:

tables = $('.before table');

Edit

As noted by Mark Schultheiss in the comments, the later, but shorter syntax for jQuery selectors can be slower than the first one on large DOMs. So use the extended syntax on large DOMs. I've updated the plunker to use the better performing syntax.

Upvotes: 1

Related Questions