0

Okay, so quite a smile question that I am stuck with. I am attempting to make a HTML text box that when submitted, the text is thrown into a function and checked to see if there are any links. If there is a link, it is wrapped in anchor tags and made into a clickable link.

So I got that part working, but I then created an edit function. So when an edit button is pressed on the comment, a popup is shown with the created comment. The value of the comment (taken from an XML file) is placed into the value of this edit text area. But the value of the links still has the anchor tags, so it looks extremely messy.

I am trying to make a function that runs over this comment and removes any anchor tags and just has the remaining text within the anchor tags.

Simple example, when a user posts a comment, with a link like www.stackoverflow.com, it will be saved in my XML document like so:

<a href="www.stackoverflow.com">www.stackoverflow.com</a>

It also works for if the user posts the link with http:// at the beginning.

I am now trying to revert the link to normal text like it was before.

Here are both of my functions. The first one, convertLink works perfectly. convertLinkEdit is attempting to revert the process, but I am having no luck.

function convertLink(text) {
  var words = text.split(' ');
  var newText = '';

  for (var i = 0; i < words.length; i++) {
    var word = words[i];
    if (word.indexOf('http://') === 0) {
      word = '<a href=" ' + word + ' ">' + word + '</a>';
    } else if (word.indexOf('www.') === 0) {
      word = '<a href=" http://' + word + '" >' + word + '</a>';
    }

    newText += word + ' ';
  }

  return newText;
}

function convertLinkEdit(text) {
  var words = text.split(' ');
  var newText = '';

  for (var i = 0; i < words.length; i++) {
    var word = words[i];
    if (word.indexOf('href=') === 0) {
      //if index of finds "href=", it means a link is coming up
      //Therefore, since everything is split at blank spaces,
      //after the next blank space will be the current text that needs saving
    }

    newText += word + ' ';
  }

  return newText;
}

Inside my non working function is comments on how I think it should be done, although I am not to sure on how to implement.

pb2q
  • 58,613
  • 19
  • 146
  • 147
Fizzix
  • 23,679
  • 38
  • 110
  • 176
  • Can you not grab the `innerHTML` of the anchor tag?? – Sethen Apr 03 '13 at 03:15
  • What about the case when a user provides the text as "this href= something". In your edit function it will be considered as a link, or is there a check for such kind of inappropriate input ?? – vdua Apr 03 '13 at 03:17
  • @SethenMaleno - Honestly, I'm not to sure how to do that? – Fizzix Apr 03 '13 at 03:28
  • @vdua - I am basically just hoping they don't do that haha.. – Fizzix Apr 03 '13 at 03:29

4 Answers4

2

Actually, DOM is smart enough to parse the link into text for you, so you can simply use this (link to jsFiddle):

function convertLinkEdit(text) {
    // simply create an empty <p> element
    var dummy = document.createElement('p');
    
    // change it's HTML contents to the comment one
    dummy.innerHTML = text;

    // return the TEXT value of our <p>
    return dummy.textContent || dummy.innerText; // we first look up textContent* (newer browsers) and fall back to innerText (older browsers) if needed
}

* For information on textContent look here: https://developer.mozilla.org/en-US/docs/DOM/Node.textContent

I have no idea on browser compatibility for above though, so, here is (link to jsFiddle) RobG's variation applied to your function:

function convertLinkEdit(text) {
    var dummy = document.createElement('p');
    dummy.innerHTML = text;
    
    var links = dummy.getElementsByTagName('a');
    
    for (var i = 0, l = links.length; i < l; i++)
    {
        var link = links[i];
        var node = document.createTextNode(link.textContent || link.innerText);
        link.parentNode.replaceChild(node, link);
    }
    
    return dummy.textContent || dummy.innerText;
}

FYI: You should always use DOM and it's APIs for parsing / manipulating HTML. Regex is highly discouraged to be used for HTML parsing.
Yes, it might work in some cases, but you have no control over it, because it won't properly distinguish attributes, elements and all the other mess DOM comes with.

Update:

http://jsfiddle.net/2b8uz/5/ here is an updated version.

The problem is that, as plaxl already noted, that getElementsByTagName and any other getElement.. family member will return a NodeList that is a Live object. Once an element in the NodeList changes, it's automatically updated.

I added a little snippet borrowed from here, that will convert NodeList to simple array before entering the conversion loop.

Although, if the first version of the function works for you, use that one, it should be much faster than looping over 2 times.

Community
  • 1
  • 1
tomsseisums
  • 13,168
  • 19
  • 83
  • 145
1

This should work, however there might be more efficient ways of doing it. I tested performance and it seems way faster than the accepted solution, however I guess it might not be as reliable. Here's the test http://jsperf.com/replace-links

 function convertLinkEdit(text) {
    var rx = /<a [^>]*?href="([^"]+)"[^>]*>[^<]*<\/a>/g;

    convertLinkEdit = function (text) {
        return text.replace(rx, '$1');
    };

    return convertLinkEdit(text);

}
plalx
  • 42,889
  • 6
  • 74
  • 90
  • Never used a regex before, might have to give it a read so I understand whats going on. – Fizzix Apr 03 '13 at 03:30
  • This is a project that I am working on, and trying to leave jQuery out of it :) – Fizzix Apr 03 '13 at 03:34
  • Also, I am getting an error from your code stating: text.match(rx) is null – Fizzix Apr 03 '13 at 03:35
  • What are you passing as `text` exactly? – plalx Apr 03 '13 at 03:36
  • A large (or small) message created by a user from a text area. I have a variable that is the contents of the message being pulled from my XML document. That variable (now being the large message), is then pushed into the functions, like so: editMessage = convertLinkEdit(editMessage); – Fizzix Apr 03 '13 at 03:39
  • Oh ok, I assumed you were passing the link's html only. Let me fix this. – plalx Apr 03 '13 at 03:41
  • Ahhh right. Yeah, I am passing the full message into this function. I require the function to then return the new text as a brand new full message with the fixed links. – Fizzix Apr 03 '13 at 03:43
  • You are right, it runs way faster. it also allows the input of two or more links, while my previous selected answer did not. Thanks for your help :) – Fizzix Apr 03 '13 at 04:43
0

Consider looking for links, then replacing the link element with a text node of its content. The following will replace every link in the page with it's content:

windowonload = function() {

  var links = document.links;
  var link, node;
  var i = links.length;

  while (i--) {
    link = links[i];
    node = document.createTextNode(link.textContent || link.innerText);
    link.parentNode.replaceChild(node, link);
  }
};
RobG
  • 142,382
  • 31
  • 172
  • 209
  • I am not to sure on how to implement this into its own function with a return of the links content..? – Fizzix Apr 03 '13 at 03:36
0

you can use regex for finding the href. Since your word will be href="someurl">

var res = word.match(/^href="(.+)">/;
if (res && res.length == 2) 
{
     //res[1] will be your url, do whatever you want with it
}

Assumption your links are created as I have mentioned before and your href attribute has " instead of the ' quote.

vdua
  • 1,281
  • 1
  • 14
  • 24