Toggle between icons depending on number of child elements - javascript

I figured out how to change the icon when more elements are added, but I can't figure out to how return it to the original icon while the cart is empty.
Javascript
let cartItems = document.getElementsByClassName('cart-container')[0];
if (cartItems.childElementCount <= 1) {
let cartBtn = document.getElementsByClassName('cart-btn')[0]
cartBtn.innerHTML = `
<i class="fa fa-cart-plus cart-btn text-danger"></i>`
}
HTML
<h1 class="cart-btn">
<i class="fa fa-shopping-cart"></i>
</h1>
<div class="container cart-container d-flex flex-column pb-5">
<div class="row mt-5 mb-4">
<div class="col">
</div>
</div>
</div>

I have a shopping cart button on a navbar that I need to switch between different states depending on if the cart is empty or not. I figured out how to change it to one state when an item was added to the cart, but couldn't figure out how to change it back to the original state when I emptied the cart. However, I used this code to accomplish that task.
Javascript
function checkNavBtn() {
let cartItems = document.getElementsByClassName('cart-container')[0];
let cartBtn = document.getElementsByClassName('fa-shopping-cart')[0];
if (cartItems.childElementCount >= 0) {
cartBtn.classList.add('fa-cart-plus', 'text-danger');
} if (cartItems.childElementCount <= 0) {
cartBtn.classList.remove('fa-cart-plus', 'text-danger');
}
}

Related

Change style of an element in a forEach loop

Goal: Change style of an element in a forEach loop
Issue: Style not being applied
In my loop, if I console.log(element), I do get the right list of filtered elements.
Running this works, but I want my function to modify every element that match my filter:
let contentPreview = document.querySelectorAll('.o_last_message_preview');
contentPreview[0].style.color = 'yellow'
All elements are correctly assigned.
function changeNotificationColor() {
// Notification button that opens list of notifications
let notifyButton = document.querySelector('.dropdown-toggle.o-no-caret[title="Conversations"]');
notifyButton.addEventListener('click', function () {
// List of notifications - each notification is contained in a .o_last_message_preview class
let contentPreview = document.querySelectorAll('.o_last_message_preview');
contentPreview.forEach(function (element) { if (element.innerText.includes('Marine')) {element.style.color = 'yellow'}})
})
}
changeNotificationColor();
HTML Notifications Dropdown button:
<a class="dropdown-toggle o-no-caret" data-toggle="dropdown" data-display="static" aria-expanded="true" title="Conversations" href="#" role="button">
<i class="o_mail_messaging_menu_icon fa fa-comments" role="img" aria-label="Messages"></i> <span class="o_notification_counter badge badge-pill">366</span>
</a>
HTML template of a notification node (each notification creates one of these nodes):
<div class="o_preview_info">
<div class="o_preview_title">
<span class="o_preview_name">
You have been assigned to Backorder xx
</span>
<span class="o_preview_counter">
(1)
</span>
<span class="o_last_message_date ml-auto mr-2"> 3 minutes ago </span>
</div>
<div class="o_last_message_preview">
Marine
</div>
<span title="Mark as Read" class="o_discuss_icon o_mail_preview_mark_as_read fa fa-check"></span>
</div>
I don't know what your issue is, but it's not in the code that you showed; this works fine:
let contentPreview = document.querySelectorAll('.o_last_message_preview');
contentPreview.forEach(function (element) { if (element.innerText.includes('Marine')) {element.style.color = 'yellow'}})
<div class="o_last_message_preview">This contains Marine</div>
<div class="o_last_message_preview">This does not</div>
<div class="o_other_message_preview">This has a different class</div>

adding quantity through buttons to a shopping cart item - Javascript

I am working on a personal project, just practicing on my own and getting to know and familiarized with the language.I am trying to learn by doing so I am creating a shopping cart and I came across a situation that I can not find a proper solution.
I have a list on my shopping cart already rendered of n items. When I 'click' on a plus button to add quantity to an item, it only adds to the quantity to the item that is first on the list and the 'price' of the second item.
Thank you in advance!
function renderCarrito(){
// carritoEl.innerHTML = "";
while(carritoEl.firstChild){
carritoEl.removeChild(carritoEl.firstChild)
};
carrito.forEach((item) =>{
carritoEl.innerHTML += `
<li class="buyItem">
<img src=${item.image}>
<div class="productCartInfo">
<h5 class="prdTitle">${item.title}</h5>
<h6>${item.price}</h6>
<div class="qnty">
<div>
<button class="mbtn">-</button>
<span class="countOfProduct">${item.cantidad}</span>
<button class="pbtn">+</button>
</div>
<div><i class="fas fa-times-circle dltProduct" data-id="${item.id}"></i></div>
</div>
</div>
</li>
`
const plusBtn = document.querySelectorAll('.pbtn');
const minusBtn = document.querySelectorAll('.mbtn');
const count = document.querySelector('.countOfProduct');
plusBtn.forEach(pbtn =>{
pbtn.addEventListener('click', () => {
item.cantidad++;
count.innerHTML = item.cantidad;
carritoSumaTotal();
})});
})
carritoSumaTotal();
}
``

How to create dynamicaly a card in NuxtJS

I am new at NuxtJS and I was wondering how to create a v-card through a v-dialog box.
For example, I create an add button then a v-dialog opens then I fill up the form then I "submit" and finally a v-card with what I filled before is created.
Thank you for your help.
I think this will solve you'r problem:
In you'r script:
data() {
return {
formInfo: {
title: '',
description: ''
}
}
},
methods: {
onSubmit() {
let container = document.getElementById('card-container');
this.formInfo.forEach((result, i) => {
// Create card element
let card = document.createElement('v-card');
card.classList = 'you'r classes';
// Construct card content
const content = `
<div class="card">
<div class="card-header" id="heading-{i}">
<h5 class="mb-0">
<button class="btn btn-link">
</button>
</h5>
</div>
<div id="collapse-{i}" class="collapse show">
<div class="card-body">
<h5>{result.title}</h5>
<p>{result.description}</p>
</div>
</div>
</div>
`;
// Append newly created card element to the container
container.innerHTML += content;
})
}
}

Items in an array disappear mysteriously

So I'm currently doing a Calorie Counter project that consists on giving the user the option to firstly, add items with the respective name and number of calories, remove items or update them when clicking on an edit icon next to the item, and finally removing all items at once.
The UI will basically display all the items that the user has added (including the name and the number of calories), where each item will have an edit icon next to it, and if the icon is clicked, it will give the user the option to edit them and delete them.
I still haven't gotten to the edit part because I'm currently stuck in the delete part.
Let's say I have 3 items in the list, when I click on the edit button and then delete, everything works out fine, the html element is deleted and it looks good. If I repeat the process one more time it still works, but when I repeat the process one last time, the problem happens.
For some reason, when I hit the edit button nothing happens, I've checked and apparently the item array is completely empty, even though I only deleted 2 out of the 3 items.
I've tried everything and I've been completely stuck for 3 days straight.
// Item Controller
const ItemController = function() {
// Hard coded items
data = [{
name: "Hamburguer",
id: 0,
calories: 1000
},
{
name: "Pasta",
id: 1,
calories: 700
},
{
name: "Apple",
id: 2,
calories: 70
}
]
return {
getItems: function() {
return data;
},
deleteAllItems: function() {
data.items = [];
UIController().clearItems();
},
getTotalCalories: function() {
totalCalories = 0;
this.getItems().forEach(item => {
totalCalories += parseInt(item.calories)
});
UIController().changeToTotalCalories(totalCalories);
},
removeSingleItem: function(item, li) {
// Getting the index of the item
indexItem = items.getItems().indexOf(item);
// Deleting item from array
items.getItems().splice(indexItem, 1);
// Deleting li item from UI
li.remove();
console.log(items.getItems());
}
}
};
const items = ItemController();
// UI controller
const UIController = function() {
return {
displayItems: function(itemsPresented) {
itemsPresented.forEach(function(item) {
itemList = document.getElementById("item-list");
itemList.innerHTML += `
<li class="collection-item" id="${item.id}">
<strong>${item.name}: </strong><em>${item.calories} calories</em>
<a href="#" class="secondary-content">
<i class="edit-item fa fa-pencil">
</i>
</a>
</li>
`;
})
},
clearItems: function() {
itemList = document.getElementById("item-list");
itemList.innerHTML = "";
items.getTotalCalories();
},
changeToTotalCalories: function(totalCalories) {
document.querySelector(".total-calories").textContent = totalCalories;
},
}
}
const uiCtrl = UIController();
// So when the page loads, the hard coded items can be represented
uiCtrl.displayItems(items.getItems());
// To delete all the items at once
clearAllBtn = document.querySelector(".clear-btn");
clearAllBtn.addEventListener("click", (e) => {
items.deleteItems();
e.preventDefault();
})
// Getting the li element (The one that has all the hard-coded items)
itemList = document.getElementById("item-list");
itemList.addEventListener("click", e => {
// Checking if the user is clicking the Edit Icon
if (e.target.classList.contains("edit-item")) {
items.getItems().forEach(item => {
li = e.target.parentElement.parentElement;
// Getting the item that has the edit icon that the user clicked
if (item.id === parseInt(e.target.parentElement.parentElement.id)) {
// Putting the name and the calories of the item that is being edited in the input fields
document.getElementById("item-name").value = item.name;
document.getElementById("item-calories").value = item.calories;
// Changing the buttons so when the user edits an item, they have the options Update and Delete
document.querySelector(".add-btn").style.display = "none";
document.querySelector(".update-btn").style.display = "block";
document.querySelector(".delete-btn").style.display = "block";
document.querySelector(".back-btn").style.display = "none";
// If the user clicks the delete button
document.querySelector(".delete-btn").addEventListener("click", e => {
// Changing all the buttons back to normal
document.querySelector(".add-btn").style.display = "block";
document.querySelector(".update-btn").style.display = "none";
document.querySelector(".delete-btn").style.display = "none";
document.querySelector(".back-btn").style.display = "block";
// Clearing out the input fields
document.getElementById("item-name").value = "";
document.getElementById("item-calories").value = "";
// Deleting item
items.removeSingleItem(item, li);
// Updating the calories
items.getTotalCalories();
e.preventDefault();
});
}
});
}
})
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<nav>
<div class="nav-wrapper blue">
<div class="container">
<a href="#" class="brand-logo center">
Tracalorie
</a>
<ul class="right">
<li>
<a href="#" class="clear-btn btn blue lighten-3">
Clear All
</a>
</li>
</ul>
</div>
</div>
</nav>
<br>
<div class="container">
<!-- Form Card -->
<div class="card">
<div class="card-content">
<span class="card-title">
Add Meal / Food Item
</span>
<form class="col">
<div class="row">
<div class="input-field col s6">
<input type="text" id="item-name" placeholder="Add item">
<label for="item-name">Meal</label>
</div>
<div class="input-field col s6">
<input type="text" id="item-calories" placeholder="Add calories">
<label for="item-calories">Calories</label>
</div>
<button class="add-btn btn blue darken-3"><i class="fa fa-plus"></i>
Add Meal</button>
<button style="display: none;" class="update-btn btn orange" display=><i class="fa fa-pencil-square-o"></i>
Update Meal</button>
<button style="display: none;" class="delete-btn btn red"><i class="fa fa-remove"></i>
Delete Meal</button>
<button class="back-btn btn grey pull-right"><i class="fa fa-chevron-circle-left"></i>
Back</button>
</div>
</form>
</div>
</div>
<!-- Calorie Count -->
<h3 class="center-align">Total Calories: <span class="total-calories">
0
</span></h3>
<!-- Item list -->
<ul id="item-list" class="collection">
</ul>
</div>
It seems like you add an eventListener to the delete button every single time a user clicks on the edit pencil. You never remove these eventListeners. So when the first edit is done, there is one delete event and one items gets deleted. The next time a user clicks on the edit button, a second event gets added to the same html element, thus two items gets deleted (both events will trigger one after the other). This becomes apparent when your hardcoded list would contain 10 items, you would see 1,2,3 and lastly 4 items disappear. I suggest you look into resetting/removing eventlisteners.

Remove a specific item (index) method

So I have a list of phones that I add new input lines to, and I have a remove method set, for each individual row.
This is the template:
<div formArrayName="mobiles">
<div *ngFor="let mobile of mobiles.controls; let i = index" [formGroupName]="i">
<div class="d-flex align-items-center" [class.pt-4]="i > 0">
<input class="input" type="text" formControlName="phone">
<a class="input-remove ml-3">
<i class="icon icon-trash h3 text-primary" (click)="removeMobile()"></i>
</a>
</div>
</div>
</div>
And these are my methods that are within the respective component:
get mobiles(): FormArray {
return this.form.get("mobiles") as FormArray;
}
get stations(): FormArray {
return this.form.get("stations") as FormArray;
}
addMobile() {
this.mobiles.push(this.fb.group(new PhoneFormGroup()));
}
addStation() {
this.stations.push(this.fb.group(new PhoneFormGroup()));
}
removeMobile(index: number) {
this.mobiles.removeAt(index);
if (this.mobiles.controls.length == 0) {
this.addMobile();
}
}
removeStation(index: number) {
this.stations.removeAt(index);
if (this.mobiles.controls.length == 0) {
this.addStation();
}
}
The problem here is, that whenever I click on the delete button, it deletes the first item(index[0]) from the list, and I want it to delete the specific item I have selected for deletion.
What am I doing wrong?
You don't pass index param to removeMobile function from your HTML template.
<i class="icon icon-trash h3 text-primary" (click)="removeMobile(i)"></i>

Categories

Resources