I would have "thought" it would be a simple thing to get the (unformatted) text in each cell of a dynamic table but I have failed to solve this problem. So...I have a table that the user can dynamically load with data. They click an add button to insert a row in a table which includes a delete button per row if they want to turn around and delete it.

The table is inside a form. When they submit the form, I need to read each row and each cell in a row in order to dump it into some format so that the table contents display reasonably well in the email that is sent from the form submission.

So the add row function looks like:

function addRow() {
  //add a row to the rows collection and get a reference to the newly added row
  var newRow = document.all("mytbl").insertRow();
  noRows = noRows+1; //because I was having trouble getting the total number of rows later on so I just declared a global so this was readily available
    
  //add cells (<td>) to the new row and set the innerHTML to contain text boxes
  var oCell = newRow.insertCell();
  oCell.innerHTML = "<input type='button' value='x' onclick='removeRow(this);'/>";    

  oCell = newRow.insertCell();
  oCell.innerHTML = "<input type='text' name='t1'>";
    
  oCell = newRow.insertCell();
  oCell.innerHTML = "<input type='text' name='t2'>";
    
  oCell = newRow.insertCell();
  oCell.innerHTML = "<input type='text' name='t3'>";

  oCell = newRow.insertCell();
  oCell.innerHTML = "<input type='text' name='t4'>";
    
  oCell = newRow.insertCell();
  oCell.innerHTML = "<input type='text' name='t5'>";
    
  oCell = newRow.insertCell();
  oCell.innerHTML = "<input type='text' name='t6'>";
    
  oCell = newRow.insertCell();
  oCell.innerHTML = "<input type='text' name='t7'>";
}

function removeRow(src){
  /* src refers to the input button that was clicked. 
     to get a reference to the containing <tr> element,
     get the parent of the parent (in this case <tr>)
  */   
  var oRow = src.parentElement.parentElement;  
    
  //once the row reference is obtained, delete it passing in its rowIndex   
  document.all("acatdog").deleteRow(oRow.rowIndex); 
  noRows = noRows-1; 
}

When the form is ready to be submitted I attempted to get the contents back out as follows:

objval = "";
obj = document.getElementById("mytbl");
for (r=0; r < noRows; r++) {
   for (c=1; c<8; c++) {
       trow = obj.rows[r];
       tcell = trow.cells[c];
       cellval = tcell.innerText; //errors out with trow.cells being undefined
       if (cellval.length < 1) {
          alert("Please complete all columns (name, age, ...) for each table entry.");
          return false;  //code is inside a validate function and table contents are not validated until submit but if they are okay then I also dump contents to a text field tbllst
       }
       objval = objval+cellval+"\t";
  }
  objval = objval+"\n";
}
obj = document.getElementById("tbllst");
obj.value = objval;

I've tried all sorts of syntax for getting at those table cells. I'm obviously still getting the syntax wrong. Any help would be appreciated.

MJS

Recommended Answers

All 3 Replies

syntax for getting at those table cells

Here is a simple example that doesn't assume that all rows are of equal length. It does, however, make the simplifying assumption that the text is always in the firstChild node.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta name="generator" content=
    "HTML Tidy for Windows (vers 25 March 2009), see www.w3.org">
    <script type="text/javascript">
        function showContent() {

            var oTBL = document.getElementById('myTable')
            for (var x = 0; x < oTBL.rows.length; x++) {
                for (var y = 0; y < oTBL.rows[x].cells.length; y++) {
                    alert(oTBL.rows[x].cells[y].firstChild.data);
                }
            }
        }
    </script>
    <title></title>
  </head>
  <body>
    <table id="myTable" border="1">
      <tr>
        <td>
          r1c1
        </td>
        <td>
          r1c2
        </td>
        <td>
          r1c3
        </td>
      </tr>
      <tr>
        <td>
          r2c1
        </td>
        <td>
          r2c2
        </td>
      </tr>
    </table>
    <form>
      <input type="button" onclick="showContent()" value=
      "Show content">
    </form>
  </body>
</html>
commented: This is nice post.I found this logic helpful for me +0

Hey my thing is tht i need the data of all the rows to be grouped in an array......... any help with tht

tech.b,

I don't know if this helps but I do have my table working and can get data back out. My table allows for a visitor to the site to add and delete rows. A row is x number of cells each with an input tag in the cell so that I can reference the data the user has entered into the cell. So I dynamically build the table as follows:

//A button on my form triggers this function
function addRow() {
  //add a row to the rows collection and get a reference to the newly added row
  noRows = noRows+1; //I use this elsewhere so it's really just a convenience
  var newRow = document.getElementById("mytbl").insertRow(-1);
    
  //add cells (<td>) to the new row with a unique tag and set the innerHTML to contain text boxes
  var oCell = newRow.insertCell(-1);
  //create a button in the row that will allow the user to delete the row
  oCell.innerHTML = "<input type='button' value='x' onclick='removeRow(this);'/>";    

  //in my case, I have a static number (known) rows
  for (c=1; c<8; c++) {
     //I build an id for the input tag for the cell
     tag = "t"+noRows.toString()+c.toString(); //could just as easily be a tag "r1c1"
     oCell = newRow.insertCell(-1);
     oCell.innerHTML = "<input type='text' id='"+tag+"' />";
  }
}

//triggered when user clicks the "x" button in a row
function removeRow(src){
  /* src refers to the input button that was clicked. 
     to get a reference to the containing <tr> element,
     get the parent of the parent (in this case <tr>)
  */   
  var oRow = src.parentNode.parentNode;  
    
  //once the row reference is obtained, delete it passing in its rowIndex   
  document.getElementById("acatdog").deleteRow(oRow.rowIndex); 
  noRows = noRows-1; 
}

Then, later, when I need to access that data, I do the following and build it essentially into a string (I need to print the contents of the whole thing into a form results email) but instead you could build a dynamic array:

function deconstruct() {
  // string together rows from mytbl into myformstring
  // flag used because this function is called from inside a validation routine and I
  // want to be sure that for each row, the user supplied 'some' data
  valid_tbl = true;
  myformstring = "";
  for (r=1; r <= noRows; r++) {
     for (c=1; c<8; c++) {
	    tag="t"+r+c;
		obj=document.getElementById(tag);
		cellval=obj.value;
		if ((cellval.length < 1) && valid_tbl == true) {
		  alert("Please provide data for all columns in the table.");
		  valid_tbl = false; }
		else {
		  if (c == 7) myformstring = myformstring+cellval+"\n";
	      else myformstring = myformstring+cellval+"\t"; }
	 }
  }
  //if the user completed the entire table then I have my string which will be
  //be assigned to a form field for display in my form results; otherwise, a null
  //string tells the calling function that the user didn't complete the table and
  //returns a false on the validation routine
  if (valid_tbl == false) myformstring = "";
  return myformstring;
}

Some of the above was provided by fxm in the first place so thanks to him for all his help.

In any event, you could simply declare an array and loop through the table as above but instead:

//since my code is all dynamic building of objects...loop through your rows
colarray = "[";
colarray = colarray+cellval+","; // for each cell in the row putting quotes around text values and not adding a comma after the last value...then
colarray = colarray+"]";
//once you've gotten all your cell data then add the entire row to a row array to 
//simulate a multi-dimensional array
rowarray = [colarray];

I haven't tested this but the solution will be something like the above. Does that help?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.