1

I want to dynamically set the text of a p element with styling, but I do not know how to do this.

Here is my HTML element: <p id="delete-speaker-info-message"> </p>

Here is my current code to set the text:

document.getElementById("delete-speaker-info-message").innerHTML = `Are you sure you want to delete <b>${speakerName}</b> from <b>${eventName}</b>? This cannot be undone.`

Although the code above works, the speakerName, and eventName values are user inputted and need to be escaped. I know innerText can do this but it also escapes the bold tags. I am sure there is a way to do this but I just could not find it online. Thanks for the help!

Lin Du
  • 88,126
  • 95
  • 281
  • 483
chiragzq
  • 388
  • 1
  • 14

2 Answers2

1

You should use something like my special function:

//<![CDATA[
/* external.js */
var doc, bod, I, special, unspecial; // for use on other loads
addEventListener('load', function(){
doc = document; bod = doc.body;
I = function(id){
  return doc.getElementById(id);
}
special = function(str){
  return str.replace(/&/g, '&amp;').replace(/'/g, '&apos;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
unspecial = function(str){
  return str.replace(/&amp;/g, '&').replace(/&apos;/g, "'").replace(/&quot;/g, '"').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
}
var speakerName = '<i>Cool Joe</i>', eventName = '<div>Keeping it Real</div>';
var deleteSpeakerInfoMsg = I('delete-speaker-info-message');
deleteSpeakerInfoMsg.innerHTML = 'Are you sure you want to delete <b>'+special(speakerName)+'</b> from <b>'+special(eventName)+'</b>? This cannot be undone.';
console.log(deleteSpeakerInfoMsg.innerHTML);
}); // end load
//]]>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
  <head>
    <meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1' />
    <title>Test Template</title>
    <link type='text/css' rel='stylesheet' href='external.css' />
    <script type='text/javascript' src='external.js'></script>
  </head>
<body>
  <div id='delete-speaker-info-message'></div>
</body>
</html>
StackSlave
  • 10,613
  • 2
  • 18
  • 35
1

Your best bet is to use a templating library. If you try to roll your own, you're probably going to mess it up and end up with XSS vulnerabilities. There's always a hacker out there who will think of something you haven't. Using a library also lets you do nice things like have an html template and pass in variables to be safely interpolated into it.

It sounds like you're not using any of the larger frameworks like React or Angular, so I'd say Lodash's template function is your best bet. Here's an example from their docs:

// Use the HTML "escape" delimiter to escape data property values.
var compiled = _.template('<b><%- value %></b>');
compiled({ 'value': '<script>' });
// => '<b>&lt;script&gt;</b>'
frodo2975
  • 10,340
  • 3
  • 34
  • 41