Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 months ago.
Improve this question
I'm programming a cart system to add items and remove them, but I have a problem when removing items (it's not working).
Maybe someone can help me with it, that would be awesome.
gsdsd
gsdsd
gsdsdssd
gsdsd
gsdsd
gdds
gsdsd (without this wouldnt let me post)
gds
gdss
gdsd
Here is the code of the JS (sorry about the Spanish):
class Carrito {
//add product to cart
comprarProducto(e) {
e.preventDefault();
if (e.target.classList.contains('agregar-carrito')) {
const producto = e.target.parentElement.parentElement;
//read product data
this.leerDatosProducto(producto);
}
}
//read product data
leerDatosProducto(producto) {
const infoProducto = {
imagen: producto.querySelector('img').src,
titulo: producto.querySelector('h3').textContent,
precio: producto.querySelector('.precio span').textContent,
id: producto.querySelector('a').getAttribute('data-id'),
cantidad: 1
}
let productosLS;
productosLS = this.obtenerProductosLocalStorage();
productosLS.forEach(function(productoLS) {
if (productoLS.id === infoProducto.id) {
productosLS = productoLS.id;
}
});
this.insertarCarrito(infoProducto);
}
//show the item in cart
insertarCarrito(producto) {
const row = document.createElement('tr');
row.innerHTML = `
<td>
<img src="${producto.imagen}" width=100>
</td>
<td>${producto.titulo}</td>
<td>${producto.precio}</td>
<td>
</td>`;
listaProductos.appendChild(row);
this.guardarProductosLocalStorage(producto);
}
//it is suposed to delete the item visually not in the LocalStorage
eliminarProducto(e) {
e.preventDefault();
let producto, productoID;
if (e.target.classList.contains('borrar-producto')) {
e.target.parentElement.parentElement.remove();
producto = e.target.parentElement.parentElement;
productoID = producto.querySelector('a').getAttribute('data-id');
}
this.eliminarProductoLocalStorage(productoID);
this.calcularTotal();
}
//Empty the cart (not in LS)
vaciarCarrito(e) {
e.preventDefault();
while (listaProductos.firstChild) {
listaProductos.removeChild(listaProductos.firstChild);
}
this.vaciarLocalStorage();
return false;
}
//Saves items in LS
guardarProductosLocalStorage(producto) {
let productos;
//Toma valor de un arreglo con datos del LS
productos = this.obtenerProductosLocalStorage();
//Agregar el producto al carrito
productos.push(producto);
//Agregamos al LS
localStorage.setItem('productos', JSON.stringify(productos));
}
//check if there are items in the LS
obtenerProductosLocalStorage() {
let productoLS;
//Comprobar si hay algo en LS
if (localStorage.getItem('productos') === null) {
productoLS = [];
} else {
productoLS = JSON.parse(localStorage.getItem('productos'));
}
return productoLS;
}
//Shows items in LS
leerLocalStorage() {
let productosLS;
productosLS = this.obtenerProductosLocalStorage();
productosLS.forEach(function(producto) {
//Construir plantilla
const row = document.createElement('tr');
row.innerHTML = `
<td>
<img src="${producto.imagen}" width=100>
</td>
<td>${producto.titulo}</td>
<td>${producto.precio}</td>
<td>
</td>`;
listaProductos.appendChild(row);
});
}
//Deletes an item by id
eliminarProductoLocalStorage(productoID) {
let productosLS;
//Obtenemos el arreglo de productos
productosLS = this.obtenerProductosLocalStorage();
//Comparar el id del producto borrado con LS
productosLS.forEach(function(productoLS, index) {
if (productoLS.id === productoID) {
productosLS.splice(index, 1);
}
});
//Añadimos el arreglo actual al LS
localStorage.setItem('productos', JSON.stringify(productosLS));
}
//clears the localstorage
vaciarLocalStorage() {
localStor);
}
<div class="container">
<div class="header-menu">
<div class="hm-logo">
<a href="#">
<img src="img/jaf.logo.png" alt="">
</a>
</div>
<nav class="hm-menu">
<ul>
<li>Productos</li>
<li>Nosotros</li>
<li>Instagram</li>
<li>Contacto</li>
<li class="nav-item dropdown">
<i class="nav-link dropdown-toggle img-fluid las la-shopping-cart icono" height="100px" width="100px" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
<span id="cant">0</span>
<div id="carrito" class="dropdown-menu" aria-labelledby="navbarCollapse">
<table id="lista-carrito" class="table">
<thead>
<tr>
<th>Imagen</th>
<th>Nombre</th>
<th>Precio</th>
<th></th>
</tr>
</thead>
<tbody></tbody>
</table>
Vaciar Carrito
Procesar Compra
</div>
</li>
</ul>
</nav>
</div>
</div>
<!-- =================================
HEADER MENU Movil
================================= -->
<div class="header-menu-movil">
<button class="cerrar-menu"><i class="fas fa-times"></i></button>
<ul>
<li>Productos</li>
<li>Nosotros</li>
<li>Instagram</li>
<li>Contacto</li>
</ul>
</div>
html of a product:
<div class="product-item">
<div class="p-portada">
<a href="">
<img src="img/1.jpg" alt="">
</a>
<span class="stin stin-new">New</span>
</div>
<div class="p-info">
<a href="">
<h3>Example</h3>
</a>
<div class="precio">
<span>$0</span>
</div>
<a href="" class="hm-btn btn-primary uppercase agregar-carrito" data-id="2" >Add to cart</a>
</div>
</div>
Remove items from cart
Related
i'm quite new to programming and currently and having a problem with a website project. It's a website for a moving company. In this website there is a system of estimation of volume of all the furniture selected by user. I have already the system which allows to select a different number of furniture to move in different categories. Each furniture has a title, image, quantity and a increase an decrease buttons. Additionally, in my JS object each furniture have a volume parameter. I user Handlebars to display all the furniture from my JS objects. I am supposed to do a program to calculate the total volume of all the furniture selected. I have already a code to do this, but the problem is that the value of total volume can be affected by the decrease button of other furniture which is not selected. For example, if i have selected 2 TVs, and one couch, i have a total volume of 4 cubic meters, but this total volume can be decreased if i press the decrease button of washing machine which was not selected initially and still have a quantity = 0.
Here I've selected 2 couches, 1 small bed and 1 large bed by pressing the "+" buttons, and i have the correct value of the total volume..
However, here i managed to decrease the value of total volume to 0 by pressing the "-" of the third furniture.. After first click, it decreased the total volume by 1 and it turns 9, which is logic, but i can press the same button again until the total volume becomes 0, which is not logic because i still have 2 other furniture selected.
Here is my JS code (i have not written all this code by myself):
const source = document.getElementById('templateHB').innerHTML;
const template = Handlebars.compile(source);
const contextSalon = {
lesMeublesSalon: [
{
image: 'images/canape.png',
element: 'Canapé',
quantity: 0,
index: 0,
volume: 3
},
{
image: 'images/canape.png',
element: 'Lit',
quantity: 0,
index: 0,
volume: 4
},
{
image: 'images/bed.svg.png',
element: 'Lit double',
quantity: 0,
index: 0,
volume: 1
}
]
};
const compiledHtmlSalon = template(contextSalon);
const injectionObjetSalon = document.getElementById('meuble-salon');
injectionObjetSalon.innerHTML = compiledHtmlSalon;
const contextChambre = {
lesMeublesChambre: [
{
image: 'images/bed.svg.png',
element: 'Lit double',
quantity: 0,
index: 0,
volume: 1
}
]
}
const compiledHtmlChambre = template(contextChambre);
const injectionObjetChambre = document.getElementById('meuble-chambre');
injectionObjetChambre.innerHTML = compiledHtmlChambre;
const contextCuisine = {
lesMeublesCuisine: [
{
image: 'images/frigo.svg',
element: 'Frigo',
quantity: 0,
index: 0,
volume: 1
}
]
}
const compiledHtmlCuisine = template(contextCuisine);
const injectionObjetCuisine = document.getElementById('meuble-cuisine');
injectionObjetCuisine.innerHTML = compiledHtmlCuisine;
const contextBain = {
lesMeublesBain: [
{
image: 'images/machine-a-laver.svg',
element: 'Machine à laver',
quantity: 0,
index: 0,
volume: 1
}
]
}
const compiledHtmlBain = template(contextBain);
const injectionObjetBain = document.getElementById('meuble-bain');
injectionObjetBain.innerHTML = compiledHtmlBain;
let totalVolume = 0; //use variable globale pour stocker le volume total des meubles
function renderCategory (containerElement, products) {
// initially render our HTML with Handlebars
containerElement.innerHTML = template({
products: products
});
const addOneBtns = containerElement.querySelectorAll("[data-increase]");
const removeOneBtns = containerElement.querySelectorAll("[data-decrease]");
const quantityDisplays = containerElement.querySelectorAll("[data-quantity]");
function renderQuantities () {
quantityDisplays.forEach((quantityDisplay, index) => {
const quantity = products[index].quantity;
quantityDisplay.textContent = String(quantity);
})
};
function updateTotalVolumeDisplay() {
const totalVolumeDisplay = document.getElementById("volume-total");
totalVolumeDisplay.textContent = totalVolume;
}
addOneBtns.forEach(addOneBtn => {
addOneBtn.addEventListener('click', function (event) {
const index = Number(event.target.dataset.increase);
products[index].quantity += 1;
totalVolume += products[index].volume;
renderQuantities();
updateTotalVolumeDisplay();
});
});
removeOneBtns.forEach(removeOneBtn => {
removeOneBtn.addEventListener('click', function (event) {
const index = Number(event.target.dataset.decrease);
products[index].quantity = Math.max(products[index].quantity - 1, 0);
totalVolume -= products[index].volume;
if(totalVolume < 0){
totalVolume = 0;
}
renderQuantities();
updateTotalVolumeDisplay();
});
});
function updateTotalVolumeDisplay() {
const totalVolumeDisplay = document.getElementById("volume-total");
totalVolumeDisplay.textContent = totalVolume;
}
}
const salonContainer = document.getElementById('meuble-salon');
renderCategory(salonContainer, contextSalon.lesMeublesSalon);
const chambreContainer = document.getElementById('meuble-chambre');
renderCategory(chambreContainer, contextChambre.lesMeublesChambre);
const cuisineContainer = document.getElementById('meuble-cuisine');
renderCategory(cuisineContainer, contextCuisine.lesMeublesCuisine);
const bainContainer = document.getElementById('meuble-bain');
renderCategory(bainContainer, contextBain.lesMeublesBain);
And here is my HTML code associated with JS and Handlebars:
<script src="https://cdn.jsdelivr.net/npm/handlebars#latest/dist/handlebars.js"></script>
<script id="templateHB" type="text/x-handlebars-template">
{{#each products}}
<div class="meuble"><img src="{{this.image}}">
<p>{{this.element}}</p>
<div class="plus-moin">
<button data-increase="{{#index}}">+</button>
<p data-quantity="{{#index}}">{{this.quantity}}</p>
<button data-decrease="{{#index}}">-</button>
</div>
</div>
{{/each}}
</script>
</head>
<body>
<header>
<nav>
<a href="#">
<h1 class="logo"><span class="way">WAY</span>TRANSPORT</h1>
</a>
<ul>
<a href="index.html">
<li>ACCUEIL</li>
</a>
<a href="services.html">
<li>SERVICES</li>
</a>
<a href="devis.html">
<li class="active">DEVIS</li>
</a>
<a href="#">
<li>TARIFS</li>
</a>
<a href="contact.html">
<li>CONTACT</li>
</a>
</ul>
</nav>
</header>
<main>
<div class="banniere">
Réaliser un devis en ligne
</div>
<article>
<!-- LES BOUTTONS ONGLET -->
<button class="active" id="btn-salon">SALON</button>
<button id="btn-chambre">CHAMBRE</button>
<button id="btn-cuisine">CUISINE</button>
<button class="last" id="btn-bain">SALLE DE BAIN</button>
<!-- ONGLET POUR LES ELEMENT DU SALON -->
<div id="onglet-salon" class="contenu">
<h2>Seléctionnez vos meuble de salon</h2>
<div id="meuble-salon" class="produit">
</div>
</div>
<!-- ONGLET POUR LES ELEMENT DE CHAMBRE -->
<div id="onglet-chambre" class="contenu" style="display: none;">
<h2>Seléctionnez vos meuble de chambre</h2>
<div id="meuble-chambre" class="produit">
</div>
</div>
<!-- ONGLET POUR LES ELEMENT DE CUISINE -->
<div id="onglet-cuisine" class="contenu" style="display: none;">
<h2>Seléctionnez vos meuble de cuisine</h2>
<div id="meuble-cuisine" class="produit"></div>
</div>
<!-- ONGLET POUR LES ELEMENT DE SALLE DE BAIN -->
<div id="onglet-bain" class="contenu" style="display: none;">
<h2>Seléctionnez vos meuble de bain</h2>
<div id="meuble-bain" class="produit"></div>
</div>
</article>
<section>
<div id="tester" class="selected-total">
<p>Produit seléctionnez :</p>
<div class="selected">
<ul>
<li>Lit double <span class="nombre">x 1</span></li>
<li>Canapé <span class="nombre">x 1</span></li>
<li>Armoir <span class="nombre">x 2</span></li>
</ul>
</div>
<div class="selected">
<ul>
<li>Lit double <span class="nombre">x 1</span></li>
<li>Canapé <span class="nombre">x 1</span></li>
<li>Armoir <span class="nombre">x 2</span></li>
</ul>
</div>
<div class="total">
<p>Total m³ : <span id="volume-total">0</span></p>
<p>Prix : <span id="prix-total">0</span></p>
</div>
</div>
</section>
</main>
I have tried different ways to solve this, i also have asked to ChatGPT but not much success. I'm a student so i don't have any experienced developer to ask for a hint, so i would appreciate any help solving this. Thanks in advance.
The simplest solution would be to exit-out of the remove handler early when the quantity of the associated product is already at 0. The issue currently is that the decrement of totalVolume happens even when the quantity was at 0 when the user pressed the button. (A good enhancement to this app would be to disable the decrement buttons when the quantity is 0)
To exit early we need add only one line of code:
removeOneBtn.addEventListener('click', function (event) {
const index = Number(event.target.dataset.decrease);
// This is the new line that will exit early.
if (products[index].quantity === 0) { return; }
// products[index].quantity = Math.max(products[index].quantity - 1, 0);
// we can remove the Math.max(), since this will never get below 0
products[index].quantity = products[index].quantity - 1;
/* rest of remove handler stays the same */
}
Here is a fiddle for reference.
I'm working on a handlebar's page that show some books. Books can be filtered by title or by author or by city/library.
The page is rendered well the first time, but if I use filters and recall the handler with new parameters, the query is executed well (I can see new books' list) but handlebar doesn't update the page with new data
here is a part of my code:
#Get()
#Render("ciclo/index")
async getCicloBooks(
#Query("ciclo") ciclo,
#Query("codProv") codProvincia,
#Query("comune") idComune,
#Query("title") title,
#Query("author") author
) {
let books = undefined;
let comuni = undefined;
let librariesId = [];
const libraries = [];
let data = {};
this.logger.debug("[getCicloBooks] ciclo: " + ciclo);
const province = await this.cicloService.getProvince();
// Titolo
if (title != undefined) {
this.logger.log(`[getCicloBooks] per ciclo: ${ciclo} e titolo ${title}`);
const query = { ciclo: ciclo, title: title };
books = await this.bookService.getBooksByAdvancedQuery(query);
// TODO considerare che lo stesso libro può essere in più librerie
data = {
pageTitle: `Trovate n librerie che hanno in catalogo ${title}`,
ciclo: `${ciclo}`,
books: books,
libraries: null,
provincie: province,
comuni: comuni,
comune: null,
author: `${author}`,
title: `${title}`,
};
} // Autore
else if (author != undefined) {
this.logger.log(`[getCicloBooks] per ciclo: ${ciclo} e autore ${author}`);
const query = { ciclo: ciclo, author: author };
books = await this.bookService.getBooksByCicloAndAuthor(query);
// TODO considerare che lo stesso libro può essere in più librerie
data = {
pageTitle: `Trovate n librerie con libri di ${author}`,
ciclo: `${ciclo}`,
books: books,
libraries: null,
provincie: province,
comuni: comuni,
comune: null,
author: `${author}`,
title: `${title}`,
};
} // Provincia e comune
else if (idComune != undefined) {
this.logger.log(`[getCicloBooks] ciclo: ${ciclo} id comune ${idComune}`);
const comune = await this.cicloService.getComune(idComune);
const allLibraries = await this.cicloService.getAllLibrariesInCities();
this.logger.log("[getCicloBooks] comune " + JSON.stringify(comune));
librariesId = [];
allLibraries.forEach((library) => {
if (library.comune.id == idComune) {
libraries.push(library);
librariesId.push(library.id);
}
});
this.logger.log("[getCicloBooks] ids " + JSON.stringify(librariesId));
const query = { ciclo: ciclo, id: In(librariesId) };
// join book e libreria oppure find in table book_library_libreria where libreriaID in [libreriaId])
books = await this.bookService.getBooksByAdvancedQuery(query);
// this.logger.log("[getCicloBooks] books " + JSON.stringify(books));
books.forEach((book) => {
const libs = [];
book.library.forEach((l) => {
librariesId.forEach((id) => {
if (l.id == id) {
libs.push(l);
}
});
});
book.library = libs;
});
// this.logger.log("[getCicloBooks] books " + JSON.stringify(books));
data = {
pageTitle: `Tutti i libri disponibili per il ciclo: ${ciclo}`,
ciclo: `${ciclo}`,
books: books,
libraries: allLibraries,
provincie: province,
comuni: comuni,
comune: comune,
author: `${author}`,
title: `${title}`,
};
} else {
books = await this.bookService.getBooksByCiclo(ciclo);
data = {
pageTitle: `Tutti i libri disponibili per il ciclo: ${ciclo}`,
ciclo: `${ciclo}`,
books: books,
libraries: null,
provincie: province,
comuni: comuni,
comune: null,
author: `${author}`,
title: `${title}`,
};
}
this.logger.debug("[getCicloBooks] books: " + JSON.stringify(books));
if (books === undefined) {
data = {
title: "Book Store",
subtitle: `Attualmente non abbiamo nessun libro in catalogo per il ciclo ${ciclo}`,
books: null,
province: province,
comuni: comuni,
};
}
// this.logger.log(books);
return { viewData: data };
}
while this is the template code that doesn't update when new data are given
{{#> app}}
{{#*inline "content"}}
<div class="container">
<div class="row" style="margin-top: 25px;">
<div class="col">
<input id="ciclo" name="ciclo" value="{{viewData.ciclo}}" type="hidden">
<h3 class="fw-bold mt-5 text-center">{{ viewData.pageTitle }}</h3>
<h4 class="fw-bold text-center">Raffina la tua ricerca:</h4>
</div>
</div>
<div class="row mt-auto">
<!-- Navigatore delle Tabs -->
<ul class="nav nav-tabs mb-3" id="ex1" role="tablist">
<li class="nav-item" role="presentation">
<a id="tab1" href="#tabPlace" class="nav-link active" data-mdb-toggle="tab" role="tab" aria-controls="tabPlace"
aria-selected="true">Cerca per provincia e comune</a>
</li>
<li class="nav-item" role="presentation">
<a id="tab2" href="#tabAuthor" class="nav-link" data-mdb-toggle="tab" role="tab" aria-controls="tabAuthor"
aria-selected="false">Cerca per autore</a>
</li>
<li class="nav-item" role="presentation">
<a id="tab3" href="#tabTitle" class="nav-link" data-mdb-toggle="tab" role="tab" aria-controls="tabTitle"
aria-selected="false">Cerca per titolo</a>
</li>
</ul>
<!-- Tabs navs -->
</div>
<!-- Tabs content -->
<div id="search-content-tabs" class="tab-content">
<!-- Cerca per comune -->
<div id="tabPlace" class="tab-pane fade show active" role="tabpanel" aria-labelledby="tab-1">
<div class="container">
<div class="row mt-2" style="border: 1px;">
{{!-- blocco provincia --}}
<div class="col-lg-1 col-xs-1" style="margin-top: 8px;"> Provincia:</div>
{{#with viewData}}
<div class="col-lg-3 col-xs-3">
<select name="provincia" id="provinciaDropdown" class="form-select" aria-label="example">
<option value="">Seleziona la Provincia</option>
{{#each provincie}}
<option value="{{codice}}">{{provincia}}</option>
{{/each}}
</select>
</div>
{{/with}}
{{!-- blocco comune --}}
<div class="col-lg-1" style="margin-top: 8px;"> Comune:</div>
<div class="col-lg-3">
<select id="comuneDropdown" name="comune" class="form-select" aria-label="example">
<option value="">Seleziona il Comune</option>
</select>
</div>
</div> <!-- riga dei select provincia e comune -->
<div class="row mt-4"> <!-- riga bottone cerca -->
<div class="col-2">
**<button id="cityBtn" type="submit" class="btn btn-primary" onclick="onCityClicked(event)">Cerca</button>**
</div>
</div>
</div>
</div>
<!-- Cerca per comune -->
<!-- Cerca per autore -->
<div id="tabAuthor" class="tab-pane fade" role="tabpanel" aria-labelledby="tab-2">
<div class="container">
<div class="row mt-2" style="border: 1px;">
{{!-- blocco autore --}}
{{!-- <div class="col-lg-1" style="margin-top: 8px;"> Autore:</div> --}}
<div class="col-lg-3 form-outline">
<input id="formAuthor" type="text" class="form-control form-control-lg" />
<label class="form-label" for="formAuthor">Cerca per autore del libro</label>
</div>
</div>
<div class="row mt-4"> <!-- riga bottone cerca -->
<div class="col-2">
<button id="authorBtn" type="submit" class="btn btn-primary" onclick="onAuthorClicked(event)">Cerca</button>
</div>
</div>
</div>
</div>
<!-- Cerca per autore -->
<!-- Cerca per Titolo -->
<div id="tabTitle" class="tab-pane fade" role="tabpanel" aria-labelledby="tab-3">
<div class="container">
<div class="row mt-2" style="border: 1px;">
<div class="col-lg-1 form-outline">
<input id="formTitle" type="text" class="form-control form-control-lg" />
<label class="form-label" for="formTitle">Cerca per titolo del libro</label>
</div>
</div>
<div class="row mt-4"> <!-- riga bottone cerca -->
<div class="col-2">
<button id="titleBtn" type="submit" class="btn btn-primary" onclick="onTitleClicked(event)">Cerca</button>
</div>
</div>
</div>
</div>
<!-- Cerca per Titolo -->
</div>
<!-- Tabs content -->
</div>
<!-- Blocco Risultato ricerca -->
{{ log viewData}}
<ul id="booksPreview">
{{#each viewData.books}}
<li style="list-style-type: none">
<div class="container mt-5">
<div class="row bt-2" style="margin-top: 20px;">
<div class="col-lg-3 col-md-2 col-lg-2 mb-2">
<img src="/covers/{{getCoverImage}}" style="height: 320px; width: 230px;">
</div>
<div class="col-lg-7 col-md-8 col-lg-6 mb-2">
<div class="text-md-start text-black text-capitalize fa-2x">{{title}}</div>
<div class="text-md-start">Autore {{getAuthor}}</div>
<div class="text-md-start">Prezzo {{getPrice}} €</div>
<div class="text-md-start">Abstract {{getDescription}}</div>
</div>
<div class="col-lg-2 col-md-2 mb-2">
<div class="bi-text-left ">
Aggiungi al carrello
</div>
</div>
</div>
</div>
</li>
{{/each}}
</ul>
<!-- Blocco Risultato ricerca -->
{{/inline}}
{{/app}}
And this is part of scripts's functions called on serch button click
$(document).ready(function () {
$("#provinciaDropdown").on("change", function () {
console.log(`Selected provincia: ${this.value}`);
var country_id = this.value;
$("#comuneDropdown").html("");
uri = `http://${host}:${port}/admin/getComuni?prov=${country_id}`;
$.ajax({
url: uri,
type: "GET",
success: function (result) {
/* console.log(' Result listaComuni ' + result.viewData.comuni); */
if ($.isArray(result.viewData.comuni)) {
$("#comuneDropdown").html(
'<option value="">Seleziona il Comune</option>'
);
comuni = result.viewData.comuni;
for (i = 0; i < comuni.length; i++) {
str = `<option value="${comuni[i].id}"> ${comuni[i].comune} </option>`;
// console.log(str);
$("#comuneDropdown").append(str);
}
} // isArray
}, // success
});
}); // onChange
$("#comuneDropdown").on("change", function () {
var idComune = this.value;
console.log(`Selected comune with id ${this.value}`);
}); // onChange comuneDropdown
});
function onCityClicked(event) {
event.preventDefault();
var city = document.getElementById("comuneDropdown").value;
var ciclo = document.getElementById("ciclo").value;
console.log(`[onCityClicked] ciclo: ${ciclo} city: ${city} `);
var uri = `http://${host}:${port}/ciclo?ciclo=${ciclo}&comune=${city}`;
console.log(`[onCityClicked] uri: ${uri} `);
$.ajax({
url: uri,
type: "GET",
success: function (result) {
data = result.viewData;
console.log("----- SUCCESS -----");
}, // success
}); // ajax
}
So, from main page I show the book's page (default query is executed and template page is rendered successfully), then when I try to change filters, the book's page is called with choosen filters, the query is excuted well (I check logs) but the template doesn't update. I got the previous page
I added to original code the <ul id=".."> <li></li> </ul> tags, trying to intercept at runtime some action on id and clean the book's list before the new render, but I wasn't able to do
Can someone help me?
Thanks
In my website there are some films that i get from firebase. The scores of the movies are between 0 and 100. I already got all the movies in my website. I also want to display them in descending order.(for ex. top 5 rated movies) How can i achieve this? Thanks for your answers.
const app = initializeApp(firebaseConfig);
const db = getDatabase(app);
const auth = getAuth(app);
const firebaseRef= ref(getDatabase());
var body = document.getElementById('movies');
var body2 = document.getElementById('series');
function AddItemsToTable(name, score, img, id) {
var movies = `<div class="content"><img src="${img}" ><p>${name}</p> <p> <i class="fa fa-star checked" id="star${id}"></i> <a class="scoretxt">${score}%</a> </p> </div>`;
body.innerHTML+=movies;
}
function AddItemsToTable2(name, score, img, id) {
var series = `<div class="content"><img src="${img}" ><p>${name}</p> <p> <i class="fa fa-star checked" id="star2${id}"></i> <a class="scoretxt">${score}%</a> </p> </div>`;
body2.innerHTML += series;
}
//*******************************I got the movies************************************************
function AddAllItemsToTable(TheMovies){
var counter=0;
TheMovies.forEach(element => {
if (counter===6) {
return;
}
AddItemsToTable(element.movieName, element.movieScore, element.movieImage, element.movieId);
counter++;
});
}
//************************I got tv series*********************************************
function AddAllItemsToTable2(TheSeries){
var counter=0;
TheSeries.forEach(element => {
if (counter===6) {
return;
}
AddItemsToTable2(element.seriesName, element.seriesScore, element.seriesImage, element.seriesId);
counter++;
});
}
function AddAllItemsToTable3(TheMovies){
var counter=0;
TheMovies.forEach(element => {
if (counter===6) {
return;
}
AddItemsToTable3(element.movieName, element.movieScore, element.movieImage, element.movieId);
counter++;
});
}
function getAllDataOnce(){
const dbRef=ref(db);
get(child(dbRef,"Movies"))
.then((snapshot)=>{
var movies=[];
snapshot.forEach(childSnapshot => {
movies.push(childSnapshot.val())
});
AddAllItemsToTable(movies);
});
}
function getAllDataOnce2(){
const dbRef=ref(db);
get(child(dbRef,"Series"))
.then((snapshot)=>{
var series=[];
snapshot.forEach(childSnapshot => {
series.push(childSnapshot.val())
});
AddAllItemsToTable2(series);
});
}
window.onload = (event) => {
getAllDataOnce();
getAllDataOnce2();
};
<div class="grid-container">
<header class="header">
<div class="solheader">
<img src="img/sonlogo3.png" alt="logo">
<img src="img/logosmall.png" alt="logo" style="width:60px;height:48px;margin:5px;">
</div>
<div class="ortaheader">
<input type="text" placeholder="Movies or TV series.." class="searchbox"><i class="fa fa-search arama"></i> </input>
<ul>
<li class="categories">Categories <i class="fa fa-caret-down" style="font-size:16px;"> </i>
<ul class="dropdown">
<li>TV Series</li>
<li>Movies</li>
</ul>
</li>
</ul>
</div>
<div class="menu sagheader">
<ul>
<li>
<button class="ikon dropdown-toggle" type="button" data-toggle="dropdown"><i class="far fa-user"></i> </button>
<ul class="dropdown-menu">
<li class="accountname"><b><script>document.write(document.cookie.substring(5))</script></b></li>
<li class="login"><i class="fa fa-sign-in-alt" style="color:red;"></i> Login </li>
<li class="signup"><i class="fa fa-user-plus" style="color:red;"></i> Sign up </li>
<li class="logout"><a onclick="deletecookie()" style="cursor:pointer;"><i class="fas fa-door-open" style="color:red;"></i> Log out</a></li>
</ul>
</li>
</ul>
</div>
</header>
<div class="body" id="body">
<div class="baslik">Movies</div>
<div class="baslik2">See all</div>
<div id="movies">
</div>
<div class="baslik">Series</div>
<div class="baslik2">See all</div>
<div id="series">
</div>
<div class="baslik">Top Rated Movies</div>
<div class="baslik2">See all</div>
<div id="toprated">
</div>
</div>
<div class="footer">
<div class="">
<img src="img/sonlogo3.png" alt="logo">
<ul>
<li>Help</li>
<li>About</li>
<li>Contact</li>
<li>Terms and Policies</li>
</ul><br><br>
<ul>
<li>© 2021 Cinemeter</li>
<li class="destroy">|</li>
<li>All rights reserved.</li>
</ul>
</div>
</div>
</div>
Firebase Database
This is my website
While Firebase can order results, the results are always ascending. If you want to show them in descending order, you'll have to reverse them in your application code.
Something like this:
const query = query(child(dbRef,"Movies"), orderByChild("movieScore"));
get(query).then((snapshot)=>{
var movies=[];
snapshot.forEach(childSnapshot => {
movies.push(childSnapshot.val())
});
movies.reverse
});
If you want to get the top scores, you can use limitToLast in the query too:
const query = query(child(dbRef,"Movies"), orderByChild("movieScore"), limitToLast(5));
Also see the Firebase documentation on ordering and filtering data and limiting the number of results.
A few notes on your data structure:
Using sequential numeric keys for you nodes is an anti-pattern in Firebase, and it is typically better to use push keys. Also see Best Practices: Arrays in Firebase.
You're storing the score as a string, which is bound to lead to problems as strings are sorted lexicographically. I recommend converting your data to store the scores as numbers (so without " quotes around them).
const setupProducts = (data) => {
if (data.length) {
let html = '';
data.forEach(doc => {
const product = doc.data();
const li = `
<li>
<div class="collapsible-header grey lighten-4"> ${product.title} </div>
<div class="collapsible-header grey lighten-4"> ${doc.id} </div>
<div class="collapsible-body white"> ${product.content}
<a href="" class="secondary-content">
<a class="btn orange modal-trigger" >Get ID</a>
</a>
</li>
`;
html += li;
});
productList.innerHTML = html
} else {
productList.innerHTML = '<h5 class="center-align">Login to view products</h5>';
}
};
My idea is that I want to get the ID by clicking on the document and then but the product.title in db.collection('activeWorks').doc(doc.id or product.id (I don't know what's right...)).set. I have no idea how to do this, please help
Maybe do something like this: set the id tag of each <li> element to the doc id from Firestore, then attach an onclick event trigger
const setupProducts = (data) => {
if (data.length) {
let html = '';
productList.innerHTML = ''
data.forEach(doc => {
const product = doc.data();
const li = `
<li id="${doc.id}">
<div class="collapsible-header grey lighten-4"> ${product.title} </div>
<div class="collapsible-header grey lighten-4"> ${doc.id} </div>
<div class="collapsible-body white"> ${product.content}
<a href="" class="secondary-content">
<a class="btn orange modal-trigger" >Get ID</a>
</a>
</li>
`;
html += li;
productList.innerHTML += html
document.getElementById(doc.id).onclick = () => {
// do firestore stuff here
// db.collection('activeWorks').doc(doc.id).set(your_data)
}
});
} else {
productList.innerHTML = '<h5 class="center-align">Login to view products</h5>';
}
};
If I misunderstood your question I'm sorry
First of all, I list the e-mail from coming ActionResult in the first cycle.
I want to see the details by clicking on the listed data. I open with the help of jQuery details. The problem arises in this section. in this case ,the opening of the details of the first mail in the detail of each row.
There are details of the message in the second loop.To connect to the two loops in a guid font was coming. (MessageId).
id=messageId (guid type)
mailing list
<div class="message-list-container">
<div class="message-list" id="message-list">
#foreach (var item in Model)
{
<div id="#item.MessageId" class="message-item">
<span class="sender" title="#item.From">
#item.From
</span>
<span class="time">#mvcHelper.saatAyarla(item.Date)</span>
#if(item.Attachments.Any())
{
<span class="attachment">
<i class="ace-icon fa fa-paperclip"></i>
</span>
}
<span class="summary">
<span class="text">
#item.Subject
</span>
</span>
</div>
}
</div>
</div>
mailing details
<!--Messsage details-->
#foreach (var item in Model)
{
<!-- <div class="hide message-content" id="id-message-content">-->
<div class="hide message-content" id="#item.MessageId">
<div class="message-header clearfix">
<div class="pull-left">
<span class="blue bigger-125"> #item.Subject </span>
<div class="space-4"></div>
<i class="ace-icon fa fa-star orange2"></i>
<img class="middle" alt="John's Avatar" src="/Areas/admin/Content/images/avatars/avatar.png" width="32" />
#item.From
<i class="ace-icon fa fa-clock-o bigger-110 orange middle"></i>
<span class="time grey">#mvcHelper.saatGoster(item.Date)</span>
</div>
</div>
<div class="hr hr-double"></div>
<div class="message-body">
<p>
#item.TextBody
</p>
</div>
<div class="hr hr-double"></div>
<!--Eklenti paneli-->
<div class="message-attachment clearfix">
#if (item.Attachments.Any())
{
<div class="attachment-title">
<span class="blue bolder bigger-110">Eklentiler</span>
<span class="grey">(#item.Attachments.Count() Dosya)</span>
</div>
<ul class="attachment-list pull-left list-unstyled">
#foreach (var attachment in item.Attachments)
{
<li>
<a href="#" class="attached-file">
<i class="ace-icon fa fa-file-o bigger-110"></i>
<span class="attached-name">#mvcHelper.getAttachmentName(attachment.ToString())</span>
</a>
<span class="action-buttons">
<a href="#">
<i class="ace-icon fa fa-download bigger-125 blue"></i>
</a>
<a href="#">
<i class="ace-icon fa fa-trash-o bigger-125 red"></i>
</a>
</span>
</li>
}
</ul>
}
</div>
</div><!-- /.message-content -->
}
<!--Eklenti paneli Son-->
<!--message details end-->
loop connecting two points.
first foreach = <div id="#item.MessageId" class="message-item">
//Places where the problem is. They need to be connected.
second foreach = <!-- <div class="hide message-content" id="id-message-content">-->
<div class="hide message-content" id="#item.MessageId">
var content = message.find('.message-content:last').html($('#id-message-content').html());
jQuery code
$('.message-list .message-item .text').on('click', function () {
var message = $(this).closest('.message-item');
//if message is open, then close it
if (message.hasClass('message-inline-open')) {
message.removeClass('message-inline-open').find('.message-content').remove();
return;
}
$('.message-container').append('<div class="message-loading-overlay"><i class="fa-spin ace-icon fa fa-spinner orange2 bigger-160"></i></div>');
setTimeout(function () {
$('.message-container').find('.message-loading-overlay').remove();
message
.addClass('message-inline-open')
.append('<div class="message-content" />');
var content = message.find('.message-content:last').html($('#id-message-content').html());
//remove scrollbar elements
content.find('.scroll-track').remove();
content.find('.scroll-content').children().unwrap();
content.find('.message-body').ace_scroll({
size: 150,
mouseWheelLock: true,
styleClass: 'scroll-visible'
});
}, 500 + parseInt(Math.random() * 500));
});
Your first problem is that you are creating multiple elements with identical id properties. This makes your HTML invalid.
Here is the problem code:
#foreach (var item in Model)
{
<div id="#item.MessageId" class="message-item">
...
#foreach (var item in Model)
{
<div class="hide message-content" id="#item.MessageId">
...
For each message in your model, this will create 2 <div> elements whose id has the value of the #item.MessageID variable. The second of these is and illegal element because it has the same ID as an earlier element. You will need to make these <div>s have unique IDs.
The second problem is:
When you run
var content = message.find('.message-content:last').html($('#id-message-content').html());
this part:
$('#id-message-content').html()
cannot find anything because there is no element whose id is "id-message-content". Also every time you open the message, you are appending another "message-content" div into the message-item. This is not necessary.
To fix these issues, you can change the code like this:
First loop:
#foreach (var item in Model)
{
<div data-messageid="#item.MessageId" class="message-item">
...
<span class="summary">
<span class="text">
#item.Subject
</span>
</span>
<div class="message-content" hidden></div>
...
Second loop:
#foreach (var item in Model)
{
<div class="hide message-content" id="message-content-#item.MessageId">
...
jQuery:
$('.message-list .message-item .text').on('click', function () {
var message = $(this).parents('.message-item');
//if message is open, then close it
if (message.hasClass('message-inline-open')) {
message.removeClass('message-inline-open').find('.message-content').hide();
return;
}
$('.message-container').append('<div class="message-loading-overlay"><i class="fa-spin ace-icon fa fa-spinner orange2 bigger-160"></i></div>');
setTimeout(function () {
$('.message-container').find('.message-loading-overlay').remove();
message.addClass('message-inline-open');
var content = message.find(".message-content");
content.show();
content.html($('#message-content-' + message.data("messageid")).html());
//remove scrollbar elements
content.find('.scroll-track').remove();
content.find('.scroll-content').children().unwrap();
content.find('.message-body').ace_scroll({
size: 150,
mouseWheelLock: true,
styleClass: 'scroll-visible'
});
}, 500 + parseInt(Math.random() * 500));
});
Solved
public static class mvcHelper
{
public static string variableReplace(string id)
{
string yazi = null;
if (id != null)
{
yazi = id.Replace('#', 'a').ToString();
}
else
{
yazi = id;
}
return yazi;
}
}
<div data-messageid="#mvcHelper.variableReplace(item.MessageId)" class="message-item">
<div class="hide message-content" id="message-content-#mvcHelper.variableReplace(item.MessageId)">