Sharvari
Sharvari

Reputation: 257

How to create matrix table

I want to create dynamic matrix type data display using java script, html, and jquery which is shown here.

var reservations = [
    {"date":"22-12-2013","MCHC":"22","Pulse rate":"75","weight":"50" },
    {"date":"11-12-2013","CBC":"5"},
    {"date":"11-12-2013","weight":"55"}
];
var tbody = $('#reservations tbody'),
    props = ["date", "MCHC", "CBC", "Pulse rate", "weight"];

$.each(reservations, function(i, reservation) {
  var tr = $('<tr>');
  $.each(props, function(i, prop) {
       $('<td>').html(reservation[prop]).appendTo(tr);  
  });
  tbody.append(tr);
});

The problem is that the code is working properly but it does not display unique data based on date. For example, as shown in the above link "date:11-12-2013" is repeated twice which I don't want. I want to display unique data.

My desired output is: enter image description here

Upvotes: 6

Views: 13066

Answers (4)

Hasan A Yousef
Hasan A Yousef

Reputation: 24988

What about trying the below approach with Vanilla JS, I tried to make it simple and clean to be easily understood from the no JQuery fans, though it is getting benefits from the answers above.

var tbody = document.querySelector('#reservations').querySelector('tbody');
var props = ["date", "MCHC", "CBC", "Pulse rate", "weight"];

var reservations = [
    {"date":"22-12-2013","MCHC":"22","Pulse rate":"75","weight":"50" },
    {"date":"11-12-2013","CBC":"5"},
    {"date":"11-12-2013","weight":"55"}
];

var cache = {},
    date;
reservations.forEach(function(reservation, rIndex){
    date = reservation['date'];
    if (!cache[date]) {
      cache[date] = 'yes';
      var tr = tbody.insertRow(rIndex);
      tr.id = 'id'+date;
      props.forEach(function(){tr.insertCell();})
      tbody.appendChild(tr);
    } 
    var row = tbody.querySelector('#id'+date).rowIndex - 1;
    props.forEach(function(prop,pIndex){
       if(reservation[prop]) 
         tbody.rows[row].cells[pIndex].innerHTML=reservation[prop];
    })
});
table { border-collapse: collapse; }
<table id="reservations" border="2px;">
        <thead>
            <tr>
                <th>Date\Mesurment</th><th>MCHC</th><th>CBC</th><th>Pulse rate</th><th>weight</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
  </table>

For those who read from database, most likely there will be no 2 lines with the same date, so simple they can use the below JS code:

reservations.forEach(function(reservation, rIndex){
      var row = tbody.insertRow(rIndex);
      props.forEach(function(prop,pIndex){
        row.insertCell();
        if(reservation[prop]) 
             tbody.rows[rIndex].cells[pIndex].innerHTML=reservation[prop];
    })
});

Upvotes: 1

fbynite
fbynite

Reputation: 2661

Another solution would be to organize reservations before you start building the HTML.

You could do that by using a function like:

function uniqueReservation(reservations) {
  var results = [],
      cache = {}, 
      reservation,date;

  for (var i=0;i<reservations.length;i++) {
    reservation = reservations[i];
    date = reservation.date;

    if (!cache[date]) {
      cache[date] = {};
      results.push(cache[date]);
    } else {
        cache[date] = cache[date];
    }


    for (var k in reservation) {
        cache[date][k] = reservation[k];
    }
  }

  console.log('results',results);
  return results;
}


//before you pass reservations to $.each
reservations = uniqueReservation(reservations);

You could probably write this function a few different ways. However, the idea is the same - organize the data structure how you want it and then build up your HTML. Anyway, here is DEMO.

Upvotes: 1

CodeDeer
CodeDeer

Reputation: 742

var reservations = [{
"date": "22-12-2013",
    "MCHC": "22",
    "Pulse rate": "75",
    "weight": "50"
}, {
"date": "11-12-2013",
    "CBC": "5"
}, {
 "date": "11-12-2013",
    "weight": "55"
}];
var tbody = $('#reservations tbody'),
props = ["date", "MCHC", "CBC", "Pulse rate", "weight"];
$.each(reservations, function (i, reservation) {
//get the date value of the reservation
var tr = $('td:contains("' + reservation.date +'")').closest('tr');
if (tr.length <= 0)
{
     tr = $('<tr>');
}
$.each(props, function (i, prop) {
    var td = tr.children('.' + prop);
    if (td.length <= 0)
    {            $('<td>').html(reservation[prop]).appendTo(tr).addClass(prop.replace(/\s/g, ''));
    } else 
    {
        td.html(reservation[prop]);
    }
});
tbody.append(tr);
});

While this is similar to the response you already have it looks at the fact that Jquery does not like to have multiple elements with the same ID which the previous answer did with the columns.

Upvotes: 1

rynhe
rynhe

Reputation: 2529

Try this

Live Demo

var reservations = [
    {"date":"22-12-2013","MCHC":"22","Pulse rate":"75","weight":"50" },
    {"date":"11-12-2013","CBC":"5"},
    {"date":"11-12-2013","weight":"55"}
];
var tbody = $('#reservations tbody'),
    props = ["date", "MCHC", "CBC", "Pulse rate", "weight"];
$.each(reservations, function(i, reservation) {
  var trid = reservation["date"];
    if($("#"+trid).length <= 0) {
      var tr = $('<tr>').attr("id",trid);
      $.each(props, function(i, prop) {
        var tdid = prop.replace(/\s/g, '');
        $('<td>').html(reservation[prop]).attr("id",tdid).appendTo(tr);  
      });
      tbody.append(tr);
    }
    else {
      $.each(props, function(i, prop) {
        var tdid = prop.replace(/\s/g, '');
          $("#"+trid).find("td#"+tdid).html(reservation[prop])
      });  
    }
});

Upvotes: 7

Related Questions