astralaaron Posted October 2, 2013 Share Posted October 2, 2013 I need to be able to strip out everything inside of a <td id="abc"></td> except for an anchor tag... for example: <td id="abc"> <a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td> needs to become <td id="abc"> <a id="a1" href="">test</a></td> really appreciate any help Link to comment Share on other sites More sharing options...
justsomeguy Posted October 3, 2013 Share Posted October 3, 2013 With Javascript? I guess one way would be to use regular expressions to match every anchor tag, and then rebuild the content with just the matches. Link to comment Share on other sites More sharing options...
astralaaron Posted October 3, 2013 Author Share Posted October 3, 2013 Thanks JSG. I was able to get around my problem with some css...(the tables are auto generated content by a CMS)... what I did was set the font-size to 0 of everything in the TD's then set the font size of the anchors back to their normal size and it worked out. Link to comment Share on other sites More sharing options...
davej Posted October 3, 2013 Share Posted October 3, 2013 (edited) <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Strip Children</title><script>window.onload = init;function init(){document.getElementById('btn1').onclick = strip;document.getElementById('btn2').onclick = show;}function show(){var txt="";var c=document.getElementById('abc').childNodes;for (i=0; i<c.length; i++){txt = txt + c[i].nodeName + "<br>";}var x = document.getElementById("out"); x.innerHTML=txt;}function strip(){var base = document.getElementById('abc');var ch = null;var found = false;do{if (found == false){ch = base.firstChild;}else{ch = base.lastChild;}if (ch != null){if ( ch.nodeName == 'A' ){found = true;}else{//alert('deleting '+ch.nodeName);base.removeChild(ch);}}}while(base.firstChild !== base.lastChild);}</script></head><body><table><tr><td id="abc"><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td></tr></table><br/><input type="button" id="btn1" value="Strip Unwanted"/><input type="button" id="btn2" value="Show All Children"/><div id="out"></div></body></html> Edited October 3, 2013 by davej Link to comment Share on other sites More sharing options...
thescientist Posted October 3, 2013 Share Posted October 3, 2013 Or you could just set the display of all child elements in a <td> tag that you want to hide to none td b{ display: none;} Link to comment Share on other sites More sharing options...
astralaaron Posted October 3, 2013 Author Share Posted October 3, 2013 Thanks for the response everyone. (davej, I haven't tried that out yet, I will today. I appreciate you typing all of that up) Or you could just set the display of all child elements in a <td> tag that you want to hide to none td b{ display: none;} Thescientist, that was my first thought, I tried something like this but since not all of the text is within the <b> tag, or any other element It wouldn't work. The <a> would also display none. I tried adding display:block!important; to the <a> but had no luck. Link to comment Share on other sites More sharing options...
astralaaron Posted October 3, 2013 Author Share Posted October 3, 2013 by the way davej, this CMS I am working with is using some really bad practices (multiple td's with the same ID) your script strips out the first <td id="abc"> but leaves all of the others alone. Any way around this? Link to comment Share on other sites More sharing options...
davej Posted October 3, 2013 Share Posted October 3, 2013 It might help if we actually saw that section of the HTML markup. Multiple elements with the same id isn't just poor practice -- it is a total screw-up. Link to comment Share on other sites More sharing options...
thescientist Posted October 3, 2013 Share Posted October 3, 2013 Thanks for the response everyone. (davej, I haven't tried that out yet, I will today. I appreciate you typing all of that up) Thescientist, that was my first thought, I tried something like this but since not all of the text is within the <b> tag, or any other element It wouldn't work. The <a> would also display none. I tried adding display:block!important; to the <a> but had no luck. the <a> wouldn't be hidden unless it was in something else that was hidden, if you only target by element like in my example. also, your example didn't indicate that there would be text not in elements, so if that's the case, then that wouldn't work. another suggestion is set all the text to the same color as the background of the page, and just give a color to the <a> tags. Link to comment Share on other sites More sharing options...
astralaaron Posted October 3, 2013 Author Share Posted October 3, 2013 It might help if we actually saw that section of the HTML markup. Multiple elements with the same id isn't just poor practice -- it is a total screw-up. lol I agree.. its just like your example but with multiple td id="abc" The scientist, if you look at my example: <td id="abc"> <a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td> the "qwert qwert" is not inside of the <b> tags. So when I do display none on the abc id, obviously it will hide all it including the anchor. Setting the text to the background color doesnt work out because I need to get rid of the spacing as well, I forgot to mention there are some break lines in there after the <b> tags. Setting the font size to 0 worked out but I don't have access to IE currently, so I am just hoping it is working cross browser. For learning purposes though I appreciate the javascript example Link to comment Share on other sites More sharing options...
astralaaron Posted October 3, 2013 Author Share Posted October 3, 2013 Well it turns out in IE7 there is an issue with the way that I used font-size:0 to handle this... so I will need to do something else. I am going to try to use davej's example to build from. I appreciate any help with this. Here is an example of the table I need to strip from: <table id="news01"><tr><td id="abc"><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td></tr><tr><td id="abc"><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td></tr><tr><td id="abc"><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td></tr></table> I guess what needs to happen is grab the table id, and filter through the child elements and apply the changes to each table definition... I'm going to try my best to figure it out, again I appreciate any help. Link to comment Share on other sites More sharing options...
davej Posted October 3, 2013 Share Posted October 3, 2013 We just need a starting point that we can trust and need to understand which td's you want to clear out. Link to comment Share on other sites More sharing options...
astralaaron Posted October 3, 2013 Author Share Posted October 3, 2013 All of the td's inside of the <table id="news01"> Link to comment Share on other sites More sharing options...
justsomeguy Posted October 3, 2013 Share Posted October 3, 2013 Get the table element, loop through the child nodes (which should be the tr elements), loop through the children of those (which should be the td elements), use a regular expression to pull out any anchor element, and replace the innerHTML of the td with the anchors from it. That's what I was talking about in post 2. If you want to remove the contents of the element, that is how to do it, not trying to hide things with CSS. Alternatively, you could loop through the child nodes of each td and remove any node that is not an anchor. Either way, whether you use a regular expression to update the innerHTML, or remove the nodes you don't want, that is the correct way to do it. Link to comment Share on other sites More sharing options...
astralaaron Posted October 3, 2013 Author Share Posted October 3, 2013 Thanks JSG. Is a regular expression the only way? Davej's example seemed to work for the one TD. I am very comfortable with regular expressions. I guess this is a good time to get some practice in. By the way I didn't nececarily need to remove, hiding is really all I needed, but I ran into problems with older versions of IE. Link to comment Share on other sites More sharing options...
justsomeguy Posted October 3, 2013 Share Posted October 3, 2013 I would be more reliable to loop through the child nodes in the td and remove everything that isn't an anchor, rather than dealing with regular expressions. If you do that, you want to loop backwards to make sure you don't miss anything or get errors about the index being out of bounds as you remove nodes, e.g.: for (i = td.childNodes.length - 1; i >= 0; i--) Link to comment Share on other sites More sharing options...
davej Posted October 3, 2013 Share Posted October 3, 2013 If there is only one link per td then try... <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Strip Children from td's in table except links </title><script>window.onload = init;function init(){document.getElementById('btn1').onclick = tableloop}function tableloop(){var table = document.getElementById('abc');var list = table.getElementsByTagName('td');for(var i=0 ; i<list.length ; i++){strip(list[i]);}}function strip(base){ //base parameter is a td elementvar ch = null;var found = false;do{if (found == false){ch = base.firstChild;}else{ch = base.lastChild;}if (ch != null){if ( ch.nodeName == 'A' ){found = true;}else{//alert('deleting '+ch.nodeName);base.removeChild(ch);}}}while(base.firstChild !== base.lastChild);}</script></head><body><table id="abc"><tr><td><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td><td><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td></tr><tr><td><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td><td><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td></tr></table><br/><input type="button" id="btn1" value="Strip Unwanted"/><div id="out"></div></body></html> Link to comment Share on other sites More sharing options...
astralaaron Posted October 4, 2013 Author Share Posted October 4, 2013 Thanks a bunch davej I am going to mess with this a bit later. Link to comment Share on other sites More sharing options...
astralaaron Posted October 4, 2013 Author Share Posted October 4, 2013 First of all, davej's example worked perfect for what I needed. That being said, I am messing around and trying to add multiple <a> tags and make it work. here is what I came up with so far: <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Strip Children from td's in table except links </title><script>window.onload = init;function init(){document.getElementById('btn1').onclick = tableloop}function tableloop(){var table = document.getElementById('abc');var list = table.getElementsByTagName('td'); for(var j=0; j < list.length; j++) { for(var i=0; i < list[j].childNodes.length; i++) { if(list[j].childNodes[i].nodeName != 'A') { list[j].removeChild(list[j].childNodes[i]); } } }}</script></head><body><table id="abc"><tr><td><a id="a1" href="">test1</a><b>asdf</b>qwert qwert<a id="a1" href="">test2</a><b>werq</b>qwert</td></tr><tr><td><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td></tr><tr><td><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td></tr><tr><td><a id="a1" href="">test</a><b>asdf</b>qwert qwert<b>werq</b>qwert</td></tr></table><br/><input type="button" id="btn1" value="Strip Unwanted"/><div id="out"></div></body></html> It works, except for it will not remove the bold text. It seems like <b>test</b> may be counted as 1 node instead of 3...and will not remove? I am not quite sure...any simple fix to this? or is it more complicated, as far as needing to check each node for their own child nodes? thanks for the help! Link to comment Share on other sites More sharing options...
astralaaron Posted October 4, 2013 Author Share Posted October 4, 2013 Well, this works: for(var j=0; j < list.length; j++) { var bold = list[j].getElementsByTagName('b'); for(var x=0; x < bold.length; x++) { for(var y=0; y < bold[x].childNodes.length; y++) { bold[x].removeChild(bold[x].childNodes[y]); } } for(var i=0; i < list[j].childNodes.length; i++) { if(list[j].childNodes[i].nodeName != 'A') { list[j].removeChild(list[j].childNodes[i]); } } } I guess for each type of tag I would need to add a loop. Link to comment Share on other sites More sharing options...
justsomeguy Posted October 4, 2013 Share Posted October 4, 2013 That's why I suggested looping backwards. You're probably skipping some nodes. You remove childNodes, and when you do that childNodes get updated. So childNodes[i+1] is not the next node, it's 2 nodes later. The childNodes collection is a "live" collection that updates as nodes are added or removed. If you looped backwards then that wouldn't happen. Link to comment Share on other sites More sharing options...
astralaaron Posted October 4, 2013 Author Share Posted October 4, 2013 ahh right I totally spaced that you mentioned to loop backwards. I'll give that a shot. Link to comment Share on other sites More sharing options...
astralaaron Posted October 4, 2013 Author Share Posted October 4, 2013 perfect! thanks JSG for(var j=0; j < list.length; j++) { for(var i=list[j].childNodes.length-1; i > 0; i--) { if(list[j].childNodes[i].nodeName != 'A') { list[j].removeChild(list[j].childNodes[i]); } } } Link to comment Share on other sites More sharing options...
davej Posted October 4, 2013 Share Posted October 4, 2013 I don't completely follow what you are doing. Do you need to be able to handle the possibility of multiple links in each td? I seemed to see some erratic results when I tried the array approach. Maybe the array would work fine if you started over at index 0 after every delete. Link to comment Share on other sites More sharing options...
justsomeguy Posted October 4, 2013 Share Posted October 4, 2013 Instead of starting over, the loop above starts with the last node and loops to the first, deleting anything that is not an anchor. You only need to go through the loop once. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now