views:

87

answers:

1

I want to display a "flipped" (transposed) data table. E.g. given some data:

[{col1: "abc", col2: 123}, {col1: "xxx", col2: 321}]

It's displayed as

+------+-----+-----+
| col1 | abc | xxx |
+------+-----+-----+
| col2 | 123 | 321 |
+------+-----+-----+

The rows should act the same as columns in a standard table.

Is there some JS Ajax component (like YUI DataTable or similar) that does this?

+1  A: 

Nice exercise. I think this is what you want:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Transposed table</title>
</head>
<body>
  <div id="wrapper"></div>
  <script>
    var tableData = [{col1: "abc", col2: 123},
                     {col1: "xxx", col2: 321}];

    function rotateData(theTable) {
        var result = [], i, j, key, keyFound;

        for (i = 0; i < theTable.length; ++i) {
            for (key in theTable[i]) {
                /* now loop through result[] to see if key already exists */
                keyFound = false;

                for (j = 0; j < result.length; ++j) {
                    if (result[j][0] == key) {
                        keyFound = true;
                        break;
                    }
                }

                if (!keyFound) {
                    result.push([]);  // add new empty array
                    result[j].push(key);  // add first item (key)
                }

                result[j].push(theTable[i][key]);
            }
        }

        return result;
    }

    function buildTable(theArray) {
        var html = [], n = 0, i, j;

        html[n++] = '<table>';

        for (i = 0; i < theArray.length; ++i) {
            html[n++] = '<tr>';
            for (j = 0; j < theArray[i].length; ++j) {
               html[n++] = '<td>';
               html[n++] = theArray[i][j];
               html[n++] = '</td>';
            }
            html[n++] = '</tr>';
        }

        html[n++] = '</table>';
        return html.join('');
    }

    var rotated = rotateData(tableData);
    var tableHtml = buildTable(rotated);
    document.getElementById('wrapper').innerHTML = tableHtml;
  </script>
</body>
</html>

Function rotateData rotates the objects' elements inside an array, so that you get an array like

[["col1", "abc", "xxx"], ["col2", 123, 321]]

For this the function tests if there is already an array element (in the outer array) containing the key, so it can add the value to its 'row', or it first creates a new element in the outer array with the key in its first 'column' and its value in the second.

Then buildTable creates the necessary HTML that can be inserted to every element that can contain a table. BTW, that function uses an array html to temporarily store the output and in the end joins all its elements to return a string. This is generally faster than (almost) endlessly concatenating a string.

Marcel Korpel
+1 for your work, but this isn't (exactly) what I want. I have no trouble transposing the data. The thing I want is an already existing component like YUI DataTable (or anything similar) that already does this and supports editing, sorting etc.
pablochan
@pablo: Aha. Unfortunately, I don't know any, but I'm not that much into libraries. I'll leave my answer as is, as it might be useful to someone else.
Marcel Korpel