I want to select all elements using querySelectorAll with variable "amountClass" but NodeList always is empty
function addingCoin() {
const table = document.querySelector('.list__table');
table.addEventListener('submit', (event) => {
event.preventDefault();
const walletCryptos = document.querySelector('#usersCrypto');
const coinAmount = event.target.inputAmount;
const coinRow = coinAmount.parentElement.parentElement.parentElement;
const coinName = coinRow.querySelector('.name').textContent;
const coinPrice = coinRow.querySelector('.price').textContent.match(/\d+(\.\d+)?/)[0];
const coinValue = coinAmount.value*coinRow.querySelector('.price').textContent.match(/\d+(\.\d+)?/)[0];
let amountClass = coinName;
let existingCoin = document.querySelectorAll(amountClass);
if (existingCoin.length > 0) {
existingCoin[0].innerText = coinAmount.value +
existingCoin[0].value;
} else {
const newTr = document.createElement("tr");
const nameTh = document.createElement("th");
const priceTh = document.createElement("th");
const amountTh = document.createElement("th");
const valueTh = document.createElement("th");
nameTh.innerText = coinName;
if (coinPrice < 0.95) {
priceTh.innerText = parseFloat(coinPrice).toFixed(8);
} else {
priceTh.innerText = parseFloat(coinPrice).toFixed(2);
};
amountTh.innerText = coinAmount.value;
amountTh.className += coinName;
if (coinValue < 0.95) {
valueTh.innerText = parseFloat(coinValue).toFixed(8);
} else {
valueTh.innerText = parseFloat(coinValue).toFixed(2);
};
walletCryptos.appendChild(newTr);
walletCryptos.appendChild(nameTh);
walletCryptos.appendChild(priceTh);
walletCryptos.appendChild(amountTh);
walletCryptos.appendChild(valueTh);
}});
};
I think the problem may be with this part of code:
let existingCoin = document.querySelectorAll(amountClass);
What can i change to make this work properly? Is there any other solution to check does the element with the certain class exist?
You need a . at the beginning to select a class.
Trim the text content in case it has whitespace around the text.
const coinName = coinRow.querySelector('.name').textContent.trim();
let amountClass = '.' + coinName
Finally I have found the solution:
const amountClass = '.' + coinName;
const existingCoin = document.querySelectorAll(amountClass.replace(/ /g,''));
Related
I'm new to JS so I have been writing code the most simple way possible for me just to get the functionality that I want the plan being clean it up and shorten everything later.
Part of doing this I have loads of classes to select a series of elements by their id. Is it possible to put these in an array? all the elements are numbered 1-12
Essentially I have three items to get a slide its accompanying audio and subtitle
const slide0 = document.getElementById("slide0");
const slide1 = document.getElementById("slide1");
const slide2 = document.getElementById("slide2");
const slide3 = document.getElementById("slide3");
const slide4 = document.getElementById("slide4");
const slide5 = document.getElementById("slide5");
const slide6 = document.getElementById("slide6");
const slide7 = document.getElementById("slide7");
const slide8 = document.getElementById("slide8");
const slide9 = document.getElementById("slide9");
const slide10 = document.getElementById("slide10");
const slide11 = document.getElementById("slide11");
const slide12 = document.getElementById("slide12");
const subt1 = document.getElementById("sub1");
const subt2 = document.getElementById("sub2");
const subt3 = document.getElementById("sub3");
const subt4 = document.getElementById("sub4");
const subt5 = document.getElementById("sub5");
const subt6 = document.getElementById("sub6");
const subt7 = document.getElementById("sub7");
const subt8 = document.getElementById("sub8");
const subt9 = document.getElementById("sub9");
const subt10 = document.getElementById("sub10");
const subt11 = document.getElementById("sub11");
const subt12 = document.getElementById("sub12");
const chp1 = document.getElementById("audiochp1");
const chp2 = document.getElementById("audiochp2");
const chp3 = document.getElementById("audiochp3");
const chp4 = document.getElementById("audiochp4");
const chp5 = document.getElementById("audiochp5");
const chp6 = document.getElementById("audiochp6");
const chp7 = document.getElementById("audiochp7");
const chp8 = document.getElementById("audiochp8");
const chp9 = document.getElementById("audiochp9");
const chp10 = document.getElementById("audiochp10");
const chp11 = document.getElementById("audiochp11");
const chp12 = document.getElementById("audiochp12");
Yes, you can. For example:
let slides = [];
for (let i = 0; i < num_slides; i++) {
slides.push({
slide: document.getElementById(`slide${i}`),
subt: document.getElementById(`sub${i}`),
chp: document.getElementById(`audiochp${i}`)
});
}
You could, however, also do something similar by giving your elements classes and then using document.getElementsByClassName('slide') and so on.
Surely! I highly advise you to generate a few helper functions for this. Take a look at the following example:
function getSlides(theMaxSlideNumer) {
const returnElements = [];
for (int i = 0; i <= theMaxSlideNumber; i++) {
const aSlideQuery = "#slide" + i.toString();
returnElements.push(document.querySelector(aSlideQuery));
}
return returnElements;
}
const slides = getSlides(12);
Add safeguard
function getSlides(theMaxSlideNumer) {
const returnElements = [];
for (int i = 0; i <= theMaxSlideNumber; i++) {
const aSlideQuery = "slide" + i.toString();
returnElements.push(document.querySelector(aSlideQuery));
}
returnElements.forEach((aElement)=>{
if (aElement === null) console.warn("A dom element could not be found, trace this message!");
});
return returnElements;
}
const slides = getSlides(12);
Target them using querySelectorAll and spread them into an array.
[...document.querySelectorAll('[id^=slide]')] // CSS selector that captures all elements starting with slide word
Repeat for each group you have.
Fiddle: https://jsfiddle.net/dk9f86rp/19/
How I can display localStorage information on my webpage?
I am easily setItem() to localStorage and when I console.log() it is showing but I cannot display it on the page(after reloading it is gone) I wanna keep this data on my page even when I am closing the tab
Thank you in advance
const title = document.querySelector("#title");
const author = document.querySelector("#author");
const rating = document.querySelector("#rating");
const category = document.querySelector("#category");
const bookList = document.querySelector("#book-list");
document.querySelector("#book-form").addEventListener("submit", (e) => {
e.preventDefault();
});
document.querySelector("#submit-btn").addEventListener("click", function () {
if (
title.value === "" ||
author.value === "" ||
rating.value === "" ||
category.value === ""
) {
alert("Please fill the form");
} else {
// Creating tr th and appending to list
const bookListRow = document.createElement("tr");
const newTitle = document.createElement("th");
newTitle.innerHTML = title.value;
bookListRow.appendChild(newTitle);
const newAuthor = document.createElement("th");
newAuthor.innerHTML = author.value;
bookListRow.appendChild(newAuthor);
const newRating = document.createElement("th");
newRating.innerHTML = rating.value;
bookListRow.appendChild(newRating);
const newCategory = document.createElement("th");
newCategory.innerHTML = category.value;
bookListRow.appendChild(newCategory);
const deleteBtn = document.createElement("th");
deleteBtn.classList.add("delete");
deleteBtn.innerHTML = "X";
bookListRow.appendChild(deleteBtn);
bookList.appendChild(bookListRow);
//Storage
let storageTitle = title.value;
let storageAuthor = author.value;
let storageRating = rating.value;
let storageCategory = category.value;
localStorage.setItem("title", JSON.stringify(storageTitle));
localStorage.setItem("author", JSON.stringify(storageAuthor));
localStorage.setItem("rating", JSON.stringify(storageRating));
localStorage.setItem("category", JSON.stringify(storageCategory));
for (var i = 0; i < localStorage.length; i++) {
newTitle += localStorage.getItem(localStorage.key(i));
}
// Clear
title.value = "";
author.value = "";
rating.value = "";
category.value = "";
}
});
// Remove each books by clicking X button
bookList.addEventListener("click", (e) => {
e.target.parentElement.remove();
}); ```
the question of your code may is that you just save the data to the localStoarge, but at the initial of the page ,you did't get the data from the localStorage, you should get data like this:
window.onload = function (){
let storageTitle = JSON.parse(localStorage.getItem("title"));
document.querySelector("#title").innerHtml = storageTitle;
}
this code should be working can you specify the problem a little further!
You are setting it correctly but not reading it as you should. Local storage persists data even if you close the tab, so it is just your code that is causing you trouble.
You can find an explanation how you should work with local and session storage here.
https://stackoverflow.com/a/65655155/2563841
i'm making an app with marvel's api and in this app i'm trying to put a search bar but i'm not getting it.
Every time I try to search for a name in this api the function Search() it is undefined in the html.
I don't understand how the function is not defined in the html.
What can i do to change this ?
const timeStamp = "1622146184";
const privateKey = "somekey";
const publicKey = "someotherkey";
const md5 = "b34f17bceca201652c24e9aa21777da9";
const Hero = document.querySelector('article');
const input = document.getElementById('myInput');
fetch(`http://gateway.marvel.com/v1/public/characters?ts=${timeStamp}&apikey=${publicKey}&hash=${md5}&limit=6`).then((response)=> {
return response.json();
}).then((jsonParsed)=>{
jsonParsed.data.results.forEach(element => {
const srcImage = element.thumbnail.path + '.' + element.thumbnail.extension;
const nameHero = element.name;
createHero(srcImage, nameHero, Hero);
},
function Search() {
// Declare variables
const filter = input.value.toUpperCase();
const textName2 = nameHero;
// Loop through all textName2st items, and hide those who don't match the search query
for (i = 0; i <= textName2.length; i++) {
const p = textName2[i].getElementsByTagName("p")[0];
txtValue = p.textContent || p.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
textName2[i].style.display = "";
} else {
textName2[i].style.display = "none";
}
}
})
console.log(jsonParsed);
})
function createHero(srcImage, nameHero, divToAppend){
const divPai = document.createElement('section');
const textName = document.createElement('p');
const img = document.createElement('img');
textName.textContent = nameHero;
img.src= srcImage;
divPai.appendChild(img);
divPai.appendChild(textName);
divToAppend.appendChild(divPai);
divPai.classList.add("personagem");
}
<main>
<input type="text" id="myInput" onkeyup="Search()" placeholder="Search for names.." />
<article id="herois"></article>
</main>
The search function is undefined because the fetch isn't closed properly. I'm also guessing that you only want to make a request when the user has actually entered some search query. I don't see multiple article elements so don't really know what to do with this. But do note that in this case you might as well use getElementById. And if there are multiple articles with the same id that it won't work.
const timeStamp = "1622146184";
const privateKey = "somekey";
const publicKey = "someotherkey";
const md5 = "b34f17bceca201652c24e9aa21777da9";
const Hero = document.getElementById('herois');
const input = document.getElementById('myInput');
async function Search() {
console.log(input.value);
await fetch(`http://gateway.marvel.com/v1/public/characters?ts=${timeStamp}&apikey=${publicKey}&hash=${md5}&limit=6`)
.then( response => {
return response.json();
})
.then(jsonParsed => {
console.log(jsonParsed);
jsonParsed.data.results.forEach(element => {
const srcImage = element.thumbnail.path + '.' + element.thumbnail.extension;
const nameHero = element.name;
createHero(srcImage, nameHero, Hero);
});
});
// Declare variables
const filter = input.value.toUpperCase();
const textName2 = nameHero;
// Loop through all textName2st items, and hide those who don't match the search query
for (i = 0; i <= textName2.length; i++) {
const p = textName2[i].getElementsByTagName("p")[0];
txtValue = p.textContent || p.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
textName2[i].style.display = "";
} else {
textName2[i].style.display = "none";
}
}
}
function createHero(srcImage, nameHero, divToAppend){
const divPai = document.createElement('section');
const textName = document.createElement('p');
const img = document.createElement('img');
textName.textContent = nameHero;
img.src= srcImage;
divPai.appendChild(img);
divPai.appendChild(textName);
divToAppend.appendChild(divPai);
divPai.classList.add("personagem");
}
<main>
<input type="text" id="myInput" onchange="Search()" placeholder="Search for names.." />
<article id="herois"></article>
</main>
I'm very new to javascript/dev so I hope there is a an obvious solution that I've not thought of. My code returns search items from TVMaze.com API. The feature giving me trouble is the incremental search (as a user types in input box, the code returns and displays images by creating a new div and appending images, removing and replacing the an div).
My problem is that on deleting all characters from input box, I receive the error: "Uncaught (in promise) TypeError: shows is not iterable" which I suppose means that there is no object to iterate over? Thanks in advance for any help.
const input = document.querySelector("#query");
input.addEventListener("input", async function (e) {
e.preventDefault();
const searchTerm = e.target.value;
const config = { params: { q: searchTerm } };
const res = await axios.get(`http://api.tvmaze.com/search/shows?`, config);
makeImages(res.data);
clearList();
});
const makeImages = (shows) => {
const div = document.createElement("div");
for (let result of shows) {
if (result.show.image) {
const img = document.createElement("IMG");
img.className += "resultImage";
img.src = result.show.image.medium;
const title = document.createElement("h3");
title.className += "resultTitle";
title.innerText = result.show.name;
const year = document.createElement("h4");
year.className += "score";
year.innerText = result.show.premiered;
var sub = year.innerText.substring(0, 4);
var yearNum = parseInt(sub);
div.append(year);
div.append(img);
div.append(title);
document.body.appendChild(div);
}
if (yearNum <= 2000) {
var retro = document.createElement("h5");
retro.className = "retro";
retro.innerText = "retro";
div.append(retro);
}
}
};
let clearList = () => {
var allImg = document.querySelectorAll("IMG");
if (allImg.length === 0) {
document.createElement("div");
return makeImages();
}
var oldDiv = document.querySelector("div");
oldDiv.remove();
console.log(oldDiv);
};
I'm solving this problem, I want to add and remove items to the HTML table using javascript. So far I've got this, but I don't really know how to make the removing part possible. Could you give me a hand please?
let inputJmeno = document.querySelector('#inputJmeno');
let inputPrijmeni = document.querySelector('#inputPrijmeni');
let inputVek = document.querySelector('#inputVek');
let buttonAdd = document.querySelector('#add');
let table = document.querySelector('table');
let tbody = document.querySelector('tbody');
let tr = document.querySelector('tr');
let jmeno = null;
let prijmeni = null;
let vek = null;
let pocetOsob = 0;
buttonAdd.addEventListener('click', add);
function add() {
jmeno = inputJmeno.value;
prijmeni = inputPrijmeni.value;
vek = inputVek.value;
let newRow = document.createElement('tr');
let newJmeno = document.createElement('td');
let newPrijmeni = document.createElement('td');
let newVek = document.createElement('td');
let krizek = document.createElement('span');
krizek.id = "krizek" + pocetOsob;
krizek.className = "krizClass";
newRow.id = "row" + pocetOsob;
newJmeno.innerHTML = jmeno;
newPrijmeni.innerHTML = prijmeni;
newVek.innerHTML = vek;
krizek.innerHTML = 'x';
tbody.appendChild(newRow);
newRow.appendChild(newJmeno);
newRow.appendChild(newPrijmeni);
newRow.appendChild(newVek);
newRow.appendChild(krizek);
load(pocetOsob);
pocetOsob++;
}
function load(p) {
let krz = document.querySelector('#krizek'+p);
console.log(p);
}
try
newRow.removeChild(krizek);