I'm trying to build a simple shopping cart. I want to add the whole item to the cart when clicking the add button. The item looks like this (there are 6 with different name and prices
For now I'm working on adding to the cart just the name (I will use the same process for the price), but when I click the add button it adds the name of the last item and not the one I'm clicking. How do I fix this?
const cart = document.querySelector(".cart");
const productName = document.querySelectorAll(".product-name");
const productPrice = document.querySelector(".product-price");
const addBtn = document.querySelectorAll(".add");
addBtn.forEach(button => {
button.addEventListener("click", addToCart);
})
//Add to cart
function addToCart(e) {
e.preventDefault();
//Create DIV
const item = document.createElement("div");
item.classList.add("item");
//Add name
const name = document.createElement("h2");
name.classList.add("product-name");
productName.forEach(productN => {
name.innerText = productN.innerText;
})
item.appendChild(name);
cart.appendChild(item);
}
<div class="product">
<h2 class="product-name">Beer</h2>
<h3 class="product-price">$4</h3>
<button class="add">Add to cart</button>
</div>
<div class="product">
<h2 class="product-name">Burger</h2>
<h3 class="product-price">$12</h3>
<button class="add">Add to cart</button>
</div>
<section class="section">
<h2 class="text-center">Cart</h2>
<div class="cart"></div>
</section>
You likely want this
const cart = document.getElementById("cart");
const productName = document.querySelectorAll(".product-name");
const productPrice = document.querySelector(".product-price");
const addBtn = document.querySelectorAll(".add");
addBtn.forEach(button => {
button.addEventListener("click", addToCart);
})
//Add to cart
function addToCart(e) {
e.preventDefault();
//Create DIV
const item = document.createElement("div");
item.classList.add("item");
//Add name
const name = document.createElement("h2");
name.classList.add("product-name");
name.innerText = e.target.parentNode.querySelector(".product-name").innerText;
item.appendChild(name);
cart.appendChild(item);
}
<div class="product">
<h2 class="product-name">Beer</h2>
<h3 class="product-price">$4</h3>
<button class="add">Add to cart</button>
</div>
<div id="cart"></div>
Delegate the click from the products
const cart = document.getElementById("cart");
const products = document.getElementById("products");
const productName = document.querySelectorAll(".product-name");
const productPrice = document.querySelector(".product-price");
products.addEventListener("click", addToCart);
//Add to cart
function addToCart(e) {
e.preventDefault();
const tgt = e.target;
if (!tgt.classList.contains("add")) return; // not a button
const parent = tgt.parentNode;
//Create DIV
const item = document.createElement("div");
item.classList.add("item");
//Add name
const name = document.createElement("h2");
name.classList.add("product-name");
name.innerText = parent.querySelector(".product-name").innerText;
item.appendChild(name);
cart.appendChild(item);
}
<div id="products">
<div class=" product ">
<h2 class="product-name ">Beer</h2>
<h3 class="product-price ">$4</h3>
<button class="add ">Add to cart</button>
</div>
<div class="product ">
<h2 class="product-name ">Wine</h2>
<h3 class="product-price ">$4</h3>
<button class="add ">Add to cart</button>
</div>
</div>
<div id="cart"></div>
Related
Top section is my HTML, bottom is my Javascript. This is my first time using stackoverflow, so I may have formatted the code wrong on here. My modal won't connect to the 'get episodes' button for some reason. I think it has something to do with my populateEpisodes function because getEpisodes console.logs the array of episodes object, so I have the array but I can't figure out why my modal won't work.
const missingPhotoURL = "URL stack wouldn't let me post";
async function searchShows(query) {
let showRequest = await axios.get(`http://api.tvmaze.com/search/shows?q=${query}`);
let showArray = [];
for(let show of showRequest.data){
let showObj = {
id: show.show.id,
name: show.show.name,
summary: show.show.summary,
image: show.show.image ? show.show.image.medium : missingPhotoURL
};
showArray.push(showObj)
}
console.log(showRequest);
console.log(showArray);
return showArray; //returns array of show objects
}
function populateShows(shows) {
const $showsList = $("#shows-list");
$showsList.empty();
for (let show of shows) {
let $show = $(
`<div class="col-md-6 col-lg-3 Show" data-show-id="${show.id}">
<div class="card" data-show-id="${show.id}">
<div class="card-body" id = "showCard">
<img class="card-img-top" src=${show.image}>
<h5 class="card-title">${show.name}</h5>
<p class="card-text">${show.summary}</p>
<button class="btn btn-outline-primary get-episodes" id="episodeButton" data-bs-toggle="modal" data-bs-target="#episodeModal">Show Episodes</button>
</div>
</div>
</div>
`
);
$showsList.append($show);
}
}
$("#search-form").on("submit", async function handleSearch (evt) {
evt.preventDefault();
let query = $("#search-query").val();
if (!query) return;
$("#episodes-area").hide();
let shows = await searchShows(query);
populateShows(shows);
});
async function getEpisodes(id) {
let episodesRequest = await axios.get(
`http://api.tvmaze.com/shows/${id}/episodes`
);
console.log(episodesRequest);
let episodeArray = [];
for(let episode of episodesRequest.data){
let episodeObj = {
id: episode.id,
name: episode.name,
season: episode.season,
number: episode.number,
};
episodeArray.push(episodeObj);
}
console.log(episodeArray);
return episodeArray;
}
async function populateEpisodes(episodes){
const $episodesModalBody = $('.modalBody')
//$episodesModalBody.empty();
for(let episode of episodes){
let $episodeBody = $(
`<p> ${episode.name} (Season:${episode.season} Episode:${episode.number})</p>`
);
$episodesModalBody.append($episodeBody);
}
}
$('#shows-list').on('click', '.get-episodes', async function episodeClick(e){
let showID = $(e.target).closest('.Show').data('show-id');
let episodes = await getEpisodes(showID);
populateEpisodes(episodes);
})
<!doctype html>
<html>
<head>
<title>TV Maze</title>
<link rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.css">
</head>
<body>
<h1>TV Maze</h1>
<form class="form-inline" id="search-form">
<input class="form-control" id="search-query" placeholder = 'Show Name'>
<button class="btn btn-primary" type="submit">Go!</button>
</form>
<div class="row mt-3" id="shows-list">
<div class = 'modal fade' id = 'episodeModal' tabindex = '-1'>
<div class = 'modal-dialog modal-dialog-scrollable' >
<div class = 'modal-content'>
<div class = 'modal-header'>
<h5>Episode List:</h5>
</div>
<div class = 'modal-body'>
</div>
<div class = 'modal-footer'>
<button type="button" class="btn btn-outline-danger" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<script src="http://unpkg.com/jquery"></script>
<script src="http://unpkg.com/axios/dist/axios.js"></script>
<script src="tvmaze.js"></script>
</body>
</html>
Add your div to populate inside of the modal body, and add .modal('show'), so the actual modal window can be shown.
const missingPhotoURL = "URL stack wouldn't let me post";
async function searchShows(query) {
let showRequest = await axios.get(`http://api.tvmaze.com/search/shows?q=${query}`);
let showArray = [];
for(let show of showRequest.data){
let showObj = {
id: show.show.id,
name: show.show.name,
summary: show.show.summary,
image: show.show.image ? show.show.image.medium : missingPhotoURL
};
showArray.push(showObj)
}
console.log(showRequest);
console.log(showArray);
return showArray; //returns array of show objects
}
function populateShows(shows) {
const $showsList = $("#shows-list");
$showsList.empty();
for (let show of shows) {
let $show = $(
`<div class="col-md-6 col-lg-3 Show" data-show-id="${show.id}">
<div class="card" data-show-id="${show.id}">
<div class="card-body" id = "showCard">
<img class="card-img-top" src=${show.image}>
<h5 class="card-title">${show.name}</h5>
<p class="card-text">${show.summary}</p>
<button class="btn btn-outline-primary get-episodes" id="episodeButton" data-bs-toggle="modal" data-bs-target="#episodeModal">Show Episodes</button>
</div>
</div>
</div>
`
);
$showsList.append($show);
$('#episodeModal').modal('show');
}
}
$("#search-form").on("submit", async function handleSearch (evt) {
evt.preventDefault();
let query = $("#search-query").val();
if (!query) return;
$("#episodes-area").hide();
let shows = await searchShows(query);
populateShows(shows);
});
async function getEpisodes(id) {
let episodesRequest = await axios.get(
`http://api.tvmaze.com/shows/${id}/episodes`
);
console.log(episodesRequest);
let episodeArray = [];
for(let episode of episodesRequest.data){
let episodeObj = {
id: episode.id,
name: episode.name,
season: episode.season,
number: episode.number,
};
episodeArray.push(episodeObj);
}
console.log(episodeArray);
return episodeArray;
}
async function populateEpisodes(episodes){
const $episodesModalBody = $('.modalBody')
//$episodesModalBody.empty();
for(let episode of episodes){
let $episodeBody = $(
`<p> ${episode.name} (Season:${episode.season} Episode:${episode.number})</p>`
);
$episodesModalBody.append($episodeBody);
}
}
$('#shows-list').on('click', '.get-episodes', async function episodeClick(e){
let showID = $(e.target).closest('.Show').data('show-id');
let episodes = await getEpisodes(showID);
populateEpisodes(episodes);
})
<!doctype html>
<html>
<head>
<title>TV Maze</title>
<link rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.css">
</head>
<body>
<h1>TV Maze</h1>
<form class="form-inline" id="search-form">
<input class="form-control" id="search-query" placeholder = 'Show Name'>
<button class="btn btn-primary" type="submit">Go!</button>
</form>
<div class="row mt-3" >
<div class = 'modal fade' id = 'episodeModal' tabindex = '-1'>
<div class = 'modal-dialog modal-dialog-scrollable' >
<div class = 'modal-content'>
<div class = 'modal-header'>
<h5>Episode List:</h5>
</div>
<div class = 'modal-body'>
<div id="shows-list"></div>
</div>
<div class = 'modal-footer'>
<button type="button" class="btn btn-outline-danger" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<script src="http://unpkg.com/jquery"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/js/bootstrap.min.js"></script>
<script src="http://unpkg.com/axios/dist/axios.js"></script>
<!--script src="tvmaze.js"></script-->
</body>
</html>
I am facing a problem within JavaScript when I attempt to delete a li, it will delete the entire ul. Does anyone know a solution for this?
const add = document.querySelector(".add");
add.addEventListener("click", function() {
const cont = document.querySelector(".menu");
const input = document.querySelector(".put");
const newli = document.createElement("LI");
const text = document.createTextNode(input.value);
cont.append(newli);
newli.appendChild(text);
})
const remove = document.querySelector(".remove");
remove.addEventListener("click", function() {
const df = document.querySelector(".menu");
df.remove(newli);
})
<div class="parent-row">
<h1>Add a new Post </h1>
<div>
<input type="text" class="put">
<button class="add">Add a Post</button>
<button class="remove">Remove a Post</button>
</div>
<ul class="menu">
<li>Albenis</li>
</ul>
</div>
</div>
</div>
</div>
Solution
HTML:
<div class="parent-row">
<h1>Add a new Post</h1>
<div>
<input type="text" class="put" />
<button class="add">Add a Post</button>
<button class="remove">Remove a Post</button>
</div>
<ul class="menu">
<li>Albenis</li>
</ul>
</div>
JavaScript:
const add = document.querySelector(".add");
const remove = document.querySelector(".remove");
add.addEventListener("click", function () {
const cont = document.querySelector(".menu");
const input = document.querySelector(".put");
const newli = document.createElement("LI");
newli.innerText = input.value;
cont.append(newli);
});
remove.addEventListener("click", function () {
const df = document.querySelector(".menu");
df.firstElementChild.remove();
});
Working example: https://codesandbox.io/s/pensive-almeida-z82lr?file=/index.html:262-561
Your error
Your error was you were trying to get the newli constant from outside of its code block remember that const variables are scoped to there block.
A different way of doing this
This way is a bit more simplified and allows you to delete anyone of the posts not just the last added.
const postBtn = document.querySelector('#post')
const list = document.querySelector('#list')
postBtn.addEventListener('click', () => {
const text = document.querySelector('#post-text')
list.innerHTML += `<li>${text.value} <button id="remove" onclick="remove(event)">remove</button></li>`
text.value = ''
})
const remove = (e) => {
e.target.parentElement.remove()
}
<div>
<h1>Make a post</h1>
<input id="post-text" type="text" placeholder="Text"><button id="post">Post</button>
<ul id="list">
</ul>
</div>
Question
I have created a cart, where you can add or remove items. If you remove an item, the price is taken away from the total price calculation: and more importantly the element that is displayed as a cart item is removed from the Cart.
When many cart items are added to the cart, for some reason only the very first cart item can be removed. All subsequent remove buttons do not work.
I will do my best to provide a minimal sample:
if(document.readyState == 'loading'){
document.addEventListener('DOMContentLoaded', ready);
} else {
ready();
}
const BasketTotal = document.getElementsByClassName('basket-total')[0];
function ready(){
let removeCartItemButtons = document.getElementsByClassName('remove-btn');
for(let i = 0; i < removeCartItemButtons.length; i++){
let button = removeCartItemButtons[i];
button.addEventListener('click', removeCartItem);
}
let addToCartButtons = document.getElementsByClassName('add-to-cart-btn');
for(let i=0; i < addToCartButtons.length; i++){
let button = addToCartButtons[i];
button.addEventListener('click', addToCartClicked);
}
document.getElementsByClassName('btn-purchase')[0].addEventListener('click', purchaseClicked);
}
function purchaseClicked(){
alert('Thank you for your purchase');
var cartItems = document.getElementsByClassName('cart-cards')[0];
while(cartItems.hasChildNodes()){
cartItems.removeChild(cartItems.firstChild)
}
updateCartTotal()
}
function removeCartItem(event){
let buttonClicked = event.target;
buttonClicked.parentElement.parentElement.remove();
updateCartTotal();
}
function addToCartClicked(event){
let button = event.target;
let cartItem = button.parentElement;
let title = cartItem.getElementsByClassName('dom-title')[0].innerText;
let price = cartItem.getElementsByClassName('item-price')[0].innerText;
addItemToCart(title, price);
updateCartTotal();
}
function addItemToCart(title, price){
let basketItem = document.createElement('div');
//CartItems was changed to cartCards
let cartCards = document.getElementsByClassName('cart-cards')[0];
let cartItemNames = cartCards.getElementsByClassName('cart-domain');
for(let i = 0; i < cartItemNames.length; i++){
if(cartItemNames[i].innerText == title){
alert('This item is already added to the cart');
return;
}
}
let cartContents = `
<br>
<br>
<div class="cart-card">
<h5 class="cart-domain">${title}<span style="color: gray">.crypto</span></h5>
<hr style="width: 80%; margin: auto;">
<p class="cart-text">No recurring fees. This domain will never expire. You will own the domain outright.</p>
<br>
<br>
<button class="cart-purchase">Buy it now</button>
<div class="price-cart-item">
<br>
<br>
<p>
Price: <span class="cart-item-price">${price}</span>
</p>
<br>
<button class="remove-btn">Remove <i class="fas fa-trash"></i></button>
</div>
<p class="cart-text">Renewal Cost: $0.00</p>
</div>`;
basketItem.innerHTML = cartContents;
cartCards.append(basketItem);
cartCards.getElementsByClassName('remove-btn')[0].addEventListener('click', removeCartItem);
}
function updateCartTotal(){
let cartItemContainer = document.getElementsByClassName('cart-cards')[0];
let cartCards = cartItemContainer.getElementsByClassName('cart-card');
let total = 0;
for(let i =0; i < cartCards.length; i++){
let cartCard = cartCards[i];
let priceElement = cartCard.getElementsByClassName('cart-item-price')[0];
let price = parseFloat(priceElement.innerText.replace('$', '').replace(',', ''));
total += price;
}
total = Math.round(total * 100) / 100;
let commasAdded = total.toLocaleString();
document.getElementsByClassName('basket-total')[0].innerText = '$' + commasAdded;
}
<!--Products for sale -->
<div class="domain-item">
<p class="domain-aspect domain-title"><strong class="linked"><span class="dom-title">happy</span><span style="color: #1a6db7">.com</span></strong> <span class="item-price">$100,000</span></p>
<button class="domain-aspect add-to-cart-btn">Add To Cart</button>
</div>
<div class="domain-item">
<p class="domain-aspect domain-title"><strong class="linked"><span class="dom-title">exchange</span><span style="color: #1a6db7">.com</span></span></strong> <span class="item-price">$100,000</span></p>
<button class="domain-aspect add-to-cart-btn">Add To Cart</button>
</div>
<div class="domain-item">
<p class="domain-aspect domain-title"><strong class="linked"><span class="dom-title">bestdadever</span><span style="color: #1a6db7">.com</span></span></strong> <span class="item-price">$100,000</span></p>
<button class="domain-aspect add-to-cart-btn">Add To Cart</button>
</div>
<!--Cart-->
<div class="cart-total-text">
<p>Your Items</p>
<p>Total: <span class="basket-total"></span></p>
</div>
<div class="cart-cards">
</div>
This would really help me out if you can identify why the remove buttons are only working some of the time!
You call the ready() function only once when the document is ready. I made a little change in your code and put the ready() function into your addToCartClicked(event) function too. So every time you click the add to cart button, you create the remove buttons, and then you add the event listeners.
Hope it helps you.
if(document.readyState == 'loading'){
document.addEventListener('DOMContentLoaded', ready);
} else {
ready();
}
const BasketTotal = document.getElementsByClassName('basket-total')[0];
function ready(){
let removeCartItemButtons = document.getElementsByClassName('remove-btn');
for(let i = 0; i < removeCartItemButtons.length; i++){
let button = removeCartItemButtons[i];
button.addEventListener('click', removeCartItem);
}
let addToCartButtons = document.getElementsByClassName('add-to-cart-btn');
for(let i=0; i < addToCartButtons.length; i++){
let button = addToCartButtons[i];
button.addEventListener('click', addToCartClicked);
}
document.getElementsByClassName('btn-purchase')[0].addEventListener('click', purchaseClicked);
}
function purchaseClicked(){
alert('Thank you for your purchase');
var cartItems = document.getElementsByClassName('cart-cards')[0];
while(cartItems.hasChildNodes()){
cartItems.removeChild(cartItems.firstChild)
}
updateCartTotal()
}
function removeCartItem(event){
let buttonClicked = event.target;
buttonClicked.parentElement.parentElement.remove();
updateCartTotal();
}
function addToCartClicked(event){
let button = event.target;
let cartItem = button.parentElement;
let title = cartItem.getElementsByClassName('dom-title')[0].innerText;
let price = cartItem.getElementsByClassName('item-price')[0].innerText;
addItemToCart(title, price);
updateCartTotal();
// HERE
ready();
}
function addItemToCart(title, price){
let basketItem = document.createElement('div');
//CartItems was changed to cartCards
let cartCards = document.getElementsByClassName('cart-cards')[0];
let cartItemNames = cartCards.getElementsByClassName('cart-domain');
for(let i = 0; i < cartItemNames.length; i++){
if(cartItemNames[i].innerText == title){
alert('This item is already added to the cart');
return;
}
}
let cartContents = `
<br>
<br>
<div class="cart-card">
<h5 class="cart-domain">${title}<span style="color: gray">.crypto</span></h5>
<hr style="width: 80%; margin: auto;">
<p class="cart-text">No recurring fees. This domain will never expire. You will own the domain outright.</p>
<br>
<br>
<button class="cart-purchase">Buy it now</button>
<div class="price-cart-item">
<br>
<br>
<p>
Price: <span class="cart-item-price">${price}</span>
</p>
<br>
<button class="remove-btn">Remove <i class="fas fa-trash"></i></button>
</div>
<p class="cart-text">Renewal Cost: $0.00</p>
</div>`;
basketItem.innerHTML = cartContents;
cartCards.append(basketItem);
cartCards.getElementsByClassName('remove-btn')[0].addEventListener('click', removeCartItem);
}
function updateCartTotal(){
let cartItemContainer = document.getElementsByClassName('cart-cards')[0];
let cartCards = cartItemContainer.getElementsByClassName('cart-card');
let total = 0;
for(let i =0; i < cartCards.length; i++){
let cartCard = cartCards[i];
let priceElement = cartCard.getElementsByClassName('cart-item-price')[0];
let price = parseFloat(priceElement.innerText.replace('$', '').replace(',', ''));
total += price;
}
total = Math.round(total * 100) / 100;
let commasAdded = total.toLocaleString();
document.getElementsByClassName('basket-total')[0].innerText = '$' + commasAdded;
}
<!--Products for sale -->
<div class="domain-item">
<p class="domain-aspect domain-title"><strong class="linked"><span class="dom-title">happy</span><span style="color: #1a6db7">.com</span></strong> <span class="item-price">$100,000</span></p>
<button class="domain-aspect add-to-cart-btn">Add To Cart</button>
</div>
<div class="domain-item">
<p class="domain-aspect domain-title"><strong class="linked"><span class="dom-title">exchange</span><span style="color: #1a6db7">.com</span></span></strong> <span class="item-price">$100,000</span></p>
<button class="domain-aspect add-to-cart-btn">Add To Cart</button>
</div>
<div class="domain-item">
<p class="domain-aspect domain-title"><strong class="linked"><span class="dom-title">bestdadever</span><span style="color: #1a6db7">.com</span></span></strong> <span class="item-price">$100,000</span></p>
<button class="domain-aspect add-to-cart-btn">Add To Cart</button>
</div>
<!--Cart-->
<div class="cart-total-text">
<p>Your Items</p>
<p>Total: <span class="basket-total"></span></p>
</div>
<div class="cart-cards">
</div>
I have a webpage that looks like this
I want it like that every time the save note is pressed a new card with updated title and description appears on the right.
This is the html code I wrote
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-4 rightLine">
<h1 class="bottomLine">Note List</h1>
<div class="active-cyan-3 active-cyan-4 mb-4">
<input class="form-control" type="text" placeholder="Search" aria-label="Search">
</div>
<div id ="cards"></div>
</div>
<div class="col-md-8">
<h1 class="bottomLine">Note</h1>
<div class="active-cyan-3 active-cyan-4 mb-4">
<input class="form-control" id="title" type="text" placeholder="Enter title here" aria-label="Search">
</div>
<div class="active-cyan-3 active-cyan-4 mb-4 bottomLine">
<textarea class="form-control" id="description" rows="15" placeholder="Enter descirption here"></textarea>
</div>
<div>
<button type="button" id="removenote" class="btn btn-outline-danger">Remove Note</button>
<button type="button" id="savenote" class="btn btn-outline-success" onclick="x.saveNote()">Save Note</button>
<button type="button" id="addnote" class="btn btn-outline-primary" onclick="x.addNote()">Add Note</button>
</div>
</div>
</div>
</div>
The card is the one with id=card in the code and that is the thing I want new every-time.
This is the javascript I wrote
class Note {
constructor(name, description) {
this.name = name;
this.description = description;
}
}
class NoteComponent {
constructor() {
this.listOfNotes = [];
}
saveNote() {
let title = document.getElementById("title").value;
let description = document.getElementById("description").value;
let currentNote = new Note(title, description);
this.listOfNotes.push(currentNote);
getCardHTML(this.listOfNotes);
this.listOfNotes.forEach((arrayItem) => {
console.log('name is ' + arrayItem.name + ' description is ' + arrayItem.description);
});
}
addNote() {
let title = document.getElementById("title").value = "";
let description = document.getElementById("description").value = "";
}
filterList(noteList, Query) {}
}
/*when the specific note card clicked the title and description places will be populated*/
function showNote(){
console.log('the onclcik worked fine');
}
function getCardHTML(arr) {
let divOfCards = document.getElementById('cards');
while (divOfCards.firstChild) {
divOfCards.removeChild(divOfCards.firstChild);
}
for (let i = 0; i < arr.length; i++) {
let div = document.getElementById("cards");
let anchor = document.createElement("div");
anchor.className = "list-group-item list-group-item-action flex-column align-items-start";
let innerDiv = document.createElement("div");
innerDiv.className = "d-flex w-100 justify-content-between";
let divHeading = document.createElement("h5");
divHeading.className = "mb-1";
divHeading.innerHTML = arr[i].name;
let divPara = document.createElement("p");
divPara.className = "mb-1";
divPara.innerHTML = arr[i].description;
//anchor.href = "#";
anchor.onclick = showNote();
innerDiv.appendChild(divHeading);
anchor.appendChild(innerDiv);
anchor.appendChild(divPara);
div.appendChild(anchor);
}
}
let x = new NoteComponent();
When a new note is saved it appears on the left side. I don't understand how when that card on the left side is clicked that notes title and description occupies the places on the right.
There is a JavaScript function called createElement() that allows you to create and assign a HTML element into a variable.
Once the element is created, just append the content to it and then append the element to a HTML element.
For example:
var body = document.getElementsByTagName('body');
var title = document.getElementById("title").value;
var description = document.getElementById("description").value;
var div = document.createElement("div");
var h1 = document.createElement("h1");
var p = document.createElement("p");
// assign values to elements
h1.textContent = title;
p.textContent = description;
// append elements to div
div.appendChild(h1);
div.appendChild(p);
// append div to body
body.appendChild(div);
You can also use createTextNode instead of textContent.
Traverse the listOfNodes and create card and append it to the div. Whenever you click savenote the card will be appeared. Here is the working demo.
class Note{
constructor(name, description) {
this.name = name;
this.description = description;
}
}
let listOfNotes = [];
class NoteComponent{
constructor(){}
filterList(noteList,Query){}
}
document.getElementById("savenote").addEventListener("click", function(){
let title = document.getElementById("title").value;
let description = document.getElementById("description").value;
let currentNote = new Note(title,description);
listOfNotes.push(currentNote);
var newNode = document.getElementById("card");
listOfNotes.forEach((arrayItem) => {
console.log(arrayItem.name);
var name = document.createElement("h5");
var nameText = document.createTextNode(arrayItem.name);
name.appendChild(nameText);
var description = document.createElement("p");
var desc = document.createTextNode(arrayItem.description);
description.appendChild(desc);
var card_body = document.createElement("div");
card_body.className = "card_body";
card_body.appendChild(name);
card_body.appendChild(description);
var card = document.createElement("div");
card.className = "card";
card.appendChild(card_body);
var aTag = document.createElement("a");
aTag.className="custom-card";
aTag.setAttribute("id", "card");
aTag.appendChild(card);
var cardDiv = document.getElementById("card");
cardDiv.appendChild(aTag);
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-4 rightLine">
<h1 class="bottomLine">Note List</h1>
<div class="active-cyan-3 active-cyan-4 mb-4">
<input class="form-control" type="text" placeholder="Search" aria-label="Search">
</div>
<div id="card">
<a href="#" id="card" class="custom-card">
<div class="card">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
</div>
</div>
</a>
</div>
</div>
<div class="col-md-8">
<h1 class="bottomLine">Note</h1>
<div class="active-cyan-3 active-cyan-4 mb-4">
<input class="form-control" id="title" type="text" placeholder="Enter title here" aria-label="Search">
</div>
<div class="active-cyan-3 active-cyan-4 mb-4 bottomLine">
<textarea class="form-control" id="description" rows="15" placeholder="Enter descirption here"></textarea>
</div>
<div>
<button type="button" id="removenote" class="btn btn-outline-danger">Remove Note</button>
<button type="button" id="savenote" class="btn btn-outline-success">Save Note</button>
<button type="button" id="addnote" class="btn btn-outline-primary">Add Note</button>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
<script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</div>
</body>
</html>
Replace your anchor template (your "a ...id="card" code) with an unordered list like so:
<ul id="cards"></ul>
Then utilize DOM's appendChild() method:
https://www.w3schools.com/jsref/met_node_appendchild.asp
So your JS code will be something like this
document.getElementById("savenote").addEventListener("click", function(){
let title = document.getElementById("title").value;
let description = document.getElementById("description").value;
let currentNote = new Note(title,description);
let listedCard = document.createElement("LI");
listOfNotes.push(currentNote);
listOfNotes.forEach((arrayItem) => {
console.log('name is ' + arrayItem.name + ' description is ' + arrayItem.description);
});
// New code
let listedCard = document.createElement("LI");
let cardAnchor = document.createElement("A");
//...
listedCard.appendChild(cardAnchor);
//...
// The rest of your HTML code for the <a...id="card"> goes here. Little tedious
// Finally append the listedCard to the UL
let cardList = document.getElementById("cards");
cardList.appendChild(listedCard);
});
The simplest solution IMO would be generate the HTML by looping over the Notes array.
1) This function iterates (using map) over the array and returns HTML using a template literal (what's between the back-ticks):
function getCardHTML(arr) {
// Array.map returns a new array
return arr.map(({ name, description }) => {
// In this case the array has a number of elements containing
// HTML strings
return `<h5 class="card-title">${name}</h5><p class="card-text">${description}</p>`;
// which is joined into one HTML string before it's returned
}).join('');
}
2) And you can add it to the card panel like this:
const cards = document.querySelector('.card-body');
cards.innerHTML = getCardHTML(listOfNotes);
DEMO
Edit
In order to solve the next part of the question move all the node selections outside of the functions, and then add an event listener to the cards container.
class Note {
constructor(name, description) {
this.name = name;
this.description = description;
}
}
class NoteComponent {
constructor() {}
filterList(noteList, Query) {}
}
const listOfNotes = [];
const title = document.getElementById('title');
const description = document.getElementById('description');
const save = document.getElementById("savenote");
save.addEventListener("click", saveNote, false);
const cards = document.querySelector('.cards');
cards.addEventListener('click', showNote, false);
function getCardHTML(arr) {
return arr.map(({ name, description }, i) => {
return `<div data-id="${i}" class="card"><h5>${name}</h5><p>${description}</p></div>`;
}).join('');
}
function saveNote() {
let currentNote = new Note(title.value, description.value);
listOfNotes.push(currentNote);
cards.innerHTML = getCardHTML(listOfNotes);
}
function showNote(e) {
const t = e.target;
const id = t.dataset.id || t.parentNode.dataset.id;
title.value = listOfNotes[id].name;
description.value = listOfNotes[id].description;
}
<div class="cards"></div>
<div>
<input id="title" type="text" placeholder="Enter title here" aria-label="Search">
</div>
<div>
<textarea id="description" rows="15" placeholder="Enter descirption here"></textarea>
</div>
<div>
<button type="button" id="removenote">Remove Note</button>
<button type="button" id="savenote">Save Note</button>
<button type="button" id="addnote">Add Note</button>
</div>
Hope that helps.
I tried to get element's values in div with button click and bring div's values into input box.
and I tried this:
window.onload = function () {
$('.DA').on('click', '.submit_btn', function () {
var getinfo = $(this).val();
$('#val_input').val(getinfo);
});
};
this is my example.html
<input id="val_input">
<li class = 'CA'>
<div class = 'DA'>
<h1 id = 'HA'>name1</h1>
<span class = 'SA'>info1-1</span>
<span class = 'SB'>info1-2</span>
<span class = 'SC'>info1-3</span>
<button type = "submit" class = "submit_btn">submit</button>
</div>
<li>
<li class = 'CA'>
<div class = 'DA'>
<h1 id = 'HA'>name2</h1>
<span class = 'SA'>info2-1</span>
<span class = 'SB'>info2-2</span>
<span class = 'SC'>info2-3</span>
<button type = "submit" class = "submit_btn">submit</button>
</div>
<li>
...
I'm also tried to put one value in input box like this:
window.onload = function () {
$('.DA').on('click', '.submit_btn', function () {
var getinfo = $(".SA").val();
$('#val_input').val(getinfo);
});
};
but it dosen't work.
I 'm very new to JS and Jquery so can't get a clue how to solve & where am I missing...
Try this
check this link
<input id="val_input">
<li class= 'CA'>
<div class= 'DA'>
<h1 id = 'HA'>name2</h1>
<span class= 'SA'>info2-1</span>
<span class= 'SB'>info2-2</span>
<span class= 'SC'>info2-3</span>
<button type= "button" class="subimit">submit</button>
</div>
<li>
$(document).ready(function(){
$('.subimit').click(function(){
var getinfo = $(this).prevAll(".SA").text();
$('#val_input').val(getinfo);
});
});
You need to use .text() instead of .val(). you will also need current clicked element context to target sibling span text:
$('.DA').on('click', '.submit_btn', function () {
var getinfo = $(this).prevAll(".SA").text();
$('#val_input').val(getinfo);
});
$(document).on('click', '.subimit_btn', function() {
var getinfo = $(this).text();
$('#val_input').attr('value', getinfo);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="val_input">
<li class = 'CA'>
<div class = 'DA'>
<h1 id = 'HA'>name1</h1>
<span class = 'SA'>info1-1</span>
<span class = 'SB'>info1-2</span>
<span class = 'SC'>info1-3</span>
<button type = "submit" class = "subimit_btn">submit</button>
</div>
<li>
<li class = 'CA'>
<div class = 'DA'>
<h1 id = 'HA'>name2</h1>
<span class = 'SA'>info2-1</span>
<span class = 'SB'>info2-2</span>
<span class = 'SC'>info2-3</span>
<button type = "submit" class = "subimit">submit</button>
</div>
<li>