Dynamically add/remove table rows

I have the following JS code which adds a new row to an existing HTML table:

function addRows(cid)
{
var tbody = document.getElementById(cid).getElementsByTagName("TBODY")[0];

var row = document.createElement("TR");

row.setAttribute('id', 'rowNum' + rowCount);

var t1 = document.createElement("TD");
t1.innerHTML='To:';

var t2 = document.createElement("TD");
t2.innerHTML='<input name="birthdayEmails" type="text" class="inputText" size="30" value="">';

var t3 = document.createElement("TD");

row.appendChild(t1);
row.appendChild(t2);
row.appendChild(t3);

tbody.appendChild(row)

t3.innerHTML='<a href=\\'javascript:deleteRow("bdayTable", ' + rowCount + ')\\'>Remove</a>';

rowCount++;

}

And the following code is being used to delete a row from the table:

function deleteRow(tblName, rowId)
{
       var tbl = document.getElementById(tblName);
	var tbody = document.getElementById(cid).getElementsByTagName("TBODY")[0];

	var rowNum = document.getElementById('rowNum' + rowId);
	
	if (tbl.rows.length > 1)
	{
          //tbl.deleteRow(rowId);
	  tbody.removeChild(rowNum);
	
	}
	
}

And this is the HTML code:

<table width="46%" id="bdayTable" border="1" cellpadding="3" cellspacing="0" class="bordered_table">
     <TBODY>
      <tr>
        <td>&nbsp;</td>
        <td><span class="style1">Email address</span></td>
      </tr>

        <tr>
          <td width="8%" class="style1">To:</td>
          <td width="20%">
            <input name="birthdayEmails" type="text" class="inputText" size="30" value="">

          </td>
          <td width="72%">&nbsp;
          </td>
        </tr>

        <tr>
          <td width="8%" class="style1">To:</td>
          <td width="20%">
            <input name="birthdayEmails" type="text" class="inputText" size="30" value="">

          </td>
          <td width="72%">&nbsp;
          </td>
        </tr>

        <tr>
          <td width="8%" class="style1">To:</td>
          <td width="20%">
            <input name="birthdayEmails" type="text" class="inputText" size="30" value="">

          </td>
          <td width="72%">&nbsp;
          </td>
        </tr>

        <tr>
          <td width="8%" class="style1">To:</td>
          <td width="20%">
            <input name="birthdayEmails" type="text" class="inputText" size="30" value="">

          </td>
          <td width="72%">&nbsp;
          </td>
        </tr>

        <tr>
          <td width="8%" class="style1">To:</td>
          <td width="20%">
            <input name="birthdayEmails" type="text" class="inputText" size="30" value="">

          </td>
          <td width="72%">&nbsp;
          </td>
        </tr>

     </TBODY>
    </table><BR>
    <a href="javascript:addRows('bdayTable')">Add row</a> 

The add row function works fine, the problem I am having is with the delete table row function. The removeChild method doesn’t remove the selected row from the table. Specifically, it seems that the line:

tbody.removeChild(rowNum);

is not removing the corresponding table row. Anybody have any idea what I’m doing wrong? I understand that I can use:

tbl.deleteRow(rowId);

to delete a row. But the problem with this approach is that after a row is deleted from the table, the row indexes will be re-numbered, and then the call to the deleteRow(tblName, rowCount) method will not work, because the rowCount value has changed and Javascript loses track of which row to remove when the Remove row link is clicked on. Therefore, I tried to resolve this by assigning a unique ID to each table row and then using Javascript to remove the row by refering to its ID rather than its index. However, I am still very new to Javascript and am having trouble fully understanding the DOM model and how to reference and manipulate a table row object in the tree.

Am I using the right method here with tbody.removeChild(rowNum)? Or am I completely off-track? If so, can someone recommend a better approach to solving this problem or simply point me in the right direction?

Another solution I have tried using is:


<tr>
  <td>
    <a href='javascript:deleteRow("bdayTable", this)'>Remove</a>
  </td>
</tr>

And:

function deleteRow(tblName, link)
{
  var tbl = document.getElementById(tblName);
  var tableRow = link.parentElement.parentElement;

  tbl.deleteRow(tableRow.rowIndex);
}

However, the line:

tableRow = this.parentElement.parentElement;

simply produces a value of ‘undefined’. What am I doing wrong here? How can I use the parentElement parameter to reference the Table Row object that houses the ‘deleteRow()’ hyperlink? If I can reference the TR object, then removing the row from the table will be a cinch! Please help!

Thanks!

function deleteRow(tblName, link)
{
  var tbl = document.getElementById(tblName);
  var tableRow = link.[COLOR=Red]parentNode.parentNode[/COLOR];

  [COLOR=Red]tbl.removeChild(tableRow);[/COLOR]
}

Hope this helps.

Thanks, but the line:

var tableRow = link.parentNode.parentNode;

produces the following error:

Warning: reference to undefined property link.parentNode

Any idea what could be wrong?

Thanks

Testing in Explorer seems to show an extra tbody element being inserted, so try this quick fix:

function deleteRow(tblName, targetLink)
{
  var tableRow = targetLink.parentNode.parentNode;
  var tbl = tableRow.parentNode;
  tbl.removeChild(tableRow);
}

Thanks Iain, but the JS is still returning an error:

Warning: reference to undefined property link.parentNode

It seems that this line of code is causing the problem:

var tableRow = link.parentNode.parentNode;

Javascript seems unable to reference the nodes of dynamically created table rows. Is there something else I am missing?

Well I would need to see your complete code because the code as I’ve written it is working without any problems here for me on IE 6. Which browser are you using? I don’t have any others to test with here at work and I can’t think of any reason it wouldn’t work in FF.

Actually, I think your use of ‘link’ as a variable name may be the problem. That’s a reserved word. Use targetLink like I have and we may be cooking with gas.

EDIT: Scratch that, I think link is a keyword that is unreserved, but you never know, it may still be the problem. :slight_smile: