0

I am trying to give link to phone numbers in a page using javascript. SO Post is helpful but it also update contents in input box, href, src etc. How to update phone numbers that are not tag attribute and text inside <a> tag

var regex = /((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}/g; 
var text = $("body:first").html();
text = text.replace(regex, "<a href=\"tel:$&\">$&</a>");

jsfiddle

Community
  • 1
  • 1
Vishnu V
  • 382
  • 5
  • 16

3 Answers3

2

Since you need to update phone numbers that are not tag attributes and not the content inside an anchor tag, you can change the regexp to use negative lookahead.

This would be the regex -

((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}(?!([^<]*>)|(((?!<a).)*<\/a>))
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Modified part

Explaining the regex -

The first part of the regex is the same.The second part is a negative lookahead. If the regexp inside the (?! ) matches, then that is not the required string. So we need to match the tag attributes and the innerHTML of anchor tag.

For values inside tag attributes, this is the regexp

([^<]*>)

For content in anchor tag -

(((?!<a).)*<\/a>)

Placing both the regexps above inside the negative lookahead allows you to negate the strings that the above match.

It seems to work in this Fiddle.
You can check the matches for the regex here.

Kamehameha
  • 5,423
  • 1
  • 23
  • 28
0
var regex = /((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}/g; 

var text = $("body:first").text();

text = text.replace(regex, "<a href=\"tel:$&\">$&</a>");

$("body:first").html(text);

please try this

demo: http://jsfiddle.net/PShYy/34/

Karthick Kumar
  • 2,349
  • 1
  • 17
  • 30
0

Check this out: http://jsfiddle.net/PShYy/35/

// match every element in body, go to its contents
$("body:first").find('*').contents().filter(function(){
    //if it's a text node, if its value matches the regex an it's not a child of an anchor
    if(this.nodeType == 3 && regex.test(this.nodeValue) && this.parentElement.tagName !== "A"){
        // create an anchor
        var anchor = document.createElement('a');
        // set its attribute to the phone number
        anchor.setAttribute('href', this.nodeValue.match(regex)[0]);
        // set the anchor's contents to be the same as its href attribute value
        anchor.appendChild(document.createTextNode(this.nodeValue.match(regex)[0]));

        // append it after the original text node
        if(this.nextSibling)
            this.parentElement.insertBefore(anchor, this.nextSibling);
        else
            this.parentElement.appendChild(anchor);

        // remove the phone number from the original text node
        this.nodeValue = this.nodeValue.replace(regex, '');
    }
});

You could do it your way just by modifing the regex but if you replace the whole body with a new altered html, all the event listeners on your elements etc. will stop working.

kamilkp
  • 9,690
  • 6
  • 37
  • 56