Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Node removal problem

29 views
Skip to first unread message

justaguy

unread,
Feb 16, 2013, 1:09:45 PM2/16/13
to
Hi,

I attempted to remove a child inside many layers of a big TABLE but I received an error, err msg:
"NotFoundError: Node was not found"

Here's the TABLE structure (I know it's messy...).
I've also tried different parent element/node such as the very top one of id,'TBL' still to no avail. What's the correct syntax for it. Thanks.

Nodes layer (inside TABLE)
<TABLE id="TBL">
<tbody id='TB">
<table id="Content">
<tr id="row1">
<td id="del1" onclick="var PE=document.getElementById('Content'),c=document.getElementById('del1');PE.removeChild(c);">
...
</tr>
</table>
</tbody>
</TABLE>

Martin Honnen

unread,
Feb 16, 2013, 1:29:47 PM2/16/13
to
I would simply use
<td onclick="this.parentNode.removeChild(this);">...</td>
to remove the "td" element node from its parent "tr" element node.

Whether it is a good idea to remove a single cell from a table is
another issue.

justaguy

unread,
Feb 16, 2013, 1:37:31 PM2/16/13
to Martin...@gmx.de
Your method sound excellent, very clean. But I made a mistake,
for <td id="del1" onclick="var PE=document.getElementById('Content'),c=document.getElementById('del1');PE.removeChild(c);">
I meant to delete the row but the TD only,
<td id="del1" onclick="var PE=document.getElementById('Content'),c=document.getElementById('row1');PE.removeChild(c);">

Also, your method did not remove the TD thou no error with Chrome 24 on Windows and Firefox 18. Am I doing something wrong? Thanks.

justaguy

unread,
Feb 16, 2013, 1:44:54 PM2/16/13
to Martin...@gmx.de
Sorry, your method works perfectly in removing the <TD>, I had a stupid typo.
Also, I attempted to change the last 'this' to 'this.parent' to no avail in removing the TR. Hmm... thanks.

Martin Honnen

unread,
Feb 16, 2013, 1:46:37 PM2/16/13
to
justaguy wrote:

> I meant to delete the row but the TD only,
> <td id="del1" onclick="var PE=document.getElementById('Content'),c=document.getElementById('row1');PE.removeChild(c);">

If you want to delete the row the td is in from the table or table
section it is contained in then use
<td onclick="var row = this.parentNode; var tableOrSection =
row.parentNode; tableOrSection.removeChild(row);">...</td>

Actually the variables are not needed but might make the code more
descriptive than simply doing
this.parentNode.parentNode.removeChild(this.parentNode);

As for why your current approach might fail, the HTML parser might add a
table section like a tbody or thead which contains the row so trying to
remove a row from the table element itself fails as it is a child of a
tbody or thead the parser has added to the DOM tree.

justaguy

unread,
Feb 16, 2013, 2:10:23 PM2/16/13
to Martin...@gmx.de
Martin, your syntax makes perfect sense. But it still only removes the TD,
I added alert(row), and it indicated [Object HTMLTableCellElement] with both Chrome and Safari browsers. What could stand in the way? Thanks.

justaguy

unread,
Feb 16, 2013, 4:25:13 PM2/16/13
to Martin...@gmx.de
We're getting there. Previously your code covers two levels (td and its tr), we need three levels, current TD, its TR, and the TR's parent. With revised code, it solves one problem. I also have dynamically generated TRs and TDs,
such as
var newrow = document.createElement("tr");
var cell = document.createElement("td");
var cellText = document.createElement('input');
cellText.type = 'checkbox';
... set other attributes
cell.appendChild(cellText);
newrow.appendChild(cell);
cell.onclick = "var row = this.parentNode; var tdParent = row.parentNode; var trParent = tdParent.parentNode; trParent.removeChild(tdParent);"
/* the above line fails;
I attempted to use cellText.onclick as well, but to no avail
*/

What am I not doing right? Thanks.

Just removed Firefox, so, can't use Firebug for debugging info....

Thomas 'PointedEars' Lahn

unread,
Feb 16, 2013, 5:05:28 PM2/16/13
to
Martin Honnen wrote:

> justaguy wrote:
>> I meant to delete the row but the TD only,
>> <td id="del1" onclick="var
>>
PE=document.getElementById('Content'),c=document.getElementById('row1');PE.removeChild(c);">
>
> If you want to delete the row the td is in from the table or table
> section it is contained in then use
> <td onclick="var row = this.parentNode; var tableOrSection =
> row.parentNode; tableOrSection.removeChild(row);">...</td>
>
> Actually the variables are not needed but might make the code more
> descriptive than simply doing
> this.parentNode.parentNode.removeChild(this.parentNode);

Another possibility, without loss of compatibility:

var row; (row = this.parentNode).parentNode.removeChild(row);

This makes use of the fact that the result of a simple assignment is its
right-hand side, and that MemberExpressions are evaluated from left to
right.

--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

justaguy

unread,
Feb 16, 2013, 5:44:59 PM2/16/13
to Thomas 'PointedEars' Lahn
Thanks. I tried, still not removing the row. No error.
And I should have been clearer in my previous code, that is, each dynamically created row has its id added too, here's the revised code including debugging info:

var newrow = document.createElement("tr");
newrow.setAttribute('id','row'+cnt);
// yes, cnt has been defined above
var cell = document.createElement("td");
cell.setAttribute('id','del'+cnt);
var cellText = document.createElement('input');
cellText.type = 'checkbox';
... set other attributes
cell.appendChild(cellText);
newrow.appendChild(cell);
cell.onclick = "alert('hi');var rown = this.parentNode; var tdParentn = rown.parentNode; alert(tdParentn);var trParentn = tdParentn.parentNode;alert(trParentn); trParentn.removeChild(tdParentn);";

Outcome:
onclick on such a new row produces nothing, not even the alert event.
Is my syntax incorrect? Many thanks.

Thomas 'PointedEars' Lahn

unread,
Feb 16, 2013, 5:51:26 PM2/16/13
to
justaguy wrote:

> Thanks. I tried, still not removing the row. No error.

Possible, but unlikely.

> And I should have been clearer in my previous code, that is, each
> dynamically created row has its id added too,

Irrelevant.

> here's the revised code
> including debugging info:
>
> var newrow = document.createElement("tr");
> newrow.setAttribute('id','row'+cnt);

Do not use setAttribute() where short-hand properties suffice.

> […]
> Outcome:
> onclick on such a new row produces nothing, not even the alert event.

“alert” is not an event, it is a method.

> Is my syntax incorrect? Many thanks.

Your code is *syntactically* correct.

If you desire further replies, learn to post, do not post via Google Groups,
and get a real name.

<http://jibbering.com/faq/#posting>
<http://PointedEars.de/faq#posting>

justaguy

unread,
Feb 16, 2013, 6:19:18 PM2/16/13
to
> var newrow = document.createElement("tr");
> newrow.setAttribute('id','row'+cnt);

Do not use setAttribute() where short-hand properties suffice.
-------------

I suspected that as well. So, what's a more effective way to add an id and value (key/value pair) to a new TR(row) in this case then? Thanks.

SAM

unread,
Feb 16, 2013, 8:46:02 PM2/16/13
to
Le 16/02/13 19:09, justaguy a �crit :
> Hi,
>
> I attempted to remove a child inside many layers of a big TABLE but I received an error, err msg:
> "NotFoundError: Node was not found"
>
> Here's the TABLE structure (I know it's messy...).
> I've also tried different parent element/node such as the very top one of id,'TBL' still to no avail. What's the correct syntax for it. Thanks.
>
> Nodes layer (inside TABLE)
> <TABLE id="TBL">
> <tbody id='TB">

Hu ?

<tr>
<td>

> <table id="Content">
> <tr id="row1">
> <td id="del1" onclick="var PE=document.getElementById('Content'),c=document.getElementById('del1');PE.removeChild(c);">
> ...
> </tr>
> </table>

</td>
</tr>

> </tbody>
> </TABLE>
>

<container>
<element onclick="this.parentNode.removeChild(this)">
delete me
</element>
</container>



<tr>
<td onclick="this.parentNode.removeChild(this)">
delete me
</td>
</tr>






Head's JS :
===========

function del() { this.parentNode.removeChild(this); }
window.onload= function() {
var t = document.getElementsByTagName('TD'), n = t.length;
while(n--) t[n].onclick = del;
}

body :
======
<table>
<tr><td> delete me </td><td> delete me </td></tr>
<tr><td> delete me </td><td> delete me </td></tr>
</table>

--
St�phane Moriaux avec/with iMac-intel

* Anglais - d�tect�
* Anglais
* Fran�ais
* Espagnol

* Anglais
* Fran�ais
* Espagnol

<javascript:void(0);> <#>

justaguy

unread,
Feb 16, 2013, 8:59:24 PM2/16/13
to
Thanks, Sam, but it seems there's some misunderstanding here.

// 1) the following TR is dynamically created
// 2) the objective is to remove the whole row (TR), not the specific TD
<tr>
<td onclick="this.parentNode.removeChild(this)">
delete me
</td>
</tr>

>On Saturday, February 16, 2013 1:09:45 PM UTC-5, justaguy wrote:

justaguy

unread,
Feb 16, 2013, 9:44:22 PM2/16/13
to
Problem solved. Key is to use the correct syntax for object click, that is,
object.onclick = function

Thank you all.

justaguy

unread,
Feb 16, 2013, 10:08:12 PM2/16/13
to
I spoke too soon. The problem of removing a row dynamically appears to be solved. However, DOM seems to still think it exists, hence, calculating all the rows, we now got problem, so, the new question is, how do we set the dynamic and impacted field of 'qty'+{counter} field value to 0? Thanks.

justaguy

unread,
Feb 16, 2013, 10:54:44 PM2/16/13
to

SAM

unread,
Feb 18, 2013, 7:07:51 AM2/18/13
to
Le 17/02/13 02:59, justaguy a écrit :
> Thanks, Sam, but it seems there's some misunderstanding here.
>
> // 1) the following TR is dynamically created

So, don't forget to introduce a row and a cell in the mother table !

> // 2) the objective is to remove the whole row (TR), not the specific TD

Not a problem :

<tr>
<td style="cursor:pointer"
onclick="
var a = this.parentNode;
while(a.tagName.tolowerCase()!='tr') a=a.parentNode;
a.parentNode.removeChild(a);
">
delete this row
</td>
<td>
as example
</td>
</tr>



--
Stéphane Moriaux avec/with iMac-intel

Evertjan.

unread,
Feb 18, 2013, 8:29:06 AM2/18/13
to
SAM wrote on 18 feb 2013 in comp.lang.javascript:

> <td style="cursor:pointer"
> onclick="
> var a = this.parentNode;
> while(a.tagName.tolowerCase()!='tr') a=a.parentNode;
> a.parentNode.removeChild(a);
> ">

toLowerCase(), not tolowerCase()

shorter is:

<td style="cursor:pointer" onclick="
var a = this;
while(a.tagName.toLowerCase()!='tr') a=a.parentNode;
a.parentNode.removeChild(a);
">

or

<td style="cursor:pointer" onclick="
var a = this;
while( !/tr/i.test(a.tagName) ) a=a.parentNode;
a.parentNode.removeChild(a);
">

but what is wrong with:

<td style="cursor:pointer" onclick="
var a = this.parentNode;
a.parentNode.removeChild(a);
">

Surely the parentNode of a <td> always is a <tr>?


--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

Evertjan.

unread,
Feb 18, 2013, 8:36:54 AM2/18/13
to
Evertjan. wrote on 18 feb 2013 in comp.lang.javascript:

> but what is wrong with:
>
> <td style="cursor:pointer" onclick="
> var a = this.parentNode;
> a.parentNode.removeChild(a);
> ">
>
> Surely the parentNode of a <td> always is a <tr>?

or

<td style="cursor:pointer"
onclick="
var a;
(a = this.parentNode).parentNode.removeChild(a);

SAM

unread,
Feb 18, 2013, 8:41:46 AM2/18/13
to
Le 17/02/13 04:08, justaguy a �crit :
> I spoke too soon. The problem of removing a row dynamically appears
> to be solved. However, DOM seems to still think it exists, hence,
> calculating all the rows, we now got problem, so, the new question
> is, how do we set the dynamic and impacted field of 'qty'+{counter}
> field value to 0? Thanks.

I lost my crystal ball. Without html code of your hand I can not guess!

see : <http://cjoint.com/13fe/CBsoIvIDml7.htm>
copy/paste n save the shown html code and try it in a browser

SAM

unread,
Feb 18, 2013, 8:56:50 AM2/18/13
to
Le 16/02/13 22:25, justaguy a �crit :
> We're getting there. Previously your code covers two levels (td and its tr), we need three levels, current TD, its TR, and the TR's parent. With revised code, it solves one problem. I also have dynamically generated TRs and TDs,
> such as
> var newrow = document.createElement("tr");
> var cell = document.createElement("td");
> var cellText = document.createElement('input');
> cellText.type = 'checkbox';
> ... set other attributes
> cell.appendChild(cellText);
> newrow.appendChild(cell);
> cell.onclick = "var row = this.parentNode;

You can't be sure that the parentNode will be a row

> var tdParent = row.parentNode;

That's to say that we expect to get now a TBODY or a TABLE (*)

var trParent = tdParent.parentNode;

We aren't sure we got the right element (the table)


trParent.removeChild(tdParent);"

OK
if we got the good element !

> /* the above line fails;
> I attempted to use cellText.onclick as well, but to no avail
> */

As you make mistakes in nested tags of tables you will not get anything!

> What am I not doing right? Thanks.

The html isn't right !!!

(*) the table containing the row to delete in the example you gave in
one of your previous posts was "nowhere" (it wasn't in a TD).

--
St�phane Moriaux avec/with iMac-intel

SAM

unread,
Feb 18, 2013, 9:05:00 AM2/18/13
to
Le 18/02/13 14:29, Evertjan. a �crit :
> SAM wrote on 18 feb 2013 in comp.lang.javascript:
>
>> <td style="cursor:pointer"
>> onclick="
>> var a = this.parentNode;
>> while(a.tagName.tolowerCase()!='tr') a=a.parentNode;
>> a.parentNode.removeChild(a);
>> ">
>
> toLowerCase(), not tolowerCase()

OOOooops !!!

> Surely the parentNode of a <td> always is a <tr>?


Not at all sure with the html code of "justaguy" !!!

If I can make mistake I'm not alone :
that guy puts a table directly in a table
(not in the cell of a row of a table)

SAM

unread,
Feb 18, 2013, 9:13:24 AM2/18/13
to
Le 18/02/13 14:36, Evertjan. a �crit :
> Evertjan. wrote on 18 feb 2013 in comp.lang.javascript:
>
>> but what is wrong with:
>>
>> <td style="cursor:pointer" onclick="
>> var a = this.parentNode;
>> a.parentNode.removeChild(a);
>> ">
>>
>> Surely the parentNode of a <td> always is a <tr>?
>
> or
>
> <td style="cursor:pointer"
> onclick="
> var a;
> (a = this.parentNode).parentNode.removeChild(a);
> ">

from one of justaguy posts I understood that he wanted to remove the
table containing the row of the clicked cell

the problem I saw in justaguy's code is that the table to remove isn't
in the cell of a row of the parent table

By there I can't expect that the TD will be in a TR nor the TR in a
TABLE (so backwards in code)

Evertjan.

unread,
Feb 18, 2013, 4:01:41 PM2/18/13
to
SAM wrote on 18 feb 2013 in comp.lang.javascript:

> Le 18/02/13 14:29, Evertjan. a �crit :
>> SAM wrote on 18 feb 2013 in comp.lang.javascript:
>>
>>> <td style="cursor:pointer"
>>> onclick="
>>> var a = this.parentNode;
>>> while(a.tagName.tolowerCase()!='tr') a=a.parentNode;
>>> a.parentNode.removeChild(a);
>>> ">
>>
>> toLowerCase(), not tolowerCase()
>
> OOOooops !!!
>
>> Surely the parentNode of a <td> always is a <tr>?
>
>
> Not at all sure with the html code of "justaguy" !!!

Then the code is in error.

A <td> has only and always one parent and that is an <tr>.

Ask just another guy.

> If I can make mistake I'm not alone :
> that guy puts a table directly in a table
> (not in the cell of a row of a table)

You cannot do that, try it. ;-)

Evertjan.

unread,
Feb 18, 2013, 4:05:38 PM2/18/13
to
SAM wrote on 18 feb 2013 in comp.lang.javascript:

> Le 16/02/13 22:25, justaguy a �crit :
>> We're getting there. Previously your code covers two levels (td and
>> its tr), we need three levels, current TD, its TR, and the TR's
>> parent. With revised code, it solves one problem. I also have
>> dynamically generated TRs and TDs, such as
>> var newrow = document.createElement("tr");
>> var cell = document.createElement("td");
>> var cellText = document.createElement('input');
>> cellText.type = 'checkbox';
>> ... set other attributes
>> cell.appendChild(cellText);
>> newrow.appendChild(cell);
>> cell.onclick = "var row = this.parentNode;
>
> You can't be sure that the parentNode will be a row

Yes, you can.


>> var tdParent = row.parentNode;
>
> That's to say that we expect to get now a TBODY or a TABLE (*)

Always a <tbody> or a <thread> or <tfoot> is specified.

If not specified the <tbody> is inserted for you in the DOM.

> var trParent = tdParent.parentNode;
>
> We aren't sure we got the right element (the table)

Then you should test it in all different browsers.

> trParent.removeChild(tdParent);"
>
> OK
> if we got the good element !

If you doubt, test.


>> /* the above line fails;
>> I attempted to use cellText.onclick as well, but to no avail
>> */
>
> As you make mistakes in nested tags of tables you will not get
> anything!
>
>> What am I not doing right? Thanks.

Seems you don't trust yourself and don't test, bad habit.

> The html isn't right !!!
>
> (*) the table containing the row to delete in the example you gave in
> one of your previous posts was "nowhere" (it wasn't in a TD).


--
0 new messages