0

I wanted to create a HTML table with onclick function to get the key and value of a row, so far the onclick function is working but it displaying and empty array for me, how can I fix this problem. Thanks.

I wanted it to be display in console log in this format when you click on the first row:

{ "name":"Clark", "age":29};

Here is my code

var table = document.getElementById("tableID");
if (table != null) {
  for (var i = 0; i < table.rows.length; i++) {
    table.rows[i].onclick = function() {
      tableText(this);
    };
  }
}

function tableText(tableRow) {
  var myJSON = JSON.stringify(tableRow);
  console.log(myJSON);
}
<table align="center" id="tableID" border="1" style="cursor: pointer;">
<thead>
    <tr>
        <th hidden="hidden"></th>
        <th>name</th>
        <th>age</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td >Clark</td>
        <td>29</td>
    </tr>
    <tr>
        <td >Bruce</td>
        <td>30</td>
    </tr>
</tbody>
</table>
M.Izzat
  • 1,086
  • 4
  • 22
  • 50
  • You are passing a DOM element (i.e. a host object) to JSON.stringify, are you sure that should work? See [*How to serialize DOM node to JSON even if there are circular references?*](https://stackoverflow.com/questions/32377345/is-there-a-way-to-json-stringify-an-html-dom-object-javascript). – RobG Jun 02 '17 at 02:12
  • Hi @RobG thanks your reply, I guess I went to a wrong direction. My goal is to get the entire row object onClick so i can pass it later to edit a REST API Framework later. for now i just want to get the object in JSON format. can you help me with that. thanks – M.Izzat Jun 02 '17 at 02:18
  • The stringified (serialised) version of a TR would be its [*outerHTML*](https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML), which can be passed as a string then parsed back to a DOM object using an HTML parser. I think JSON is the wrong tool in this case. – RobG Jun 02 '17 at 02:20
  • i see, any suggestion? – M.Izzat Jun 02 '17 at 02:21
  • Per the first comment, you can manually serialise the element but that seems a bit extreme. So either serialise just the bits you want, or use *outerHTML*. Perhaps you should explain what you mean by "*key and value of a row*", e.g. what should clicking on a row produce (sample output)? – RobG Jun 02 '17 at 02:22
  • I edited my question to make it clearer, sorry for the misunderstanding, can you check it again – M.Izzat Jun 02 '17 at 02:33

4 Answers4

0

I think you can use tr.innerTestto get the value in the tags

Shield Chi
  • 68
  • 1
  • 6
  • I think you mean *innerText*. It seems to me that the OP wants to serialise the entire TR structure, not just get the textContent. – RobG Jun 02 '17 at 02:18
0

I edited my answer to return the data as an object. Run the script and have a look.

var table = document.getElementById("tableID");
if (table) {
  for (var i = 0; i < table.rows.length; i++) {
    table.rows[i].onclick = function() {
      tableText(this);
    };
  }
}

function tableText(tableRow) {
  var name = tableRow.childNodes[1].innerHTML;
  var age = tableRow.childNodes[3].innerHTML;
  var obj = {'name': name, 'age': age};
  console.log(obj);
}
<table align="center" id="tableID" border="1" style="cursor: pointer;">
<thead>
    <tr>
        <th hidden="hidden"></th>
        <th>name</th>
        <th>age</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td >Clark</td>
        <td>29</td>
    </tr>
    <tr>
        <td >Bruce</td>
        <td>30</td>
    </tr>
</tbody>
</table>
JJJ
  • 3,314
  • 4
  • 29
  • 43
  • Unfortunately this is not working, please refer the question again thanks – M.Izzat Jun 02 '17 at 02:34
  • @M.Izzat have a look now – JJJ Jun 02 '17 at 02:45
  • @JosanIracheta Thanks alot this works! if you dont mind me asking, if I have a much bigger table. how can make it more dynamic by not having to declare the tableRow.childNodes[i].innerHTML; 1 by 1 – M.Izzat Jun 02 '17 at 03:21
  • @M.Izzat Since you wanted an object, you're going to have to declare what you want specifically so the value is paired with the correct key. – JJJ Jun 02 '17 at 03:27
0

If you are using jQuery you can add an eventlistener to the table like this

$('#tableID').on('click', 'tr', function(e){
  tableText($(this).html());
});

function tableText(tableRow) {
  var myJSON = JSON.stringify(tableRow);
  console.log(myJSON);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<table align="center" id="tableID" border="1" style="cursor: pointer;">
  <tr>
    <td>Text</td>
    <td>MoreText</td>
    <td>Lorem</td>
    <td>Ipsum</td>
  </tr>
  <tr>
    <td>Text</td>
    <td>MoreText</td>
    <td>Lorem</td>
    <td>Ipsum</td>
  </tr>
  <tr>
    <td>Text</td>
    <td>MoreText</td>
    <td>Lorem</td>
    <td>Ipsum</td>
  </tr>
  <tr>
    <td>Text</td>
    <td>MoreText</td>
    <td>Lorem</td>
    <td>Ipsum</td>
  </tr>
</table>
Lasithds
  • 2,161
  • 25
  • 39
0

There are many ways to do what you're after, however a robust and extensible way would be to get the property names from the table header row, then get the values from the row that was clicked on.

I don't know why you have hidden cells in the header, it just complicates things. If you're using it for data, that would be much better in an associated object or data-* property of the table or row.

function getRowDetails(event) {
  row = this;
  var table = row.parentNode.parentNode;
  var header = table.rows[0];
  
  // Get property names from header cells
  var props = [].reduce.call(header.cells, function(acc, cell ) {
    if (!cell.hasAttribute('hidden')) {
      acc.push(cell.textContent);
    }
    return acc;
  }, []);
  
  // Get value for each prop from data cell clicked on
  var result = props.reduce(function(acc, prop, i) {
    acc[prop] = row.cells[i].textContent;
    return acc;
  }, {});
  
  // Do something with result
  console.log(result);
  return result;
}

// Add listener to body rows, could also put single listener on table
// and use event.target to find row
window.onload = function() {
  [].forEach.call(document.getElementsByTagName('tr'), function(row, i) {
    if (i) row.addEventListener('click', getRowDetails, false);
  });
}
<table align="center" id="tableID" border="1">
<thead>
  <tr><th hidden="hidden"></th><th>name</th><th>age</th></tr>
</thead>
<tbody style="cursor: pointer;">
  <tr><td >Clark</td><td>29</td></tr>
  <tr><td >Bruce</td><td>30</td></tr>
</tbody>
</table>
RobG
  • 142,382
  • 31
  • 172
  • 209