0

Please forgive me and let me know if my post is not right since I am brand new to this forum.

I have found most of the answer here (Create a <ul> and fill it based on a passed array), but my problem comes with .createTextNode. My users are using multiple editor boxes to build an outline. Within these boxes they can format the text (underline, color, bold, etc.). So the array items that I am passing to .createTextNode actually have HTML tags in them to format the line items. However .createTextNode makes it just plain text which in turn just spits out the tag instead of applying it when displayed via document.getElementById('foo').appendChild...

I know that I should stay away from HTML concatenation but it is looking very tempting.

Is there any way to retain the formatting of the list items when appended and displayed?

Thank you in advance for your assistance.

Community
  • 1
  • 1
Kevin
  • 17
  • 5
  • Try innerHTML instead of createTextNode – Leo Dec 03 '14 at 03:28
  • Well, if your HTML string is already constructed there's really nothing wrong in letting the browser parse that for you. Just set the `innerHTML` property of the nodes. – plalx Dec 03 '14 at 03:35

1 Answers1

0

Try innerHTML, which will try to parse the content string as HTML structure. For example you have a P tag

<p id="asdf"></p>
<script>
    document.getElementById('asdf').innerHTML = '<a href="#">qwerty</a>';
</script>

Will give you a clickable anchor

<p id="asdf">
    <a href="#">qwerty</a>
</p>

But be careful!!! (Notice I use three bang sign here) You must be sure there's no harmful code before you insert it. Check this example:

document.getElementById('asdf').innerHTML = '<img src="image.png" onload="alert(1)">'

You will see an alert dialog. This example is simple though, in practice it can be much more dangerous, e.g. dynamically append a cross site script into you page, aka XSS.


EDIT: here is a demo.

var options = ['<a href="#">Option 1</a>','<a href="#">Option 2</a>'];

function makeUL(){
    var LIs = '';

    for (i = 0; i < options.length; i += 1){
        LIs += '<li>' + options[i] + '</li>';
    }

    return '<ul>' + LIs + '</ul>';
}
    
document.getElementById('foo').innerHTML = makeUL();
<div id="foo"></div>
Leo
  • 13,428
  • 5
  • 43
  • 61
  • In the link example that is in my original post where would I use innHTML? I tried 'code' // Add the contents of options[0] to #foo: document.getElementById('foo').appendChild(makeUL(options[0])); 'code' – Kevin Dec 03 '14 at 14:18
  • sorry hit enter before I was done on my last comment.In the link example that is in my original post where would I use innHTML? I tried [code] document.getElementById('foo').innerHTML = (makeUL(options[0]));[[code] instead of [code] document.getElementById('foo').appendChild(makeUL(options[0])); [code]. But it printed "object". OR do I use it when I set the contents, so how would I use .innherHTML instead of [code] item.appendChild(document.createTextNode(array[i])); [code] – Kevin Dec 03 '14 at 14:35
  • Updated the fiddle, I think that'll be quite clear for you now. – Leo Dec 03 '14 at 14:37
  • the value set as innerHTML should be: (1) string type; (2) represents valid HTML structure. – Leo Dec 03 '14 at 14:38
  • Ok just saw your Fiddle link. So that seems to me to be building HTML or HTML concatenation through a function. I was thinking of that originally but most posts said to use the DOM instead which may not be possible in my scenario. Thank you, I will wait for some other comments but if I do not see any other DOM solutions I will mark your as the answer. – Kevin Dec 03 '14 at 14:41
  • That really depend. `innerHTML` has very good compatibility, and in some cases much easier than createElement/appendChild. For example to construct a table. In your case since user content may have HTML structure, `innerHTML` would be much easier, otherwise you have to do syntax analysis by yourself. In practice I actually use both ways, depending on the use case. – Leo Dec 03 '14 at 14:46