How Can I append my array of objects in an HTML file? - javascript

I get two values as name and number from input and make an object by a constructor , then I push it to an array.
I want to append those values to my HTML file by each click from user
and also use map to show only names.
How can I do that?
please help me , this is my code < br/>
const name = document.getElementById("name");
const number = document.getElementById('number');
const container = document.getElementById("container");
const sendBtn = document.getElementById("send-btn");
const contacts = [];
function ContactMaker (name, number) {
this.name = name;
this.number = number;
}
sendBtn.addEventListener('click', () => {
const newContact = new ContactMaker(name.value, number.value);
contacts.push(newContact);
name.value ='';
number.value = '';
})

You can map through the contacts and add them to the DOM:
const name = document.getElementById("name");
const number = document.getElementById('number');
const container = document.getElementById("container");
const sendBtn = document.getElementById("send-btn");
const contacts = [];
function ContactMaker(name, number) {
this.name = name;
this.number = number;
}
const addToDOM = () => {
const contactList = contacts.map(({
name
}) => `<li>${name}</li>`).join('');
container.innerHTML = `<ul>${contactList}</ul>`;
}
sendBtn.addEventListener('click', () => {
const newContact = new ContactMaker(name.value, number.value);
contacts.push(newContact);
name.value = '';
number.value = '';
addToDOM();
})
<input id="name" type="text" />
<input id="number" type="text" />
<button id="send-btn">Send</button>
<div id="container"></div>

Related

Having trouble reducing the total in this small todo app

I am having a hard time trying to figure out how to get the the value from every new Li and reduce it (add) to then output to my h2. Can't figure out what I am doing wrong. Any help would be greatly appreciated! Codepen: https://codepen.io/Chasehud26/pen/Poagjwy
I tried to console.log different variables to see if there were any hints of what is going wrong.
const form = document.querySelector("form")
const nameInput = document.querySelector("#name-input")
const priceInput = document.querySelector("#price-input")
const button = document.querySelector("button")
const nameUl = document.querySelector("#item-name")
const priceUl = document.querySelector("#item-price")
const h2 = document.querySelector("h2")
const nameLi = document.createElement("li")
const priceLi = document.createElement("li")
form.addEventListener("submit", function (e) {
e.preventDefault()
let nameVal = nameInput.value
let priceVal = priceInput.value
const nameLi = document.createElement("li")
const priceLi = document.createElement("li")
nameUl.appendChild(nameLi)
nameLi.innerHTML = nameInput.value
priceUl.appendChild(priceLi)
priceLi.textContent = `${priceInput.value}`
showTotals()
})
//TRYING TO ADD TOGETHER ALL THE PRICE VALUES AND THEN PUT IT TO MY H2//
function showTotals() {
const priceList = document.querySelectorAll("li")
for (let priceLists of priceList) {
const total = []
total.push(parseFloat(priceLists.textContent));
const totalMoney = total.reduce(function (total, item) {
total += item;
return total;
}, 0);
const finalMoney = totalMoney.toFixed(2);
h2.textContent = finalMoney;
}
}
You need to have your const total [] array initialized outside of the for loop. also, when you setup your <li> decorators, you need to differentiate between the number and non-number fields, since the way you had it, it was trying to add the text 'li' fields also:
/// truncated for clarity
const nameLi = document.createElement("li")
const priceLi = document.createElement("li")
priceLi.classList.add('num') // <== this line added
//// =================
function showTotals() {
const priceList = document.querySelectorAll("li.num") // added class
const total = [] // <== move this to here
for (let priceLists of priceList) {
total.push(parseFloat(priceLists.textContent));
const totalMoney = total.reduce(function (total, item) {
total += item;
return total;
}, 0);
const finalMoney = totalMoney.toFixed(2);
h2.textContent = finalMoney;
}

How to arrange the output in alphabetical order in javascript?

I need help as soon as possible.
I try have tried various way on how to arrange the output in alphabetical order but none of them seems work.
The question is asked to arrange the output in alphabetical order without changing the base code.
The base code:
function add() {
var name = document.getElementById("id-name").value;
var address = document.getElementById("id-address").value;
var content = document.getElementById("id-content").innerHTML;
document.getElementById("id-content").innerHTML = content + name + "<br/>" + address + "<hr/>";
}
Name: <input type="text" id="id-name" name="name"><br /> Address: <textarea id="id-address" name="address"></textarea><br />
<button id="id-send" onclick="javascript: add();">Send</button>
<hr>
<div id="id-content"></div>
This is the example of the output that it should display:
You could create an array and sort it
I wrapped in a form to have simpler event handling. Also no need for javascript: label on an inline event handler
const list = []; // you can get this from localStorage if you want to save across reloads
window.addEventListener("DOMContentLoaded", () => {
const content = document.getElementById("id-content"),
nameField = document.getElementById("id-name"),
addressField = document.getElementById("id-address");
const show = () => {
list.sort((a, b) => a.name.localeCompare(b.name))
content.innerHTML = list.map(({ name, address }) => `${name}<br/>${address}`).join("<hr/>");
};
document.getElementById("myForm").addEventListener("submit", e => {
e.preventDefault();
const name = nameField.value;
const address = addressField.value;
list.push({ name, address });
show();
});
});
<form id="myForm">
Name: <input type="text" id="id-name" name="name"><br /> Address: <textarea id="id-address" name="address"></textarea><br />
<button id="id-send">Send</button>
</form>
<hr>
<div id="id-content"></div>
You could keep an array of submitted data and sort the array alpabetically. This solution should work:
let listOfData = [];
function add() {
var name = document.getElementById("id-name").value;
var address = document.getElementById("id-address").value;
var content = document.getElementById("id-content").innerHTML;
listOfData.push({
personName: name,
personAddress: address
});
document.getElementById("id-content").innerHTML = "";
listOfData.sort((a, b) => a.personName.localeCompare(b.personName));
for (let person of listOfData) {
document.getElementById(
"id-content"
).innerHTML += `${person.personName} <br/> ${person.personAddress}<br/> <hr/>`;
}
}
Use this code it will work
function add() {
var name = document.getElementById("id-name").value;
var address = document.getElementById("id-address").value;
let data = document.getElementById("id-content");
let content = data.innerHTML;
content = content + name + "<br/>" + address + "<hr>";
let dt = "";
let sortArr = content.split("<hr>").sort().join().split(",");
for (let i = 1; i < sortArr.length; i++) {
dt += sortArr[i] + "<hr>";
}
data.innerHTML = dt;
}

Conditional statement limiting the number of displayed elements

I'm having trouble implementing the logic that will limit me from adding the same items to my shopping list. When the item is the same, I just want to display the quantity with the existing item.
<div class="pizzas">
</div>
<div class="shoppingCart">
<p class="totalPrice">Hungry? order our pizzas</p>
</div>
// js
fetch("https://raw.githubusercontent.com/alexsimkovich/patronage/main/api/data.json")
.then(data => data.json())
.then(data => {
let valueCurrency = 0;
data.forEach(element => {
const shoppingCart = document.querySelector(".shoppingCart");
const pizzas = document.querySelector(".pizzas");
const box = document.createElement("div");
const img = document.createElement("img");
const title = document.createElement("h3");
const ingredients = document.createElement("p");
const price = document.createElement("h4");
const btn = document.createElement("button");
const totalPrice = document.querySelector(".totalPrice");
box.className = "box";
ingredients.className = "ingredients"
btn.className = "btn";
img.src = element.image;
img.className = "img";
title.innerHTML = element.title;
ingredients.innerHTML = element.ingredients;
price.innerHTML = element.price.toFixed(2) + " zł";
btn.innerHTML = "Dodaj do koszyka";
box.appendChild(img);
box.appendChild(title);
box.appendChild(ingredients);
box.appendChild(price);
box.appendChild(btn);
pizzas.appendChild(box);
btn.addEventListener("click", (e) => {
valueCurrency = valueCurrency + element.price;
const pizza = document.createElement("div");
pizza.className = "pizzaList";
const pizzasList = document.createElement("li");
const pizzaPrice = document.createElement("p");
const btnRemove = document.createElement("button");
btnRemove.innerText = "X";
pizzasList.innerText = title.textContent;
pizzaPrice.innerText = price.textContent;
pizza.appendChild(pizzasList);
pizza.appendChild(pizzaPrice);
pizza.appendChild(btnRemove);
totalPrice.innerText = "Całkowita cena: " + valueCurrency.toFixed(2);
if(pizzasList.innerText === pizzasList.innerText)
{
// don't add another item to the list
// just add +1 to existing element
}
else
{
// add an item to the list
shoppingCart.prepend(pizza);
}
btnRemove.addEventListener("click", (e) => {
pizza.remove();
valueCurrency = valueCurrency - element.price;
totalPrice.innerText = "Całkowita cena: " + valueCurrency.toFixed(2);
})
})
});
})
.catch(err => console.log(err));
My problem is exactly in the conditional statement, I don't know exactly how to implement the counting of the same pizzas option.
Thank you in advance for your help.
Since you are using html elements for this, what you can do is to use a data-attribute in your pizza element and increment it each time you need.
Something like:
if(pizzasList === pizzasList)
{
pizza.dataset.total = Number(pizza.dataset.total) + 1;
}
else
{
pizza.dataset.total = 1;
shoppingCart.prepend(pizza);
}
Then just use pizza.dataset.total to retieve the total number of repetitions.

(index):19 Uncaught ReferenceError: Search is not defined at HTMLInputElement.onkeyup

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>

needing help fixing unordered list not displaying through Dom

The logic seems sound but my ul is not displaying what I am asking it to. I have used console.logs and I am for sure getting poem in the function displayPoem(poem) but it isn't showing up when I button click. Any help would be greatly appreciated!
const inputsList = document.querySelector('ol');
const poemsList = document.getElementById('savedThoughts');
const form = document.getElementById('')
const submitButton = document.getElementById('submitThoughts');
const startButton = document.querySelector('#startButton')
startButton.onclick = () => {
const ranNum = generateRanNum();
generateInputs(ranNum)
changeToRestartText()
}
submitButton.onclick = () => {
const poem = savePoem();
console.log(poem)
displayPoem(poem);
clearForm()
}
const generateRanNum = () => {
let randomNumber = Math.floor(Math.random() * 20);
return randomNumber
}
const changeToRestartText = () => {
startButton.textContent = 'Restart Game'
}
const generateInputs = (ranNum) => {
const listItem = document.createElement('li');
for(let i = 1; i <= ranNum; i++){
const input = document.createElement('input');
listItem.appendChild(input).setAttribute('type', 'text');
console.log(ranNum)
}
inputsList.appendChild(listItem);
}
const savePoem = () => {
let poemArr = [];
const input = document.querySelectorAll('input');
input.forEach(element => {
poemArr.push(element.value);
})
// console.log(poemArr)
return poemArr;
}
const displayPoem = (poem) => {
const savedPoem = document.createElement('li')
const savedText = document.createElement('span')
const deletePoem = document.createElement('button')
console.log(poem)
savedPoem.appendChild(savedText);
savedText.textContent = poem.toString();
savedPoem.appendChild(deletePoem);
deletePoem.textContent = 'Delete';
poemsList.appendChild(savedPoem)
deletePoem.onclick = e => {
poemsList.removeChild(savedPoem);
}
}
const clearForm = () => {
const inputLi = document.querySelectorAll('li');
inputLi.forEach(element => {
element.remove()
})
}
small html segment
<div >
<ul id="savedThoughts">
</ul>
</div>
Your saved list items aren't showing up because your submit onclick calls displayPoem which creates list items and then calls clearForm which removes all list items on the page. Try inputLi = document.querySelectorAll('ol > li').

Categories