Add to cart buttons functionality - javascript

I have products and a cart. Each product has an "Add to cart" button and when you click it, it'll add the product to the cart and the inner text of the button will be "In cart" and the button will be disabled. My problem is that I can't figure out how to enable the button and change the inner text back to "Add to cart" after I remove the product from the cart or clear it.
This is the JS for adding the product:
let addBtns = document.getElementsByClassName("bag-btn");
for (let i = 0; i < addBtns.length; i++) {
const btn = addBtns[i];
btn.addEventListener("click", addToCart);
}
function addToCart(e) {
const button = e.target;
button.innerText = "In Cart";
button.disabled = true;
const title = button.parentElement.nextElementSibling.textContent;
const price =
button.parentElement.nextElementSibling.nextElementSibling.children[0]
.textContent;
const img = button.parentElement.children[0].src;
addItemToCart(title, price, img);
}
function addItemToCart(title, price, img) {
const newRow = document.createElement("div");
newRow.classList.add("cart-item");
newRow.innerHTML = `
<img src="${img}" alt="product" srcset="" />
<div>
<h4>${title}</h4>
<h5>${price}</h5>
<span class="remove-item">Remove</span>
</div>
<div>
<i class="fas fa-chevron-up"></i>
<p class="item-amount">1</p>
<i class="fas fa-chevron-down"></i>
</div>`;
cartContent.append(newRow);
}
this is the remove product function:
cartContent.addEventListener("click", (e) => {
if (e.target.classList.contains("remove-item")) {
let removeItem = e.target;
cartContent.removeChild(removeItem.parentElement.parentElement);
SO, how to change the button text and functionality back to normal after I remove the product from the cart? Any help would be appreciated.

Why do you not do the same delegation for the add as you do for the remove?
I do not have your HTML, but something like this
cartContent.addEventListener("click", (e) => {
const tgt = e.target;
if (tgt.classList.contains("remove-item")) {
tgt.closest("whatever container").remove();
tgt.closest("whatever container has button").querySelector(".bag-btn").textContent="Add to cart";
}
else if (e.target.classList.contains("bag-btn")) addToCart(tgt)
})
and have
function addToCart(button) {
// const button = e.target;
All those parentElement.nextElementSibling.nextElementSibling.children[0] are horrific
Instead use button.closest("whatever container").querySelector("some selector")

Related

show the number of likes when click the like button

I try this concept but it not success, When I click the like button
then count of likes will be increase by 1 again I press that button
then it decrease by 1. For example, Now the count is 5 I click the
like button then the count is 6, again I press now the count is 5
(like Facebook).
JSP
<button class="like_btn" onclick="like()">
<span id="icon"><i class="far fa-thumbs-up"></i></span> <span
id="count">0</span>Like
</button>
JavaScript
function like(){
const likeBtn = document.querySelector(".like_btn");
let likeIcon= document.querySelector("#icon");
let count = document.querySelector("#count");
let clicked = false;
likeBtn.addEventListener("click", () => {
if (!clicked) {
clicked = true;
likeIcon.innerHTML = `<i class="fas fa-thumbs-up"></i>`;
count.textContent++;
}else{
clicked = false;
likeIcon.innerHTML = `<i class="far fa-thumbs-up"></i>`;
count.textContent--;
}
});
}

Trying to appendChild an user input and a button element into the same <li>

i am trying to get a event planner app to show some user input and subsequently allow them to delete it when needed.
i have the input part working, but i can't figure out how to get a button with "delete" added to the same li when the user presses Enter.
this is my JS so far: (what do i need to add to get the button included in the li)
function todoList(){
const item: string = (<HTMLInputElement>document.getElementById('todoInput')).value;
const text = document.createTextNode(item)
const newItem = document.createElement('li')
const button: any = document.createElement("button")
button.innerHTML = 'Delete';
newItem.appendChild(text)
// #ts-ignore
}
const form = (<HTMLInputElement>document.getElementById('todoForm'))
form.addEventListener("submit", (e) => {
e.preventDefault();
})
<h1 class="title">todos</h1>
<form id="todoForm" onsubmit="todoList()" >
<button id="scrolldown-menu-toggle">˅</button>
<input type="text" id="todoInput" placeholder="Fill in your plan">
</form>
<ol id="todoList">
</ol>
You need to append the button into the <li> as well.
So you would want to do this -
function todoList(){
const item: string =
(<HTMLInputElement>document.getElementById('todoInput')).value;
const text = document.createTextNode(item)
const newItem = document.createElement('li')
const button: any = document.createElement("button")
button.innerHTML = 'Delete';
newItem.appendChild(text)
newItem.appendChild(button) // <--- Add this line
// #ts-ignore
}
This seems to work:
function todoList() {
// <HTMLInputElement> removed as the snippet will not run otherwise.
// This does however not seem to affect the execution of the code.
// Read the input text into variable:
const item: string = (document.getElementById('todoInput')).value;
// Create text-node:
const text = document.createTextNode(item);
// Create list item:
const newItem = document.createElement('li');
// Create button:
const button: any = document.createElement("button");
// Create button text node and append it to button:
const btnText = document.createTextNode('Delete');
button.appendChild(btnText);
// Add handler to actually delete the entry:
button.addEventListener('click', e => newItem.remove());
// Append text and button to the list item:
newItem.appendChild(text);
newItem.appendChild(button);
// Append list item to the ordered list:
document.getElementById('todoList').appendChild(newItem);
// #ts-ignore
}
const form = (document.getElementById('todoForm'))
form.addEventListener("submit", (e) => {
e.preventDefault();
})
<h1 class="title">todos</h1>
<form id="todoForm" onsubmit="todoList()">
<button id="scrolldown-menu-toggle" type="submit">˅</button>
<input type="text" id="todoInput" placeholder="Fill in your plan" />
</form>
<ol id="todoList">
</ol>

Filter function not working in a Todo App

i'm a beginner trying to learn JS, I have made this todo app, everything's working fine but for some reason the filter function won't work, i tried everything I could think of. Please help.
I had already made this app with materialize and it worked fine.
I already tried to use task.style.display and task.className but it didn't work.
SITE DEMO
https://codepen.io/salma-py97/pen/mdOdLvo?editors=1010
here's the HTML:
<body class="bg-secondary">
<div class="container">
<div class="row">
<div class="col">
<div class="col-md-6 mx-auto">
<div class="card card-body text-center mt-5">
<h2 class="display-5 pb-3">
<i class="fas fa-list"></i> Task List
</h2>
<form id="task-form">
<div class="form-group">
<input type="text" class="form-control" id="task-input" placeholder="Task" value="">
</div>
<div class="form-group">
<input type="submit" value="Add Task" class="btn btn-dark btn-block">
</div>
</form>
<hr>
<h3 class="display-5">Task</h3>
<div class="form-group">
<input type="text" class="form-control" id="filter-tasks" placeholder="Filter Tasks">
</div>
<ul class="list-group mb-4" id="task-list"></ul>
<div class="form-group">
<input type="submit" class="btn btn-large btn-dark mx-auto" id="clear-tasks" value="Clear Tasks">
</div>
</div>
</div>
</div>
</div>
</div>
here's the JS:
// Define UI Variables
const form = document.querySelector('#task-form');
const taskInput = document.querySelector('#task-input');
const filter = document.querySelector('#filter-tasks')
const taskList = document.querySelector("#task-list");
const clearBtn= document.querySelector("#clear-tasks");
// Load All Event Listeners
loadEventListeners();
// Event Listeners
function loadEventListeners(){
// DOM Event Load
document.addEventListener('DOMContentLoaded', getTasks);
// Add Task
form.addEventListener('submit', addTask);
// Remove task (Event delegation --> putting the eventlistener on the parent element(ul))
taskList.addEventListener('click', removeTask);
// filter Tasks
filter.addEventListener('keyup', filterTasks);
// Clear Tasks
clearBtn.addEventListener('click', clearTasks)
}
// Event Handlers
// Get ALL the Tasks when the DOM Loads
function getTasks(){
let tasks;
if (localStorage.getTasks("tasks")===null){
tasks=[];
} else {
tasks=JSON.parse(localStorage.getItem("tasks"));
}
tasks.forEach(function(task){
// Create li element
const li = document.createElement('li');
// Add Bootstrap4 class
li.className = 'list-group-item d-flex justify-content-between'
// Create TextNode and append to li
li.appendChild(document.createTextNode(task));
// Create link element
const link = document.createElement('a');
// Add class to link
link.className='delete-item';
// Add icon innerHTML
link.innerHTML = '<i class= "fa fa-remove"></i>';
// append link to li
li.appendChild(link);
// append li to ul
taskList.appendChild(li);
})
}
//Add Task
function addTask(e){
if(taskInput.value === ""){
alert("Add task");
} else {
// Create li element
const li = document.createElement('li');
// Add Bootstrap4 class
li.className = 'list-group-item d-flex justify-content-between'
// Create TextNode and append to li
li.appendChild(document.createTextNode(taskInput.value));
// Create link element
const link = document.createElement('a');
// Add class to link
link.className='delete-item';
// Add icon innerHTML
link.innerHTML = '<i class= "fa fa-remove"></i>';
// append link to li
li.appendChild(link);
// append li to ul
taskList.appendChild(li);
// store in LocalStorage
AddTasktoLocalStorage(taskInput.value);
// clear taskInput
taskInput.value='';
// Prevent Default behaviour of forms
e.preventDefault();
}
}
// Add task to LocalStorage
function AddTasktoLocalStorage(task){
let tasks;
if (localStorage.getItem("tasks")=== null){
tasks=[];
} else {
tasks= JSON.parse(localStorage.getItem("tasks"));
}
tasks.push(task);
// store the new array
localStorage.setItem("tasks", JSON.stringify(tasks));
}
// Remove task
function removeTask(e){
// Event Delegation
if (e.target.parentElement.classList.contains('delete-item')){
e.target.parentElement.parentElement.remove();
}
// remove from LocalStorage
removeTaskFromLocalStorage(e.target.parentElement.parentElement);
}
function removeTaskFromLocalStorage(taskItem){
// initialise tasks
let tasks;
// check if tasks is stored in LS
if (localStorage.getItem("tasks")===null){
// if it is not, set tasks array
tasks=[];
// if it is, parse through it
tasks = JSON.parse(localStorage.getItem("tasks"));
}
//loop through the tasks array
// if a task in the array matches the task we want removed --> remove it
tasks.forEach(function(task, index){
// !!!! task is text, taskItem should be text as well
if(task === taskItem.textContent){
// remove 1 task starting from its index
tasks.splice(index,1);
}
})
// store new tasks array
localStorage.setItem("tasks", JSON.stringify(tasks));
}
// filter Tasks
function filterTasks(e){
// compare between tasks in the ul and the input in the filter
const text = e.target.value.toLowerCase();
// console.log(text);
document.querySelectorAll('.list-group-item').forEach(function(task){
// if the filterInput matches a task, show task
// console.log(task);
const item = task.firstChild.textContent;
if(item.toLowerCase().indexOf(text) != -1){
task.classList.add("d-block");
// else hide task
} else {
task.classList.add("d-none");
}
})
}
// Clear Tasks
function clearTasks(e){
// Clear ul
taskList.innerHTML="";
e.preventDefault();
// Clear LocalStorage
clearsTasksFromLocalStorage();
}
// Clear LocalStorage
function clearTasksFromLocalStorage(){
localStorage.clear();
}
One source of data is my favorite concept and DRY
const form = document.querySelector('#task-form');
const taskInput = document.querySelector('#task-input');
const filter = document.querySelector('#filter-tasks')
const taskList = document.querySelector("#task-list");
const clearBtn= document.querySelector("#clear-tasks");
class Tasks {
constructor(taskList) {
this.taskList = taskList;
this.tasks=[];
this.loadTasks();
this.drawTasks();
}
loadTasks(){
const stored = (localStorage.getItem("tasks"));
this.tasks = stored ? JSON.parse(stored) : [];
}
createTaskLI(task){
const li = document.createElement('li');
li.className = 'list-group-item d-flex justify-content-between'
li.appendChild(document.createTextNode(task));
const link = document.createElement('a');
link.className='delete-item';
link.innerHTML = '<i class= "fa fa-remove"></i>';
li.appendChild(link);
this.taskList.appendChild(li);
}
drawTasks() {
this.tasks.forEach((task) => {
this.createTaskLI(task)
})
}
clearTasks = () =>{
this.taskList.innerHTML="";
this.tasks=[];
localStorage.clear();
}
addTask = (e) => {
e.preventDefault()
if(taskInput.value === ""){
alert("Add task");
} else {
this.createTaskLI(taskInput.value)
this.tasks.push(taskInput.value);
this.UpdateLocalStorage();
taskInput.value='';
}
}
removeTask = (e) => {
if (e.target.parentElement.classList.contains('delete-item')){
const item = e.target.parentElement.parentElement;
const parent = item.parentElement;
const index = [...parent.children].indexOf(item);
item.remove();
this.tasks.splice(index, 1);
this.UpdateLocalStorage();
}
}
UpdateLocalStorage(){
localStorage.setItem("tasks", JSON.stringify(this.tasks));
}
filterTasks = (e) => {
const text = e.target.value.toLowerCase();
document.querySelectorAll('.list-group-item')
.forEach((task, index) => {
const condition = (text === "" || this.tasks[index].includes(text))
task.classList.add(condition ? "d-flex" : "d-none");
task.classList.remove(condition ? 'd-none': "d-flex");
})
}
}
const tasks = new Tasks(taskList);
loadEventListeners();
function loadEventListeners(){
form.addEventListener('submit', tasks.addTask);
taskList.addEventListener('click', tasks.removeTask );
filter.addEventListener('keyup', tasks.filterTasks);
clearBtn.addEventListener('click', tasks.clearTasks)
}
The function filterTasks adds classes but doesn't remove it. You have to remove classes
if(item.toLowerCase().indexOf(text) != -1){
task.classList.remove("d-none");
task.classList.add("d-block");
// else hide task
} else {
task.classList.remove("d-block");
task.classList.add("d-none");
}
Probably classList.toggle works even better.
I finally made it work
function filterTasks(e){
// Compare betweeen tasks in the ul and the input in the filter
const text = e.target.value.toLowerCase();
// Select all the lis and loop through them
document.querySelectorAll('.list-group-item').forEach(function(task){
const item = task.firstChild.textContent;
console.log(task);
// If the filterInput matches a task, show task
if(item.toLocaleLowerCase().indexOf(text) != -1){
task.className = "list-group-item d-flex justify-content-between";
} else {
// else, hide task
task.classList.remove("d-flex");
task.classList.add("d-none");
}
})
e.preventDefault();
}

How do i create a system where a user can favourite/unfavourite individual courses on a webpage?

I am trying to create a 'favourites' system where the user can click on a star in the top right of a button to add that course to their list of 'favourites'. Here is the HTML for said button (there are 6 of them and all 6 are the same):
<button class="divflexbuttonitem">
<div class="libraryfaviconcontainer">
<i class="libraryfavicon" onclick="toggleFavourite()"></i>
</div>
</button>
And here is my (attempt at) JavaScript for the toggleFavourite() function:
function toggleFavourite() {
console.log("Running toggleFavourite();");
var favicon = document.getElementsByClassName("libraryfavicon");
var faviconCount = favicon.length;
var favArray = new Array();
var favArrayString = favArray.toString();
var i;
for(i = 0; i < faviconCount; i++) {
favArray.push(favicon[i].id);
}
alert(favArray.length);
alert(favArrayString);
let favourite = false;
if (favicon[i].style.backgroundImage == 'url("libraryfavselected.png")') {
favourite = true;
}
else if (favicon[i].style.backgroundImage == 'url("libraryfavunselected.png")') {
favourite = false;
}
if (!favourite) {
favicon[i].style.backgroundImage = 'url("libraryfavselected.png")';
console.log("Added to Favourites");
}
else {
favicon[i].style.backgroundImage = 'url("libraryfavunselected.png")';
console.log("Removed from Favourites");
}
}
I am trying to get all elements with a specific class name, add them to an array, and call them from an array to change the url of the 'favicon' of the specific favicon that was pressed. However, my code does not work whatsoever and i am lost as to how to correctly code it.
There are better ways to structure this type of application, but here is some really simple code to get you started.
You can see that the fav class is toggled on and off when an item is clicked, and then we can get all the current favourites by querying all elements with the fav class.
const toggleFavourite = (event) => {
if (event.target){
const clickTarget = event.target;
clickTarget.classList.toggle('fav')
}
}
//Example use, get all favs and attach the text as a new element
const getFavs = () => {
const favs = document.querySelectorAll('.fav');
const favContainer = document.querySelector('.favs')
favContainer.innerHTML = "";
for( let fav of favs){
let newFav = document.createElement('div');
newFav.textContent = fav.textContent;
favContainer.appendChild(newFav)
}
}
.fav {
color: red;
}
<i class="" onclick="toggleFavourite(event)">1</i>
<i class="" onclick="toggleFavourite(event)">2</i>
<i class="" onclick="toggleFavourite(event)">3</i>
<i class="" onclick="toggleFavourite(event)">4</i>
<i class="" onclick="toggleFavourite(event)">5</i>
<button id="getFavs" onclick="getFavs()">Get Favs</button>
<section class='favs'>
</section>

How can I remove an item from this cart?

I have created this cart by watching lots and lots of tutorials. Now I have come to remove an item from the cart. I would really appreciate if some one could help me out.
//add item to cart
(function(){
const cartbtn = document.querySelectorAll(".add_to_cart_button");
cartbtn.forEach(function(btn) {
btn.addEventListener("click", function(event){
if (event.target.parentElement.classList.contains("add_to_cart_button"))
{
let fullpath = event.target.parentElement.previousElementSibling.children[0].children[0].src;
const item = {};
item.img = fullpath;
let name = event.target.parentElement.previousElementSibling.children[3].children[0].textContent;
item.name = name;
let price = event.target.parentElement.previousElementSibling.children[3].children[1].textContent;
let finalprice = price.slice(1).trim( );
item.price = finalprice;
//console.log(item);
const cartitem = document.createElement('li');
cartitem.classList.add("clearfix");
cartitem.innerHTML =
`
<img src="${item.img}" alt="item1" />
<span class="item-name">${item.name}</span>
<span class="item-price">${item.price}$</span>
<span class="item-quantity"> <a href="#/" />Delete</span>
`;
const cart = document.getElementById("cartitem");
const insert =document.querySelector("insert");
cart.insertBefore(cartitem,insert);
showtotal();
}
});
});
function showtotal(){
const total =[];
const items = document.querySelectorAll(".item-price");
items.forEach(function(item){
total.push(parseFloat(item.textContent));
});
const totalmoney=total.reduce(function(total,item){
total += item;
return total;
},0);
const finalmoney = totalmoney.toFixed(2);
document.getElementById("totalitem").textContent=total.length;
document.getElementById("totalitems").textContent=total.length;
document.querySelector(".main-color-text").textContent = finalmoney ;
}
})();
At the code line,
<a href="#/" />Delete</span> // Also, do not forget to close Anchor Link tags
You can add a class, to these Delete buttons,
Delete
Add an event to your remove-item-from-cart classes when the page is fully loaded and in the event listener, use some JavaScript to delete item from cart by checking event variable.

Categories

Resources