问题
I'm having trouble with my homework assignment. I need to create a Shopping Cart using Javascript, HTML5 and JQuery, and it must collect all the items from the shop inside an Array. I think I pretty much solved it, but I cannot figure out how to add multiple of the same item to the cart without it creating 2 different objects on the cart list.
Also, if possible, I would like to be able to change the amount of certain items directly from the cart, with the option of upgrading or downgrading the quantity.
This is what I've got going on at the moment:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<script>
window.onload = function () {
// Variables
var baseDeDatos = [
{
id: 1,
nombre: 'Jean Mom',
precio: 1399
},
{
id: 2,
nombre: 'Pant Ren',
precio: 990
},
{
id: 3,
nombre: 'Buzo Largo Hailey',
precio: 948
},
{
id: 4,
nombre: 'Cycle Short',
precio: 550
},
{
id: 5,
nombre: 'Top Cellie',
precio: 590
},
{
id: 6,
nombre: 'Jacket Denim Ray',
precio: 2890
},
{
id: 7,
nombre: 'Cinto Vice',
precio: 499
},
{
id: 8,
nombre: 'Top Caro',
precio: 499
},
{
id: 9,
nombre: 'Bra Top Regan',
precio: 590
},
{
id: 10,
nombre: 'Sweater Polly',
precio: 1399
},
{
id: 11,
nombre: 'Camisa June',
precio: 799
},
{
id: 12,
nombre: 'Pant Amy',
precio: 1299
},
{
id: 13,
nombre: 'Top Tai',
precio: 648
},
{
id: 14,
nombre: 'Tapado Judy',
precio: 3290
},
{
id: 15,
nombre: 'Mini Corderoy Lou',
precio: 1090
}
]
var $items = document.querySelector('#items');
var carrito = [];
var total = 0;
var $carrito = document.querySelector('#carrito');
var $total = document.querySelector('#total');
// Funciones
function renderItems () {
for (var info of baseDeDatos) {
// Estructura
var miNodo = document.createElement('div');
miNodo.classList.add('card', 'col-sm-4');
// Body
var miNodoCardBody = document.createElement('div');
miNodoCardBody.classList.add('card-body');
// Titulo
var miNodoTitle = document.createElement('h5');
miNodoTitle.classList.add('card-title');
miNodoTitle.textContent = info['nombre'];
// Precio
var miNodoPrecio = document.createElement('p');
miNodoPrecio.classList.add('card-text');
miNodoPrecio.textContent = '$' +info['precio'];
// Boton
var miNodoBoton = document.createElement('button');
miNodoBoton.classList.add('btn', 'btn-primary');
miNodoBoton.textContent = '+';
miNodoBoton.setAttribute('marcador', info['id']);
miNodoBoton.addEventListener('click', anyadirCarrito);
// Insertamos
miNodoCardBody.appendChild(miNodoTitle);
miNodoCardBody.appendChild(miNodoPrecio);
miNodoCardBody.appendChild(miNodoBoton);
miNodo.appendChild(miNodoCardBody);
$items.appendChild(miNodo);
}
}
function anyadirCarrito () {
// Anyadimos el Nodo a nuestro carrito
carrito.push(this.getAttribute('marcador'))
// Calculo el total
calcularTotal();
// Renderizamos el carrito
renderizarCarrito();
}
function renderizarCarrito () {
// Vaciamos todo el html
$carrito.textContent = '';
// Generamos los Nodos a partir de carrito
carrito.forEach(function (item, indice) {
// Obtenemos el item que necesitamos de la variable base de datos
var miItem = baseDeDatos.filter(function(itemBaseDatos) {
return itemBaseDatos['id'] == item;
});
// Creamos el nodo del item del carrito
var miNodo = document.createElement('li');
miNodo.classList.add('list-group-item', 'text-right');
miNodo.textContent = `${miItem[0]['nombre']} - $${miItem[0]['precio']}`;
// Boton de borrar
var miBoton = document.createElement('button');
miBoton.classList.add('btn', 'btn-danger', 'mx-5');
miBoton.textContent = 'X';
miBoton.setAttribute('posicion', indice);
miBoton.addEventListener('click', borrarItemCarrito);
// Mezclamos nodos
miNodo.appendChild(miBoton);
$carrito.appendChild(miNodo);
})
}
function borrarItemCarrito () {
// Obtenemos la posicion que hay en el boton pulsado
var posicion = this.getAttribute('posicion');
// Borramos la posicion que nos interesa
carrito.splice(posicion, 1);
// volvemos a renderizar
renderizarCarrito();
// Calculamos de nuevo el precio
calcularTotal();
}
function calcularTotal () {
// Limpiamos precio anterior
total = 0;
// Recorremos el array del carrito
for (var item of carrito) {
// De cada elemento obtenemos su precio
var miItem = baseDeDatos.filter(function(itemBaseDatos) {
return itemBaseDatos['id'] == item;
});
total = total + miItem[0]['precio'];
}
// Formateamos el total para que solo tenga dos decimales
var totalDosDecimales = total.toFixed(2);
// Renderizamos el precio en el HTML
$total.textContent = totalDosDecimales;
}
// Eventos
// Inicio
renderItems();
}
</script>
</head>
<body>
<div class="container">
<div class="row">
<!-- Elementos generados a partir del JSON -->
<main id="items" class="col-sm-8 row"></main>
<!-- Carrito -->
<aside class="col-sm-4">
<h2>Carrito</h2>
<!-- Elementos del carrito -->
<ul id="carrito" class="list-group"></ul>
<hr>
<!-- Precio total -->
<p class="text-right">Total: <span id="total"></span>$</p>
</aside>
</div>
</div>
</body>
</html>
Oh, and I don't really know how to implement jQuery into what I already have in my code, so any suggestions would be highly helpful!
回答1:
you have unique id right?so,add item before judge item.id is or not already in cart
回答2:
A few quick jQuery pointers:
- You are missing the jQuery and bootstrap javascript files. You only included the bootstrap CSS file - so you don't actually have jQuery in your page, or most of Bootstrap (some of the bootstrap will work, which will be confusing). To solve: In your head, replace this one line:
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
with these four lines:
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
- jQuery Tip: Replace this:
window.onload = function () {
with
$(document).ready(function(){
- jQuery Tip: Replace this:
document.querySelector
with this:$
Example FROM: document.querySelector('#items');
TO: $('#items');
- Use jQuery
.on()
- When the page is first created ("rendered"), javascript is run immediately. If some js code runs that binds an event listener to an element before the element is created, that event listener will not be attached! We usedocument.ready
to solve that.document.ready
says, "delay running all the code inside this function (that is, inside the document.ready function code block) until all the HTML elements have been rendered (created and placed on the page)".
But a similar problem is how to attach an event listener to an element that gets added to the page LATER ON -- and jQuery .on()
is how you do that. Basically, you add a jQuery .on()
function block right off the start, and later on, when one of those elements is added to the DOM, the event handler will be attached on-the-fly. This is reason #47 why we love jQuery.
- As a convention/tradition (not a rule), we generally prefix variables-that-are-jQuery-objects with the
$
. In variable names, the$
doesn't do anything, it just reminds us that this is a jQuery object and we can use jQuery methods/properties on it directly.
The purpose of StackOverflow is to assist, not to write-it-for-you. So, in that spirit, I have turned your js into jQuery. If you look at it carefully, you will see that it is exactly what you wrote - just switched over to jQuery.
It is now your job to make the code work. Not everything that I did is finished/working. Every line still needs to be reviewed/tested/tweaked. But at least now you can get started.
Notice that I added the word debugger;
to your javascript. IF you are testing in Google Chrome -- and IF you have DevTools open (press F12) -- THEN the debugger
statement will allow you to step-through your code line-by-line. This is the single best tool you will ever find to figure out how to get this working.
NON-WORKING Stack Snippet:
$(document).ready(function() {
// Variables
debugger;
var baseDeDatos = [
{
id: 1,
nombre: 'Jean Mom',
precio: 1399
},
{
id: 2,
nombre: 'Pant Ren',
precio: 990
},
{
id: 3,
nombre: 'Buzo Largo Hailey',
precio: 948
},
{
id: 4,
nombre: 'Cycle Short',
precio: 550
},
{
id: 5,
nombre: 'Top Cellie',
precio: 590
},
{
id: 6,
nombre: 'Jacket Denim Ray',
precio: 2890
},
{
id: 7,
nombre: 'Cinto Vice',
precio: 499
},
{
id: 8,
nombre: 'Top Caro',
precio: 499
},
{
id: 9,
nombre: 'Bra Top Regan',
precio: 590
},
{
id: 10,
nombre: 'Sweater Polly',
precio: 1399
},
{
id: 11,
nombre: 'Camisa June',
precio: 799
},
{
id: 12,
nombre: 'Pant Amy',
precio: 1299
},
{
id: 13,
nombre: 'Top Tai',
precio: 648
},
{
id: 14,
nombre: 'Tapado Judy',
precio: 3290
},
{
id: 15,
nombre: 'Mini Corderoy Lou',
precio: 1090
}
]
var $items = $('#items');
var carrito = [];
var total = 0;
var $carrito = $('#carrito');
var $total = $('#total');
//Use jQuery .on() method to attach an event handler to ALL FUTURE such elements
$(document).on('click', 'button.item-button', function(){
debugger;
$this = $(this);
anyadirCarrito($this)
});
$(document).on('click', 'carr-button', function(){
$this = $(this);
borrarItemCarrito($this);
});
// Funciones
function renderItems () {
for (var info of baseDeDatos) {
// Estructura
var $miNodo = $('div');
miNodo.addClass('card', 'col-sm-4');
// Body
var $miNodoCardBody = $('div');
miNodoCardBody.addClass('card-body');
// Titulo
var $miNodoTitle = $('h5');
$miNodoTitle.addClass('card-title');
$miNodoTitle.text(info['nombre']);
// Precio
var $miNodoPrecio = $('p');
$miNodoPrecio.addClass('card-text');
$miNodoPrecio.text('$' + info['precio']);
// Boton
var $miNodoBoton = $('button');
$miNodoBoton.addClass('btn', 'btn-primary', 'item-button');
$miNodoBoton.text('+');
$miNodoBoton.attr('marcador', info['id']));
// Insertamos
$miNodoCardBody.append($miNodoTitle);
$miNodoCardBody.append($miNodoPrecio);
$miNodoCardBody.append($miNodoBoton);
$miNodo.append($miNodoCardBody);
$items.append($miNodo);
}
}
function anyadirCarrito ($this) {
// Anyadimos el Nodo a nuestro carrito
carrito.push($this.getAttribute('marcador'))
// Calculo el total
calcularTotal($this);
// Renderizamos el carrito
renderizarCarrito($this);
}
function renderizarCarrito ($this, carrito) {
//What is "carrito" and where is it created? It needs to be added to the fn call
// Vaciamos todo el html
carrito.text(); //clear it
// Generamos los Nodos a partir de carrito
carrito.forEach(function (item, indice) {
// Obtenemos el item que necesitamos de la variable base de datos
var miItem = baseDeDatos.filter(function(itemBaseDatos) {
return itemBaseDatos['id'] == item;
});
// Creamos el nodo del item del carrito
var $miNodo = $('li');
$miNodo.addClass('list-group-item', 'text-right');
let summat = `${miItem[0]['nombre']} - $${miItem[0]['precio']}`;
$miNodo.text(summat);
// Boton de borrar
var $miBoton = $('button');
$miBoton.addClass('btn', 'btn-danger', 'mx-5', 'carr-button');
$miBoton.text('X');
$miBoton.attr('posicion', indice);
// Mezclamos nodos
$miNodo.append($miBoton);
carrito.append($miNodo);
});
}
function borrarItemCarrito ($this, carrito) {
// Obtenemos la posicion que hay en el boton pulsado
var posicion = $this.attr('posicion');
// Borramos la posicion que nos interesa
carrito.splice(posicion, 1);
// volvemos a renderizar
renderizarCarrito($this, carrito);
// Calculamos de nuevo el precio
calcularTotal($this);
}
function calcularTotal () {
// Limpiamos precio anterior
total = 0;
// Recorremos el array del carrito
for (var item of carrito) {
// De cada elemento obtenemos su precio
var miItem = baseDeDatos.filter(function(itemBaseDatos) {
return itemBaseDatos['id'] == item;
});
total = total + miItem[0]['precio'];
}
// Formateamos el total para que solo tenga dos decimales
var totalDosDecimales = total.toFixed(2);
// Renderizamos el precio en el HTML
// ERROR var total is not an html element, is it? You can only use `.text()` (and .textContent) on an ELEMENT
$total.textContent = totalDosDecimales;
}
// Eventos
// Inicio
renderItems();
}
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<!-- Elementos generados a partir del JSON -->
<main id="items" class="col-sm-8 row"></main>
<!-- Carrito -->
<aside class="col-sm-4">
<h2>Carrito</h2>
<!-- Elementos del carrito -->
<ul id="carrito" class="list-group"></ul>
<hr>
<!-- Precio total -->
<p class="text-right">Total: <span id="total"></span>$</p>
</aside>
</div>
</div>
</body>
</html>
来源:https://stackoverflow.com/questions/57211123/need-to-add-and-delete-items-from-a-shopping-cart-using-javascript-jquery