I have a question to save data with localStorage, it would be a shopping cart, it's getting now I need to list the data taken on the other page, I can list it through console.log, but I can't call the data, they can help ?
Page Product where, get the items
function handleCount(){
setItemCount(itemCount + parseInt(document.getElementById("quantity").value));
}
function saveCart(template){
let cartObject = parseCart() // {itemsCount: 1, itemsData: [{'name': pencil, 'quantity': 3, 'price': 2}]};
cartObject.itemsData.push(template)
let diversas_cart = {
'itemsCount': cartObject.itemsData.length,
'itemsData': cartObject.itemsData
};
localStorage.setItem('#diversas/cart', JSON.stringify(diversas_cart))
return 0;
};
function parseCart(){
let cartObject = JSON.parse(localStorage.getItem('#diversas/cart'));
console.log(cartObject)
if(cartObject !== null)
return cartObject;
return {itemsCount: 0, itemsData: []}
};
function addCart(productName, itemCount, price){
let template = {'name': productName, 'quantity': itemCount, 'price': price};
//cartItems.push(template);
saveCart(template);
}
let selectQuantity = []
for (let i = 1; i <= product?.quantity; i++) {
selectQuantity.push(<option value={i}>{i}</option>)
}
<Link to="/shopCart"><button type="button" className="btn btn-green btn-md btn-block" id="addProduct"
onClick={()=>{handleCount()
addCart(`${product?.productName}`, parseInt(document.getElementById("quantity").value), `${product?.price}`);
}}
>Buy{" "}</button></Link>
Page shopCart
let cart = JSON.parse(localStorage.getItem('#diversas/cart'));
var item0Name = cart[0].name;
{cart[0].map(item =>(
<div className="col-sm-12 col-md-3 col-lg-3 col-xl-2 col-main m-5">
<main>
<section>
<div className="card mb-3 mt-3 cardShop" key={item.id}>
<img class="card-img-top" src="" alt="" />
<div class="card-body"></div>
</div>
<h6>{item.name}</h6>
</section>
</main>
</div>
))}
enter image description here
You already have the parseCart() method in your code which returns the parsed cart data as an array. You can get the array by simply calling:
var cart = parseCart();
then you can use the following statements to get the data for each item:
var item0Name = cart[0].name;
var item1Name = cart[1].name;
var item0Quantity = cart[0].quantity;
var item1Quantity = cart[1].quantity;
Edit:
All you need is to use this statement:
var cart = JSON.parse(localStorage.getItem('#diversas/cart'));
var item0Name = cart[0].name;
Related
This is the code from telmo sampiao's shopping cart series, im missing remove items and increment/decrement buttons while also including it on local storage.
function displayCart(){
let cartItems = localStorage.getItem("productsInCart");
cartItems = JSON.parse(cartItems);
let productContainer = document.querySelector(".products");
let cartCost = localStorage.getItem('totalCost');
console.log(cartItems);
if( cartItems && productContainer){
productContainer.innerHTML = '';
Object.values(cartItems).map(item => {
productContainer.innerHTML += `
<div class="product">
<button class="btn btn-danger remove">Remove</button>
<img src="./img/${item.tag}.jpg">
<span>${item.name}</span>
</div>
<div class="price">
₱${item.price}.00
</div>
<div class="quantity"><i class="fa-solid fa-plus"></i> <span>${item.inCart}</span> <i class="fa-solid fa-minus"></i></div>
<div class="total">
₱${item.inCart * item.price}.00
</div>
`
});
productContainer.innerHTML += `
<div class="basketTotalContainer">
<h4 class="basketTotalTitle">
Cart Total
</h4>
<h4 class="basketTotal">
₱${cartCost}.00
</h4>
`;
}
}
Im not good at javascript I tried many diffrenet things but doesnt work
You only store one value for several different inputs. You need to identify each value for each input seperately.
HTML
Add a unique attribute "data-key". Or you can use the "id" of each element.
<div class="item">
<button class="plus" data-qty="1">+</button>
<input class="count" data-qty="1" type="number" min="1" max="5" value="1" data-key="myInput1"> <!-- add a unique key -->
<button class="minus" data-qty="1">-</button>
+
-
Jquery
I altered your code. See comments below. Now "data-key" is used as key for the localStorage.
<script>
let itemData = {
itemQty: 1
};
if (localStorage.getItem("itemData") === null) {
localStorage.setItem("itemData", JSON.stringify(itemData));
}
// new code for initializing
// parse all inputs and user their keys to find the corresponding itemdata
var allinputs = $('.count');
for (var i = 0; i < allinputs.length; i++) {
// get data according to "data-key"
var getItem = loadQuantity($(allinputs[i]).attr('data-key'));
if (getItem != null) {
$(allinputs[i]).val(getItem.itemQty);
} else {
// data not existing. Set global default value
saveQuantity(JSON.stringify(itemData), $(allinputs[i]).attr('data-key')); // *1 set first parameter just to itemData
}
}
$(".plus").click(function () {
// use key to get itemdata of this input
var keyOfInput = $(this).closest(".item").find(".count").attr('data-key');
var getItem = loadQuantity(keyOfInput);
getItem.itemQty = getItem.itemQty + 1;
saveQuantity(getItem, keyOfInput);
$(this).closest(".item").find(".count").val(getItem.itemQty);
});
$(".minus").click(function () {
// use key to get itemdata of this input
var keyOfInput = $(this).closest(".item").find(".count").attr('data-key');
var getItem = loadQuantity(keyOfInput);
if(getItem.itemQty != 1){
getItem.itemQty = getItem.itemQty - 1;
}
saveQuantity(getItem, keyOfInput);
$(this).closest(".item").find(".count").val(getItem.itemQty);
});
// added new parameter "key"
function saveQuantity(data, key) {
localStorage.setItem(key, JSON.stringify(data));
}
function loadQuantity(key) {
return JSON.parse(localStorage.getItem(key)); // *2 Change to JSON.parse(JSON.parse(localStorage.getItem(key)));
}
I think I know what the issue is, I suspect its this causing the issue?
let budgetArray = JSON.parse(window.localStorage.getItem(STORAGE_KEY) ?? "[]");
This is basically getting the stored data from here
/*----Store Stored budget list----*/
function storedEntry(){
const saveData = makeNewBudget();
const myJSON = JSON.stringify(saveData);
window.localStorage.setItem(STORAGE_KEY, myJSON);
}
The makenewbudget() is a function that contains an object of user input data
function makeNewBudget(){
const data = {
id: createId(),
cashflowNew: el.cashflow.value,
catagoryNew: el.catagory.value,
labelNew: el.label.value,
dateNew: createdDate(),
numberNew: el.number.value,
};
return data;
}
I have a function that when you click the create budget button its meant to add to the list
/*----form validation----*/
let budgetButton = document.querySelector(".budget-button");
let label = document.querySelector(".label");
let num = document.querySelector(".number");
let entry = document.querySelector(".entry")
budgetButton.addEventListener("click", () => {
if (!label.value || !num.value) {
alert("please make sure all inputs are filled");
}
budgetArray.push(makeNewBudget())
renderList();
storedEntry();
});
This is the renderList() function
/*----Render Budget List----*/
function renderList(){
el.list.innerHTML = budgetArray.map(function (data,i) {
return `<div class="entry">
<div class="list">
<button onclick="deleteItem(event, ${i})" class="Archive" data-id="${data.id}">
<img src="../resources/Images/archive.png" alt="Archive">
</button>
<button onclick="editItem(event, ${i})" class = "edit" data-id="${data.id}" class = "edit" data-id="${data.id}">
<img src="../resources/Images/edit.png" alt="Edit">
</button>
<div class="input" data-id="${data.id}"></div>
<label class="dateNew">${data.dateNew}</label>
<label class="cashflowNew">${data.cashflowNew}</label>
<label class="catagoryNew">${data.catagoryNew}</label>
<label class="labelNew">${data.labelNew}</label>
<label class="numberNew">${data.numberNew}</label>
</div>
</div>
<label class="total"></label>`;
});
}
I am not sure what I can do to fix the Uncaught TypeError: budgetArray.push is not a function
The error does not appear if I change
let budgetArray = JSON.parse(window.localStorage.getItem(STORAGE_KEY) ?? "[]");
to
let budgetArray = [];
So I am a bit stumped in how to fix that, because The localStorage.getItem needs to check the array for the stored data.
Hope someone can help me out.
I am trying to dynamically create some cards on my webpage out of a dictionary.
I tried to create the function but the code inside the first <div>
cards.map((character)=>(
is not recognizing the array of dictionaries.
Any ideas on how to fix it?
function MemoryCards() {
const images = [
"./img/Abadango.jpeg",
"./img/abradolf.jpeg",
"./img/Adjudicator.jpeg",
"./img/AgencyDirector.jpeg",
"./img/Alan.jpeg",
"./img/Albert.jpeg",
"./img/Alexander.jpeg",
"./img/AlienMorty.jpeg",
"./img/AlienRick.jpeg",
"./img/Annie.jpeg",
"./img/AntsJonson.jpeg",
"./img/Beth.jpeg",
"./img/Jerry.jpeg",
"./img/morty.jpeg",
"./img/ricky.jpeg",
"./img/summer.jpeg"
]
const cards = [];
let len = images.length;
for (let i = 0; i < len; i++) {
let end = images[i].indexOf('.', 3);
let name = images[i].substring(6, end);
let card = { 'name': name, 'img': images[i], 'id': i };
cards.push(card);
}
return (
<div>
cards.map((character)=>(
<div class="card">
<div className="card_header">
<img src={cards.img}></img>
</div>
<div className="card_body">
<h3>{cards.name}</h3>
</div>
</div>
))
</div>
)
}
export default MemoryCards;
Inside your loop you have {cards.img} and {cards.name} but what you want is {character.img} and {character.name}
Also you are missing curly brackets {} before initializing cards loop
Note, you have a typo, instead of className you have just class here: <div class="card">
function MemoryCards() {
const images = [
"./img/Abadango.jpeg",
"./img/abradolf.jpeg",
"./img/Adjudicator.jpeg",
"./img/AgencyDirector.jpeg",
"./img/Alan.jpeg",
"./img/Albert.jpeg",
"./img/Alexander.jpeg",
"./img/AlienMorty.jpeg",
"./img/AlienRick.jpeg",
"./img/Annie.jpeg",
"./img/AntsJonson.jpeg",
"./img/Beth.jpeg",
"./img/Jerry.jpeg",
"./img/morty.jpeg",
"./img/ricky.jpeg",
"./img/summer.jpeg"
];
const cards = [];
let len = images.length;
for (let i = 0; i < len; i++) {
let end = images[i].indexOf(".", 3);
let name = images[i].substring(6, end);
let card = { name: name, img: images[i], id: i };
cards.push(card);
}
return (
<div>
{cards.map((character, idx) => (
<div key={idx} className="card">
<div className="card_header">
<img src={character.img} alt="" />
</div>
<div className="card_body">
<h3>{character.name}</h3>
</div>
</div>
))}
</div>
);
}
export default MemoryCards;
You need to wrap your variables in curly braces {} for it to work inside JSX:
return (
<div>
{cards.map((card)=>(
<div key={card.name} class="card">
<div className="card_header">
<img src={card.img}></img>
</div>
<div className="card_body">
<h3>{card.name}</h3>
</div>
</div>
))}
</div>
)
In the example above, you can see that the entire map block should be inside the curly braces, also don't forget to add an ID to the element inside the map and to use the actual variable defined inside the map function
I am having 6 bootstrap cards in my web page where every card consists of details like id and content. When I clicked the card the details of the card should be pushed into the array and when I clicked the same card the details should be popped from the array.
My html page in django:
<div class="row">
{% for j in goal %}
<div class="col-4" onclick="getGoal({{j.id}})">
<div class="card4 mt-3" id="room_{{j.id}}" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_{{j.id}}"><b>{{j.goal}}</b></p>
</center>
</div>
</div>
</div>
{% endfor %}
My js code is
var goal = []
function getGoal(id ,content){
if (goal !== []) {
for(var i=0; i<goal.length; i++){
if(goal[i].id == id) {
var index = goal.indexOf(goal[i])
if (index !== -1) {
goal.splice(index, 1);
}
}
}
}else {
var data = {id: id, content: $("#cont_"+id).text()}
var x = JSON.stringify(data)
goal.push(x)
console.log(goal)
}
}
var storedNames = JSON.parse(localStorage.getItem("goal"))
Is the JS code correct for my requirement?
As you can see after adding indentations, you html code is not valide where do you close the center tag ? Else where / how do you call getGoal and why do you have the content parameter if you don't use it ?
var goal = []
function getGoal(id ){
if (goal.length > 0) {
let index = goal.findIndex(x=>x.id == id)
if(index != -1){
goal.splice(index, 1);
}
else{
var data = {id: id, content: $("#cont_"+id).text()}
goal.push(data)
}
}else {
var data = {id: id, content: $("#cont_"+id).text()}
//var x = JSON.stringify(data)
goal.push(data)
console.log(goal)
}
}
var storedNames = JSON.parse(localStorage.getItem("goal"))
try It
1) I am rendering messeages according to JSON. Firstly, I need to show only 3 information from that JSON (JSON has 6 attrs). When user click on the rendered message, it should show additional information like description and I need get id of that div... Problem is, I cannot access that id...
I have main div messages, and then message_items are added to this div according to json. When I am trying to get ID of that div, it writes undefined...
My code looks like:
2) How to store additional information about that div which I dont want to be visible?
$(".messages").on('click','.message__item', function(e) {
documentView.clearContent();
var targetElement = event.target || event.srcElement;
alert(targetElement);
var id = $(this).attr("id"); // DOES NOT WORK - UNDEFINED
alert(contentPanelId);
const data = {
title: $(this).find(".title").text(),
date: $(this).find(".date").text(),
desc: document.getElementById("descr").value,
createdBy: document.getElementById("createdBy").value,
id: targetElement.id // DOES NOT WORK, UNDEFINED
};
documentView.renderDocument(data);
});
export const fillDocuments = (data) => {
console.log("DATA. "+ data);
for(var i = 0; i < data.length; i++){
const markup = `
<div class="message__item id=${data[i].id}>
<img src="../img/copy.svg" class="item-type">
<div class="title">
${data[i].title}
</div>
<div class="date">
${formatTimeForMessages(data[i].uploadDatetime)}
</div>
<div class="read">
XY
</div>
// THIS DOES NOT WORK FOR ME AGAIN
<input type="hidden" id="descr" value="${data[i].description}"></input>
<input type="hidden" id="createdBy" value="Someone"/>
</div>`;
console.log("MRK "+ markup);
elements.messages.insertAdjacentHTML("beforeend", markup);
}
};
First, your didn't close the class quote on near "message__item" name. And how store data in a way that isn't visible? use data attribute, se here. Bellow a working example.
$(".messages").on('click','.message__item', function(e) {
///documentView.clearContent();
var targetElement = event.target || event.srcElement;
alert(targetElement.nodeName);
console.log(this);
var id = $(this).attr("id"); // DOES NOT WORK - UNDEFINED
alert(id);
alert(this.dataset.title);
const data = {
title: $(this).find(".title").text(),
date: $(this).find(".date").text(),
desc: document.getElementById("descr").value,
createdBy: document.getElementById("createdBy").value,
id: targetElement.id // DOES NOT WORK, UNDEFINED
};
//documentView.renderDocument(data);
});
var fillDocuments = (data) => {
for(var i = 0; i < data.length; i++){
const markup = `
<div class="message__item" data-title="${data[i].title}" id=${data[i].id}>
<img src="../img/copy.svg" class="item-type">
<div class="title">
${data[i].title}
</div>
<div class="date">
${(data[i].uploadDatetime)}
</div>
<div class="read">
XY
</div>
// THIS DOES NOT WORK FOR ME AGAIN
<input type="hidden" id="descr" value="${data[i].description}"></input>
<input type="hidden" id="createdBy" value="Someone"/>
</div>`;
$("#messages").get(0).insertAdjacentHTML("beforeend", markup);
}
};
fillDocuments([
{id:1, uploadDatetime:Date(), title: 'Title here', description: 'Desc...'}
])
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="messages" class="messages">
</div>