In the function below, I create cards that have a toggle button and remove button. However, when I try to access the buttons with a queryselector, I get null. Anyone know how to access elements that were created in a different file? I can provide the full files if needed.
function updateDisplay() {
for (i = 0; i < myLibrary.length; i++){
let div = document.createElement('div');
let title = document.createElement('h5');
let author = document.createElement('h5');
let pages = document.createElement('h5');
let isRead = document.createElement('h5');
let removeButton = document.createElement('button');
let toggleButton = document.createElement('button');
div.classList.add('card');
title.classList.add('title');
author.classList.add('author');
pages.classList.add('pages');
isRead.classList.add('isRead');
removeButton.classList.add('removeButton');
toggleButton.classList.add('toggleButton');
title.textContent = myLibrary[i].title;
author.textContent = myLibrary[i].author;
pages.textContent = `${myLibrary[i].pages} pages`;
isRead.textContent = myLibrary[i].isRead ? 'Read' : 'Unread';
removeButton.textContent = 'Remove';
toggleButton.textContent = 'Toggle Read Status';
Your problem is obvious you're creating the elements but not appending the into the body.
you'll have to append each element you create like the following example:
var element= document.createElement("div"); // Create a <div> element
element.innerHTML = "some content"; // Insert text
document.body.appendChild(element); // Append <div> to <body>
note that you can do document.body.append(div,title,author,pages,isRead,removeButton,toggleButton);
to append them all in one line
Related
I am trying to add a check box when button is pressed and also delete the same checkbox when the delete is pressed. Unfortunatly the delete function cannot run as it seems that the newly created div doesn't exist yet. How can I get around this?
<script>
const list = document.getElementById("list");
const cli_form = document.getElementById("client-form");
let idz = 0;
function add_client(input) {
const div = document.createElement("div");
div.setAttribute("id", idz.toString())
const newCheckbox = document.createElement("input");
newCheckbox.setAttribute("type", 'checkbox');
newCheckbox.setAttribute("id", 'checkbox');
const newLabel = document.createElement("label");
newLabel.setAttribute("for", 'checkbox');
newLabel.innerHTML = input.value;
const br = document.createElement("br");
const del = document.createElement("input");
del.setAttribute("type", 'button');
del.setAttribute("value", idz.toString());
del.onclick = delete_item(document.getElementById(idz.toString()));
div.appendChild(newCheckbox);
div.appendChild(newLabel);
div.appendChild(del);
div.appendChild(br);
list.appendChild(div);
idz++;
}
function delete_item(item1) {
item1.remove();
}
</script>
You are assigning the result of the function delete_item which invoke immediately. Therefore, it is removing the item before it is being added to DOM.
You might use an arrow wrapper to avoid immediate invocation.
Like this :
del.onclick = () => delete_item(document.getElementById(idz.toString()));
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>
I'm working on a simple blackjack game, where the dealer will be served one card and the player two (basic rules).
The cards display just fine, but when I append a class to the dealers card container, the container refuses to acknowledge the class I just appended. I copy and pasted the same code from my player function which deals the player cards successfully and that doesn't seem to work on my dealer function either.
The class I am trying to append is "symbol".
If you take a look at the jsfiddle snippet below, you can inspect it to see the class "symbol" doesn't get appended to dealer, but works completely fine in the player function.
Thank you in advance for the help.
http://jsfiddle.net/vorqdkb7/1/
Dealer
function deal_dealer_cards(){
let dealerContainer = document.querySelector('.dealer_container');
let card = deck.pop();
dealerHand.push(card);
let dealerCard = document.createElement('div');
dealerCard.className = "dealer_card";
dealerContainer.append(dealerCard);
let rank = document.createElement('div');
rank.className = "rank";
dealerCard.append(rank);
rank.innerHTML = card.value;
let symbol = document.createElement('div');
dealerCard.append(symbol);
symbol.className = 'symbol';
let cardSymbol = document.createElement('span');
symbol.append(cardSymbol);
cardSymbol.setAttribute('id', 'card_symbol');
let i = document.createElement('i');
cardSymbol.append(i);
let fa = "fas ";
Player
function deal_player_cards(){
let playerContainer = document.querySelector('.player_container');
let fa = "fas ";
for (let i = 0; i < 2; i++){
let card = deck.pop();
playerHand.push(card);
let playerCard = document.createElement('div');
playerCard.className = "player_card";
playerContainer.append(playerCard);
let rank = document.createElement('div');
rank.className = "rank";
playerCard.append(rank);
rank.innerHTML = card.value;
let symbol = document.createElement('div');
playerCard.append(symbol);
symbol.className = 'symbol';
let cardSymbol = document.createElement('span');
symbol.append(cardSymbol);
cardSymbol.setAttribute('id', 'card_symbol');
let i = document.createElement('i');
cardSymbol.append(i);
let fa = "fas "; }
Ok the div .symbol does get appended but down below in your code you update the className.
With this code
symbol.className = fa + "fa-heart";
Now I don't know exactly what you would need here. But if you want to append the symbol class maybe you want to do something like
symbol.className += " " + fa + "fa-heart";
I hope it helps
you can use symbol.classList.add('fa-heart') to add class to the element because you did is to override the whole className attribute with the new one.
and you can use symbol.classList.remove('fa-heart') to remove a specific class too.
Hope this helps you.
So, I am accessing a to-do list api to make a very basic to-do list app. I am able to display what I call from the api, I have the title, description, and price appended to an h1, h3, and h4 respectively and it then gets displayed to the document when the user fills out a form.
How can I append those three into a div, so that I can apply CSS to each individual to-do or so that i can add a button for when I want to delete or edit the todo?
And I want to do this in plain vanilla JavaScript, if possible.
Here is my JavaScript code and also if there is anything you see in the existing code that you feel can be improved or changed or if there is anything I am doing completely wrong, please tell me. I am still very much a beginner at this, so I can use all the help I can get.
function Todo(title, description, price){
this.title = title;
this.description = description;
this.price = price;
}
document.todo.addEventListener("submit", function(e){
e.preventDefault();
var titleForm = document.todo.title.value;
var descriptionForm = document.todo.description.value;
var priceForm = document.todo.price.value;
var newTodo = new Todo(titleForm, descriptionForm, priceForm);
axios.post("<todo api url>", newTodo).then(function(response){
console.log(response.data);
})
})
axios.get("<todo api url>").then(function(response){
for(var i = 0; i < response.data.length; i++){
var h1 = document.createElement("h1");
var h3 = document.createElement("h3");
var h4 = document.createElement("h4");
var displaytitle = document.createTextNode(response.data[i].title);
var displayDescription = document.createTextNode(response.data[i].description);
var displayPrice = document.createTextNode(response.data[i].price);
h1.appendChild(displaytitle);
h3.appendChild(displayDescription);
h4.appendChild(displayPrice);
document.body.appendChild(h1);
document.body.appendChild(h3);
document.body.appendChild(h4);
}
})
Instead of appending them to document.body, create a DIV and append them to the DIV, then append the DIV to the body.
axios.get("<todo api url>").then(function(response){
for(var i = 0; i < response.data.length; i++){
var h1 = document.createElement("h1");
var h3 = document.createElement("h3");
var h4 = document.createElement("h4");
var div = document.createElement("div");
var displaytitle = document.createTextNode(response.data[i].title);
var displayDescription = document.createTextNode(response.data[i].description);
var displayPrice = document.createTextNode(response.data[i].price);
h1.appendChild(displaytitle);
h3.appendChild(displayDescription);
h4.appendChild(displayPrice);
div.appendChild(h1);
div.appendChild(h3);
div.appendChild(h4);
document.body.appendChild(div);
}
});
If you want to style them with CSS, you probably should give them distinct classes, or give a class to the DIV, e.g.
div.classList.add("todoItem");
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/" },{...}...];