Using innerHTML.replace to replace text to create link
I am using Sharepoint (WSS 3.0) which is unfortunately very limited in its ability to format survey questions (i.e. it removes any HTML you enter). I saw a solution elsewhere that suggested adding JS to our master page file to allow line breaks. This works great, but I would like to see if we can resolve links as well.
In our WSS polls, I can now use {{br}} wherever I want a line break (it works). I tried extending the code to use link tags (e.g. {{link1}} url {{link2}} URL Title {{link3}} but that doesn't work, apparently because the updates are not (FF and IE show different results, but both don't work. If I mix the JS order below - ie do link3, 2 and then 1 - the output changes too, but still doesn't work.) Is there a better way to do this?
<script language="JavaScript">
var className;
className = 'ms-formlabel';
var elements = new Array();
var elements = document.getElementsByTagName('td');
for (var e = 0; e < elements.length; e++)
{
if (elements[e].className == className){
elements[e].innerHTML = elements[e].innerHTML.replace(/{{br}}/g,'<br/>');
elements[e].innerHTML = elements[e].innerHTML.replace(/{{link1}}/g,'<a href="');
elements[e].innerHTML = elements[e].innerHTML.replace(/{{link2}}/g,'">');
elements[e].innerHTML = elements[e].innerHTML.replace(/{{link3}}/g,'</a>');}
}
</script>
a source to share
Instead of changing the innerHTML property in chunks (the browser tries to update the DOM every time you change innerHTML), which if you provide incomplete / broken markup will obviously get messed up), make all your changes against your own string variable and then rewrite the entire innerHTML with your terminated line:
<script language="JavaScript">
var className;
className = 'ms-formlabel';
var elements = new Array();
var elements = document.getElementsByTagName('td');
for (var e = 0; e < elements.length; e++)
{
if (elements[e].className == className) {
var newHTML = elements[e].innerHTML;
newHTML = newHTML.replace(/{{br}}/g,'<br/>');
newHTML = newHTML.replace(/{{link1}}/g,'<a href="');
newHTML = newHTML.replace(/{{link2}}/g,'">');
newHTML = newHTML.replace(/{{link3}}/g,'</a>');}
elements[e].innerHTML = newHTML;
}
</script>
a source to share
The simple answer would be to create innerHTML and replace it right away:
for (var e = 0; e < elements.length; e++)
{
if (elements[e].className == className) {
var newHTML = elements[e].innerHTML;
newHTML = newHTML.replace(/{{br}}/g,'<br/>');
newHTML = newHTML.replace(/{{link1}}/g,'<a href="');
newHTML = newHTML.replace(/{{link2}}/g,'">');
newHTML = newHTML.replace(/{{link3}}/g,'</a>');
elements[e].innerHTML = newHTML;
}
}
A more complex answer would be to use capturing groups in your regex and pass the function as the second parameter to replace () to use one call to replace () for HTML. For instance,
elements[e].innerHTML = elements[e].innerHTML.replace(/({{link1}})|({{link2}})|({{link3}})/g,
function (match) {
var map = {
'{{link1}}' : '<a href="',
'{{link2}}' : '>',
'{{link3}}' : '</a>', }
return map[match];
});
The second solution is more complex and results in some ugly regex, but is more efficient than calling replace () over and over again.
a source to share