Remove or hide specific table rows
|
|
Hello, I would really appreciate it if someone could *please* write or point
<tr> <td><img src="red.gif"></td> <td>Miscellaneous text</td> </tr> The src attribute of the descendant image is the only thing that sets
I've looked around for a suitable script for a really long time, and I've
This one hides the entire page (!) even after I set keywords that
This one simply does nothing. In Greasemonkey I set it to run on
|
|
|
You could just find such images and then remove their parentNode. Something like the following... images = document.evaluate('//tr/td/img[@src="red.gif"]',document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null)
for (i = 0; i < images.snapshotLength; i++) {
(foo = images.snapshotItem(i).parentNode.parentNode).parentNode.removeChild(foo)
}
|
|
|
That is brilliant! Another couple of questions if you don't mind: 1. What would be the code to remove the grandparent element of a link instead of an image (basically, 2. How would you handle multiple keywords? Say you wanted to get rid of the table row based on red.gif as well as crimson.gif. I simply copied and pasted the code and made the change; that seems to work OK. Is there a better way to go about it? Thank you very much! |
|
|
1. What would be the code to remove the grandparent element of a link instead of an image (basically, <a> instead of <img> in the above example)?Yeah, I believe that what you said should work. 2. How would you handle multiple keywords? Say you wanted to get rid of the table row based on red.gif as well as crimson.gif. I simply copied and pasted the code and made the change; that seems to work OK. Is there a better way to go about it?This is surprisingly easy... '//tr/td/img[@src="red.gif" or @src="crimson.gif"]'.
So to do both the link and the images, you would want something like... '//tr/td/img[@src="red.gif" or @src="crimson.gif"]|//tr/td/a[@href="http://www.example.com/"]'There's probably a better way of doing this though, so if anyone wants to correct me, feel free.. |
|
|
Thanks for the reply! After an enormous amount of trial and error, it finally dawned on me that it wasn't working because one particular page I was trying to apply it to had another element between the table cell and the image or link. I adjusted it accordingly and it seems to work like a charm now! Would it be possible to match based on the inner markup of an element and to remove its parent as well as the following element (non-sibling)?
<tr title="This row would be removed"> <td>Miscellaneous text</td> </tr> <tr title="This row would be removed as well"> <td>Other text</td> </tr> '//tr/td[contains(text(), "Miscellaneous")]' is as far as I got; I saw references to followingNode here and there, but I have no idea how to piece it all together.
|
|
|
To match based on the text, you want to use this... To remove the next element, just use for (i = 0; i < images.snapshotLength; i++) {
(foo = images.snapshotItem(i).parentNode.parentNode).parentNode.removeChild(foo.nextSibling)
foo.parentNode.removeChild(foo)
}It would be equivalent, but to ease readability though you might want to make it as follows...for (i = 0; i < images.snapshotLength; i++) {
foo = images.snapshotItem(i).parentNode.parentNode
foo.parentNode.removeChild(foo.nextSibling)
foo.parentNode.removeChild(foo)
}It is important here to remove the next sibling before the original node, because if you remove the original one first you cannot then reference it to find the next one.
|
|
|
Thanks again for the reply, but I can't get this one to work. Did I get it wrong somewhere? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>Table</title> </head> <body> <table> <tr><td>Miscellaneous text</td></tr> <tr><td>Other text</td></tr> </table> </body> </html>
images = document.evaluate('//tr/td[text()="Miscellaneous text"]',document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null)
for (i = 0; i < images.snapshotLength; i++) {
foo = images.snapshotItem(i).parentNode.parentNode
foo.parentNode.removeChild(foo.nextSibling)
foo.parentNode.removeChild(foo)
}
|
|
|
I can't see something obviously wrong with that code, so try sticking |
|
|
The alert displays 1
|
|
|
try this
foo = images.snapshotItem(i).parentNode.parentNode to var foo = images.snapshotItem(i).parentNode.parentNode |
|
|
Thank you, but it still doesn't work. The Error Console displays the following message. The line referenced points to Error: Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMHTMLTableElement.removeChild] I tried disabling every extension except Greasemonkey just in case, but it didn't help. |
|
|
Try replacing that line with... if (foo.nextSibling) foo.parentNode.removeChild(foo.nextSibling)It sounds to me like you're trying to remove a node that doesn't exist (foo.nextSibling), so maybe there is no sibling after the returned result. I would guess though that this will remove the one row with "Miscellanous stuff" but not the "This row will be removed as well" row. |
|
|
the nextSibling returns null when you're at the end of the table |
|
|
Try replacing that line with... Now it gets rid of the whole table instead of the two rows (to test, I inserted a third single-cell row with random text, but everything else is the same as in the previous post). Nothing in the Error Console this time. If I comment out foo.parentNode.removeChild(foo) then nothing gets removed.
It sounds to me like you're trying to remove a node that doesn't exist (foo.nextSibling), so maybe there is no sibling after the returned result. The returned result? You mean the TD itself? In that case, there isn't. That's visible in the test case page above. I would like the script to: - Match TD that contains text - Remove next non-sibling element after TD, or next sibling of its parent element (same thing) - Remove its parent element I'm sorry, I hope this isn't too much trouble. |
|
|
Now it gets rid of the whole table instead of the two rowsI read this line and realised I'm being stupid. Before, we were grabbing an element in the row, and now we're grabbing the row instead of an element in it, but I didn't change how many times we go up a node. That is, we only need to go up once to get the row we want to remove, and not twice. Change the line foo = images.snapshotItem(i).parentNode.parentNodeto foo = images.snapshotItem(i).parentNode Sorry about that, I don't know why I didn't spot that one. |
|
|
Change the line Now it only removes the first TR (whose child TD matches "Miscellaneous text"). Wouldn't it be simpler to match the elements with XPath and then just remove them? There wouldn't be a need to know how many nodes to go up or down and so on. The following makes the alert display 2 but still only removes the first TR.
images = document.evaluate('//tr[td[text()="Miscellaneous text"]]/following-sibling::node()[position()=1]|//tr[td[text()="Miscellaneous text"]]',document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null)
alert(images.snapshotLength)
for (i = 0; i < images.snapshotLength; i++) {
foo = images.snapshotItem(i)
foo.parentNode.removeChild(foo)
}
Edit
After a maddening amount of trial and error, I managed to get it to work by duplicating it as follows: first try to remove the sibling of the parent TR, then both the parent TR and the sibling TR. As far as I can tell, nothing else works and I have no idea why.
images = document.evaluate('//tr[td[text()="Miscellaneous text"]]/following-sibling::node()[position()=1]',document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null)
for (i = 0; i < images.snapshotLength; i++) {
foo = images.snapshotItem(i)
foo.parentNode.removeChild(foo)
}
images = document.evaluate('//tr[td[text()="Miscellaneous text"]]|//tr[td[text()="Miscellaneous text"]]/following-sibling::node()[position()=1]',document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null)
for (i = 0; i < images.snapshotLength; i++) {
foo = images.snapshotItem(i)
foo.parentNode.removeChild(foo)
}
If you have any other tips, I'm all ears, if not, then thank you very much for your invaluable help. I really appreciate it. |
