Cannot create multiple list items in javascript - javascript

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.

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.

Related

Create list with hyperlink (document fragments) as text string

I am totally new at javascript and am trying to create a dynamic list in JavaScript that is both a hyperlink to and shows the text string of a tag in my html code that has the id = v1. Kind of like a menu to different parts of that same webpage.
I have tried to do this using document fragments (https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks#document_fragments) but it is not working and I don't have any idea of how to insert the text string of the in the "menu".
Here is part of my code:
var container = document.getElementById("contentarea");
var header = document.getElementById("v1");
for (i = 0; i < length.header; i++) {
$(document.createElement("li")).li;
$(document.createElement("a")).link.append(li)( {
href: "#v1"
})
list.appendChild(li);
container.appendChild(list)
}
You could do something like this
// div to get the textContent from, replace it with whatever you want
const divE = document.getElementById('test');
// our list tag
const list = document.getElementById('list');
// looping
for (let i = 0; i < 4; i++) {
const listEl = document.createElement('li'); // our list element
const aTag = document.createElement('a'); // a new <a> tag to append link
const linkTag = document.createElement('link'); //new link tag
linkTag.href = '#test'; // setting hyperlink
aTag.textContent = divE.textContent // setting the textContent for <a> tag
aTag.appendChild(linkTag); // appending link to the a tag
listEl.appendChild(aTag); // appending a tag to the <li> tag
list.appendChild(listEl) // finally appending our list element to the main list
}
<div id="test">Something here</div>
<ul id="list"></ul>

How to create HTML tags (with content) on the fly with JavaScript?

I am trying to convert this HTML code to be generated by Javascript on the fly for live data.
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
Ive found a few methods like: appendChild, getElementById, innerHTML and so on. Here is what I've tried so far. I can't seem to get the data to show up.
stringy = data2.Items[0].groupName.values[i];
var para = document.createElement("div");
var node = document.createTextNode(stringy);
para.appendChild(node);
var element = document.getElementById("parental");
element.appendChild(para);
//create div and give it a class
para.setAttribute('class', 'dropbtn');
var div = document.createElement("div");
div.setAttribute('class', 'dropdown-content');
para.parentNode.insertBefore(div, para.nextSibling);
//create link tags and give them text
var alinky = document.createElement("a");
alinky.setAttribute('id', 'linky');
document.getElementById('linky').innerHTML = "linky poo"
div.appendChild(alinky);
Hopefully someone could fill in the blanks on getting this HTML code to be reproduced with javascript. Thanks in advance!
EDIT:
I am trying to create a dropdown menu like this:
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_js_dropdown_hover
However, I am trying to create multiple dropdown menus, that dynamically change in quantity based on a query to DynamoDB (AWS). therefore I am using javascript to create the html tags.
The problem is that the scope of the query function does not allow me to see the data outside of the query function, or even inject data into it.
For example, if I try to get a button description from the query, and write to it descriptionArray[0] = data2.Items[0].description; so that I can append the button to the dropdown div, it doesn't know which iteration I'm on in the for loop due to scope. In this example, descriptionArray[0] will work, but descriptionArray[i] will not work because the for loop is outside the query.
Here is the entire logic:
//group data
var length = data2.Items[0].groupName.values.length;
// create elements
const dpdown1 = document.createElement('div');
// set dpdown1 class
dpdown1.setAttribute('class', 'dropdown');
console.log(dpdown1);
var button = new Array();
var dpdown2 = new Array();
var membersArray = new Array();
var descriptionArray = new Array();
var linksArray = new Array();
var stringy = new Array;
//list groups
for(i = 0; i<length; i++){
// create button, set button attribs
button[i] = document.createElement('button');
button[i].setAttribute('class','dropbtn');
//create dropdown div, set attributes
dpdown2[i] = document.createElement('div');
dpdown2[i].setAttribute('class', 'dropdown-content');
//list of group names
stringy[i] = data2.Items[0].groupName.values[i];
var stringyy = stringy[i];
var desc;
//query group members and description
var docClient1 = new AWS.DynamoDB.DocumentClient({ region: AWS.config.region });
var identityId = AWS.config.credentials.identityId;
var paramsyy = {
ExpressionAttributeValues: {
":v1": stringyy
},
KeyConditionExpression: "groupName = :v1",
TableName: "group"
};
docClient1.query(paramsyy, function(err, data2) {
if (err) {
console.error(err);
}else{
descriptionArray[0] = data2.Items[0].description;
//traverse members
for(k = 0; k<data2.Items[0].members.values.length; k++){
// create dropdown links of members
membersArray[k] = data2.Items[0].members.values[k];
linksArray[k] = document.createElement('a');
linksArray[k].setAttribute('href', '#')
linksArray[k].innerText = membersArray[k];
// nest into dpdown2 div, set dpdown2 attribs
dpdown2[0].appendChild(linksArray[k]);
}
}
});
button[i].innerText = stringyy + ": " + descriptionArray[0];
// nest into dpdown1
dpdown1.appendChild(button[i]);
dpdown1.appendChild(dpdown2[i]);
}
// append to DOM
const target = document.getElementById('target');
target.appendChild(dpdown1);
if I use the I from the first for loop inside the query function, it will give me undefined results.
here's how you can do it with vanilla JavaScipt, there are multiple ways to do it, but this way only uses 4 methods: createElement, setAttribute, appendChild, and getElementById, and directly sets 1 property: innerText.
// create elements
const dpdown1 = document.createElement('div');
const button = document.createElement('button');
const dpdown2 = document.createElement('div');
const link1 = document.createElement('a');
const link2 = document.createElement('a');
const link3 = document.createElement('a');
// set link attribs
link1.setAttribute('href', '#')
link1.innerText = 'Link 1';
link2.setAttribute('href', '#')
link2.innerText = 'Link 2';
link3.setAttribute('href', '#')
link3.innerText = 'Link 3';
// nest into dpdown2, set dpdown2 attribs
dpdown2.appendChild(link1);
dpdown2.appendChild(link2);
dpdown2.appendChild(link3);
dpdown2.setAttribute('class', 'dropdown-content');
// set button attribs
button.setAttribute('class','dropbtn');
button.innerText = "Dropdown"
// nest into dpdown1
dpdown1.appendChild(button);
dpdown1.appendChild(dpdown2);
// set dpdown1 class
dpdown1.setAttribute('class', 'dropdown');
// append to DOM
const target = document.getElementById('target');
target.appendChild(dpdown1);
<div id="target"></div>
You will to append it to something, in this example it's <div id="target"></div> but it could be something else.
Happy coding!
Mainly you are just doing things out of order.
Create the .dropdown <div> with its class.
Complete the .dropbtn <button> with its class and text.
Add the button to the div.
Create the .dropdown-content <div>.
Complete each link with its href attribute and text.
Add each link to the .dropdown-content <div>.
Add the .dropdown-content div to the .dropdown <div>.
Find the parent element in the document.
Append the whole complete .dropdown <div> to the document.
var para = document.createElement("div"); //make .dropdown div
para.setAttribute('class', 'dropdown'); //add .dropdown class to div
var button = document.createElement("button"); //create button
button.setAttribute('class', 'dropbtn'); //add .dropbtn class to button
var node = document.createTextNode('Dropdown'); //create button text
button.appendChild(node); //add text to button
para.appendChild(button); //add button to .dropdown div
var div = document.createElement("div"); //create .dropdown-content div
div.setAttribute('class', 'dropdown-content'); //add .dropdown-content class to div
//repeat for all necessary links
var alinky = document.createElement("a"); //creat link
alinky.setAttribute('href', '#'); //set link href attribute
var alinkyText = document.createTextNode("Link 1"); //create text for link
alinky.appendChild(alinkyText); //add text to link
div.appendChild(alinky); //add link to dropdown div
para.appendChild(div); //add .dropdown-content div to .dropdown div
var element = document.getElementById("parental"); //find parent element
element.parentNode.insertBefore(para, element.nextSibling); //add .dropdown div to the bottom of the parent element
<div id="parental">
</div>

Anchor dynamic element with click event

I am trying to dynamically add an anchor element through Javascript. The problem I have is the onclick event is not firing. I believe the problem is how I am generating the HTML. I am creating an array and then push my HTML code to the array. After I have created my output I am joining the array and then adding it to the div tag I have.
var itemLink = new Object();
itemLink.LinkName = "Edit User";
itemLink.LinkListClass = "";
itemLink.LinkListRole = "";
itemLink.LinkFunction = function() {
//do something specific with rowItem variable
alert(rowItem);
}
var aTag = document.createElement("a");
aTag.setAttribute('class', 'btn btn-primary');
aTag.innerHTML = itemLink.LinkName;
aTag.setAttribute('href', '#');
var rowItem = 'abc1111'; //would be setting the rowId or some sort of identifier
aTag.onclick = itemLink.LinkFunction;
var output = [];
output.push('<table>');
output.push('<thead>');
output.push('<tr><th>col1</th><th>col2</th></tr>');
output.push('</thead>');
output.push('<tbody>');
output.push('<tr><td>col1 data</td><td>col2 data</td></tr>');
output.push('</tbody></table>')
var d1 = document.createElement('div');
d1.appendChild(aTag);
output.push(d1.innerHTML);
var mainView = document.getElementById('mainViewer');
mainView.innerHTML = output.join('');
<div id="mainViewer"></div>
When I generate the output without the use of the array and joining of the output, the anchor element gets created and the onclick event works just fine.
Any ideas?
I will have multiple anchor links and I don't want to hardcode the function name. I want the onclick event to fire whatever function the itemLink Object has set.
What's the problem? You bind a function to a temp DOM element, then append its html, not its events (that's how innerHTML works). So when a link appended to the DOM, it's a different DOM link, so although the link looks the same it's not.
So, what is the solution? to push a DOM element instead of string, something like this:
//var itemLink = new Object();
//itemLink.LinkName = "Edit User";
//itemLink.LinkListClass = "";
//itemLink.LinkListRole = "";
//itemLink.LinkFunction = function() {
//do something specific with rowItem variable
//alert(rowItem);
//}
var itemLink = {
LinkName: "Edit User",
LinkListClass: "",
LinkListRole: "",
LinkFunction: function() {
//do something specific with rowItem variable
alert(rowItem);
}
};
var aTag = document.createElement("a");
aTag.setAttribute('class', 'btn btn-primary');
aTag.innerHTML = itemLink.LinkName;
aTag.setAttribute('href', '#');
var rowItem = 'abc1111'; //would be setting the rowId or some sort of identifier
aTag.onclick = itemLink.LinkFunction;
var output = [];
output.push('<table>');
output.push('<thead>');
output.push('<tr><th>col1</th><th>col2</th></tr>');
output.push('</thead>');
output.push('<tbody>');
output.push('<tr><td>col1 data</td><td>col2 data</td></tr>');
output.push('</tbody></table>')
var mainView = document.getElementById('mainViewer');
mainView.innerHTML = output.join('');
var d1 = document.createElement('div');
d1.appendChild(aTag);
mainView.appendChild(d1)
<div id="mainViewer"></div>
Thanks to #David Thomas for his comment :)

href in a specific word of the String using JavaScript and HTML5

I'm trying to show the content of var fruits (array) in a HTML page using li, ul, a and href for a specific word (not all the text).
For example, for the sentence I want a link here I want the link only for the word here but I don't know how to do it...
Here is the code so far:
<script>
// selects the div with an id of placeholder
var div = document.getElementById('placeholder');
// say that fruits contains all your data
var fruits = ['I want a link here','I want a link here','I want a link here','I want a link here','I want a link here'],
ul = document.createElement('ul'); // create an arbitrary ul element
// loop through the fruits array
for(var i in fruits) {
// create an arbitrary li element
var li = document.createElement('li'),
content = document.createTextNode(fruits[i]); // create a textnode to the document
var link = "http://google.com";
var element = document.createElement("a");
element.setAttribute("href", link);
element.innerHTML = fruits[i];
li.appendChild(element); // append the created textnode above to the li element
ul.appendChild(li); // append the created li element above to the ul element
}
div.appendChild(ul); // finally the ul element to the div with an id of placeholder
</script>
FIDDLE
One possible solution
var div = document.getElementById('placeholder');
// say that fruits contains all your data
var fruits = ['I want a link here','I want a link here','I want a link here','I want a link here','I want a link here'],
ul = document.createElement('ul'); // create an arbitrary ul element
// loop through the fruits array
for(var i in fruits) {
// create an arbitrary li element
var li = document.createElement('li'),
content = document.createTextNode(fruits[i]); // create a textnode to the document
var link = "http://google.com";
var element = document.createElement("span");
element.innerHTML = fruits[i];
li.appendChild(element); // append the created textnode above to the li element
ul.appendChild(li); // append the created li element above to the ul element
}
div.appendChild(ul); // finally the ul element to the div with an id of placeholder
Fiddle
If you don't want to change your original data array you could use.
for(var i in fruits) {
// create an arbitrary li element
var li = document.createElement('li');
var link = "http://google.com";
var content = fruits[i].replace('here', 'here');
var element = document.createElement("span");
element.innerHTML = content;
li.appendChild(element); // append the created textnode above to the li element
ul.appendChild(li); // append the created li element above to the ul element
}
Fiddle
This works in the fiddle you provided.
// selects the div with an id of placeholder
var div = document.getElementById('placeholder');
// say that fruits contains all your data
var fruits = ['I want a link here', 'I want a link here', 'I want a link here', 'I want a link here', 'I want a link here'],
ul = document.createElement('ul'); // create an arbitrary ul element
// loop through the fruits array
for (var i in fruits) {
// split words from sentence
var fruitWords = fruits[i].split(' ');
// select the word you want linked ( I selected 'here')
var linkWord = fruitWords[fruitWords.length-1];
// reconstruct sentence removing the linked word
fruitWords.pop();
fruits[i] = fruitWords.join(' ');
// create an arbitrary li element
var li = document.createElement('li'),
content = document.createTextNode(fruits[i]); // create a textnode to the document
var link = "http://google.com";
var element = document.createElement("a");
element.setAttribute("href", link);
element.innerHTML = linkWord;
li.innerHTML = fruits[i] + ' ';
li.appendChild(element); // append the created textnode above to the li element
ul.appendChild(li); // append the created li element above to the ul element
}
div.appendChild(ul); // finally the ul element to the div with an id of placeholder

How to access a ordered list's anchor tag and change the "href" in JavaScript

How do I change the HREF for an anchor tag that is inside an ordered list? More specifically, how do I change the HREF of the anchor tag in my specific case where the list is appended to the body?
Here is what I have tried so far:
var image = document.createElement("img");
image.src = "http://archiveteam.org/images/1/15/Apple-logo.jpg"
image.className = "image";
var aboutMe = document.createElement("p");
aboutMe.innerHTML = "Hello";
aboutMe.className = "Border";
var movies = ["Inception", "Remember the Titans", "Happy Gilmore", "Interstellar", "The Martian"]
var listOfMovies = document.createElement("ol");
for (var i = 0; i < 5; i++) {
var anchor = document.createElement("a");
anchor.href = "#";
anchor.innerHTML = movies[i];
var bullets = document.createElement("li");
bullets.appendChild(anchor);
listOfMovies.appendChild(bullets);
}
listOfMovies.getElementsByTagName("li")[0].href = 'http://www.imdb.com/title/tt1375666/';
listOfMovies.getElementsByTagName("li")[1].href = 'http://www.imdb.com/title/tt0210945/';
listOfMovies.getElementsByTagName("li")[2].href = 'http://www.imdb.com/title/tt0116483/';
listOfMovies.getElementsByTagName("li")[3].href = 'http://www.imdb.com/title/tt0816692/';
listOfMovies.getElementsByTagName("li")[4].href = 'http://www.imdb.com/title/tt3659388/';
document.body.appendChild(image);
document.body.appendChild(aboutMe);
document.body.appendChild(listOfMovies)
listOfMovies.className = "Border"
You are setting the li element's href attribute instead of the a (anchor) element. So your first line of code to change the href should be:
listOfMovies.getElementsByTagName("a")[0].href = 'http://www.imdb.com/title/tt1375666/';
You could also iterate through this list to have simpler code by adding the href's to an array in the same order as movies or even creating a movies object with Movie title and url like:
movies = [{ title: "Inception", url: "http://www.imdb.com/title/tt1375666/" },{...}...];

Categories