3

I found this question from before, here's the answer but I can't make it work. So the question is: I want to get all the values from the table into array, using javascript

HTML table:

<table id="cartGrid">
  <thead>
       <tr>
          <th>Item Description</th>
          <th>Qty</th>
          <th>Unit Price</th>
          <th>Ext Price</th>
       </tr>
  </thead>
<tbody>
    <tr><td>Old Lamp</td><td>1</td><td>107.00</td><td>107.00</td>
    <tr><td>Blue POst</td><td>2</td><td>7.00</td><td>14.00</td>
</tbody>
</table>

JavaScript:

var myTableArray = [];
$("table#cartGrid tr").each(function() {
    var arrayOfThisRow = [];
    var tableData = $(this).find('td');
    if (tableData.length > 0) {
        tableData.each(function() { arrayOfThisRow.push($(this).text()); });
        myTableArray.push(arrayOfThisRow);
    }
});

alert(myTableArray);

I found another option of doing it - but both return an empty array

var tableData = new Array();    
$('#cartGrid tr').each(function(row, tr){
    tableData[row]={
        "ItemDescription" : $(tr).find('td:eq(0)').text()
        , "Qty" :$(tr).find('td:eq(1)').text()
        , "UnitPrice" : $(tr).find('td:eq(2)').text()
        , "ExtPrice" : $(tr).find('td:eq(3)').text()
    }
}); 
tableData.shift();  // first row is the table header - so remove
CalvT
  • 3,123
  • 6
  • 37
  • 54
Slavik Ostapenko
  • 113
  • 1
  • 3
  • 10

3 Answers3

3

Making something of a guess, from your posted – not-working – code, I'd suggest the following, using jQuery:

// iterate over each of the <tr> elements within the
// <tbody>, using the map() method:
var details = $('tbody tr').map(function (i, row) {

    // creating an Object to return:
    return {

        // returning the key:value pair of
        // the hard-coded key-names against the
        // retrieved textContent (using the
        // HTMLTableRowElement's cells collection:
        'description': row.cells[0].textContent,
            'quantity': row.cells[1].textContent,
            'unitPrice': row.cells[2].textContent,
            'extPrice': row.cells[3].textContent
    }
// converting the map into an Array:
}).get();

console.log(details);

JS Fiddle demo.

Or, in plain JavaScript:

// using Array.prototype.map(), with Function.prototype.call(), to treat
// the Array-like NodeList returned by document.querySelectorAll(), as an
// Array; iterating over the found <tr> elements within the <tbody>:
var details = Array.prototype.map.call(document.querySelectorAll('tbody tr'), function (row) {
    // the first argument of the anonymous function (here: 'row') is
    // the array-element of the array over which we're iterating.

    // here we return exactly the same as before:
    return {
        'description': row.cells[0].textContent,
            'quantity': row.cells[1].textContent,
            'unitPrice': row.cells[2].textContent,
            'extPrice': row.cells[3].textContent
    };
});

console.log(details);

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
0

You could also take the heading of your table and create an 'object template' from it. So you have something like this:

{ Item_Description: '', Qty: '', Unit_Price: '', Exit_Price: '' }

And for mapping the row data later you can store each key in an array so you can easily access it for every row.

Please have a look at the demo below and here at jsFiddle.

But why do you need to get the data from the DOM? I think it would be better to get the data from the backend as JSON with an ajax request.

var tableData = [],
    objTmpl,
    objMap = [];

$("table#cartGrid tr").each(function() {
    var $row = $(this),
        key = '';
    
    //console.log($row.children().filter('th'));
    //check if heading
    var $headings = !objTmpl ? $row.children().filter('th'): []; // do this test only if objTmpl is undefined!
    //console.log($headings);
    if ( $headings.length > 0 ) {
        objTmpl = {};
        $headings.each(function(index) {
            key = $(this).text().replace(' ', '_'); 
            objTmpl[key] = '';
            objMap[index] = key;
        });
        //console.log('heading found', objTmpl, objMap);
    } else {
        // not heading --> data row
        var curRowDataObj = JSON.parse(JSON.stringify(objTmpl)); // copy tmpl.
        
        $row.children().each(function(index) {
            curRowDataObj[objMap[index]] = $(this).text();
        });
        
        tableData.push(curRowDataObj);
    }
});

//console.log(tableData);
$('#out').html(JSON.stringify(tableData, null, 4));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="cartGrid">
  <thead>
       <tr>
          <th>Item Description</th>
          <th>Qty</th>
          <th>Unit Price</th>
          <th>Ext Price</th>
       </tr>
  </thead>
<tbody>
    <tr><td>Old Lamp</td><td>1</td><td>107.00</td><td>107.00</td></tr>
    <tr><td>Blue POst</td><td>2</td><td>7.00</td><td>14.00</td></tr>
</tbody>
</table>

<h2>Output data (debugging only):</h2>
<pre id="out"></pre>
AWolf
  • 8,770
  • 5
  • 33
  • 39
  • Why do I use DOM? Here's the task that I have: 1. There's a form with 8 fields, one of them is date. When you fill the form all data goes to DB (PouchDB) 2. If date==today ->checked=true 3. User has an opportunity to check/uncheck rows of data 4. All checked rows of data have to be written into txt file ----------- So what I want to do is let user check/uncheck and then I will go thrue the DOM get that info into array and then parse it from the array to txt file. – Slavik Ostapenko May 26 '15 at 21:54
  • You don't have to use the DOM to manage your data. Keep them in you javascript and do the required checks there. Please have a look at the following [jsfiddle demo](http://jsfiddle.net/awolf2904/c2a2at8g/). The same is possible with jQuery but probably with more coding. (The date check is not in the demo but a filter for the selected items and textfile generation.) – AWolf May 27 '15 at 20:13
0

At this moment the shortest way would be:

var tableArray = [...document.querySelectorAll('table#cartGrid>*>tr')]
  .map(row => [...row.querySelectorAll('td,th')].map(cell => cell.innerText) );

Where [...x] is an implicit casting of x to an array. The last map is optional of course.

Stevelot
  • 159
  • 2
  • 4