0

I have the following array:

["uploads-1462948491987.png", "uploads-1462948492004.png"]

What I want to achieve is have an unordered list of anchors (inside list items) with image names. I have done the following:

var uploadsList = document.querySelector('ul'),
    imageitem = document.createElement('li'),
    anchorTag = document.createElement('a');

anchorTag.setAttribute('href',"#");

var imagesNamesString = "<%= uploads %>";
var imageNames = imagesNamesString.split(',');


imageNames.forEach(function(image) {
    anchorTag.innerHTML = image;
    uploadsList.appendChild(imageitem.appendChild(anchorTag));
});

console.log(imageNames);

Problem is, the last image is the only one which appears on the list, what may be causing this? Thanks in advance.

2
  • Are you sure you're not overriding the same element properties on each loop? Commented Apr 12, 2017 at 16:38
  • You are overwriting the HTML of your single anchor tag each time: anchorTag.innerHTML, so you will only show the last one. Commented Apr 12, 2017 at 16:38

1 Answer 1

3

Cannot create multiple list items in javascript

Because you're not creating multiple list items. You're creating one:

imageitem = document.createElement('li')

...and then using it:

uploadsList.appendChild(imageitem.appendChild(anchorTag));

where first you append anchorTag to the li, then immediately move it to the uploadsList (because appendChild returns the node appended, not the node you called it on). The same for the anchor, you're reusing one, not creating one for each image.

You need to create the li and anchor in the loop, and append the li, not the anchor:

imageNames.forEach(function(image) {
    var li = document.createElement('li');
    var anchor = document.createElement('a');
    anchor.href = "#"; // No need for `setAttribute
    anchor.appendChild(document.createTextNode(image));
    li.appendChild(anchor);
    uploadsList.appendChild(li);
});

var imageNames = ["uploads-1462948491987.png", "uploads-1462948492004.png"];

var uploadsList = document.querySelector('ul');

imageNames.forEach(function(image) {
  var li = document.createElement('li');
  var anchor = document.createElement('a');
  anchor.href = "#"; // No need for `setAttribute
  anchor.appendChild(document.createTextNode(image));
  li.appendChild(anchor);
  uploadsList.appendChild(li);
});

document.body.appendChild(uploadsList);
<ul></ul>

Note that I replaced the use of innerHTML with:

anchor.appendChild(document.createTextNode(image));

You probably don't want to interpret the image names as HTML. But if you do, just change it back to:

anchor.innerHTML = image;

Or at that point, really, just

imageNames.forEach(function(image) {
    var li = document.createElement('li');
    li.innerHTML = "<a href='#'>" + image + "</a>";
    uploadsList.appendChild(li);
});

var imageNames = ["uploads-1462948491987.png", "uploads-1462948492004.png"];

var uploadsList = document.querySelector('ul');

imageNames.forEach(function(image) {
    var li = document.createElement('li');
    li.innerHTML = "<a href='#'>" + image + "</a>";
    uploadsList.appendChild(li);
});

document.body.appendChild(uploadsList);
<ul></ul>

But I recommend not treating the image names as HTML (unless you actually put HTML in them).


Note that I changed the name anchorTag to anchor. An element is not a tag. A tag is how we define elements textually in HTML. <a> and </a> are tags (a start tag and an end tag, respectively); a is an element.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the answer, the structure looks a bit odd though how/where can I add a document.write("<br>"); to make look better?
@TheBrokenSpanner: There's no reason it should need further breaks, unless you've styled li elements in some way. I've added live examples of the options above in case it was an error applying the changes to your code. The structure is a simple list: <ul><li><a>..></a></li><li><a>...</a></li></ul>...
Ok, I have a custom css file so I may have put something earlier. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.