I need help in making this as short as possible and it should follow the latest ES6 standards. It it already 100% working. But I need help because i want to follow the best practices in using ES6. The code is a little bit long and messy so maybe you can help me edit my code to make it short and clean. I'm just beginning to learn ES6 so i badly needed your professional advice. Specifically, I want help in implementing on how to output table correctly and declaring variables using ES6.
const products = [];
const cart = [];
const inputs = {
id: document.getElementById("productID"),
desc: document.getElementById("product_desc"),
qty: document.getElementById("quantity"),
price: document.getElementById("price")
};
const productsTable = document.getElementById("products-table");
const cartsTable = document.getElementById("carts-table");
function renderProductsTable() {
// delete all entries
[].slice.call(productsTable.children, 1).forEach(entry => productsTable.removeChild(entry));
products.forEach(product => {
const tr = document.createElement('tr');
const id = document.createElement('td');
id.textContent = product.id;
const desc = document.createElement('td');
desc.textContent = product.desc;
const qty = document.createElement('td');
qty.textContent = product.qty;
const price = document.createElement('td');
price.textContent = product.price;
const action = document.createElement('td');
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.addEventListener('click', removeProduct.bind(null, product.id));
const addToCartButton = document.createElement('button');
action.appendChild(deleteButton);
tr.appendChild(id);
tr.appendChild(desc);
tr.appendChild(qty);
tr.appendChild(price);
tr.appendChild(action);
productsTable.appendChild(tr);
});
}
function addProduct() {
const product = {
id: inputs.id.value,
desc: inputs.desc.value,
qty: inputs.qty.value,
price: inputs.price.value
};
console.log(products);
products.push(product);
renderProductsTable();
document.getElementById('order').reset();
}
function removeProduct(product_id) {
const product = products.find(p => p.id === product_id);
const index = products.indexOf(product);
products.splice(index, 1);
renderProductsTable();
}
<!DOCTYPE html>
<html>
<head>
<title>Shopping Cart ES6</title>
</head>
<body>
<form name="order" id="order">
<table>
<tr>
<td>
<label for="productID">Product ID:</label>
</td>
<td>
<input id="productID" name="product" type="text" size="28" required/>
</td>
</tr>
<tr>
<td>
<label for="product">Product Desc:</label>
</td>
<td>
<input id="product_desc" name="product" type="text" size="28" required/>
</td>
</tr>
<tr>
<td>
<label for="quantity">Quantity:</label>
</td>
<td>
<input id="quantity" name="quantity" width="196px" required/>
</td>
</tr>
<tr>
<td>
<label for="price">Price:</label>
</td>
<td>
<input id="price" name="price" size="28" required/>
</td>
</tr>
</table>
<input type="reset" class="resetbtn" value="Reset" />
<input type="button" id="btnAddProduct" onclick="addProduct();" value="Add New Product" >
</form>
<table border="1|1" id="products-table">
<tr>
<th>Product ID</th>
<th>Product Description</th>
<th>Quantity</th>
<th>Price</th>
<th>Action</th>
</tr>
</table>
<br />
</body>
</html>
-
2\$\begingroup\$ The guidelines here say that you should describe in your description what exactly your code is supposed to do. \$\endgroup\$jfriend00– jfriend002017年07月10日 13:32:45 +00:00Commented Jul 10, 2017 at 13:32
-
\$\begingroup\$ @jfriend00. I just need help in revising my codes to adhere to the ES6 Standards. Maybe you can help me with that. Thank you. \$\endgroup\$Thomas– Thomas2017年07月10日 13:35:10 +00:00Commented Jul 10, 2017 at 13:35
2 Answers 2
as mentioned previously you are using a lot of ES6 already but you can clean things up a bit more and you seem to want to see it written so here is my attempt below.
I have added in what has been mentioned already as well as some other ES6 helpfullness such as string interpolation.
I have also added in a small bit of validation so that the product id is unique, should be expanded upon but is a start.
https://jsfiddle.net/hpyj1acs/
JavaScript
function renderProductsTable(e) {
// delete all entries
[...productsTable.children].slice(1).forEach(entry => productsTable.removeChild(entry));
products.forEach(product => {
let tr = document.createElement('tr');
tr.innerHTML = `<td>${ product.productId }</td>
<td>${ product.desc }</td>
<td>${ product.qty }</td>
<td>${ product.price }</td>
<td>
<button id="${ product.productId }">Delete</button>
<button id="${ product.productId }">Add to Cart</button>
</td>`;
productsTable.appendChild(tr);
document.getElementById(product.productId).onclick = () => removeProduct(product.productId);
});
}
function validProduct(){
let productIsValid = true;
products.forEach(product => {
if(Object.values(product).includes(inputs.productId.value)){
productIsValid = false;
}else{
productIsValid = !!(inputs.productId.value && inputs.desc.value && inputs.qty.value && inputs.price.value)
}
});
return productIsValid;
}
function addProduct() {
if(validProduct()){
const product = {
productId: inputs.productId.value,
desc: inputs.desc.value,
qty: inputs.qty.value,
price: inputs.price.value
};
console.log(products);
products.push(product);
renderProductsTable();
document.getElementById('order').reset();
}
}
function removeProduct(product_id) {
const index = products.findIndex(p => p.id === product_id);
products.splice(index, 1);
renderProductsTable();
}
const products = [];
const cart = [];
const inputs = {
productId: document.getElementById("productID"),
desc: document.getElementById("product_desc"),
qty: document.getElementById("quantity"),
price: document.getElementById("price")
};
const productsTable = document.getElementById("products-table");
const cartsTable = document.getElementById("carts-table");
document.getElementById('btnAddProduct').onclick = addProduct;
HTML
<!DOCTYPE html>
<html>
<head>
<title>Shopping Cart ES6</title>
</head>
<body>
<form name="order" id="order">
<table>
<tr>
<td>
<label for="productID">Product ID:</label>
</td>
<td>
<input id="productID" name="product" type="text" size="28" required/>
</td>
</tr>
<tr>
<td>
<label for="product">Product Desc:</label>
</td>
<td>
<input id="product_desc" name="product" type="text" size="28" required/>
</td>
</tr>
<tr>
<td>
<label for="quantity">Quantity:</label>
</td>
<td>
<input type="number" id="quantity" name="quantity" width="196px" required/>
</td>
</tr>
<tr>
<td>
<label for="price">Price:</label>
</td>
<td>
<input type="number" id="price" name="price" size="28" required/>
</td>
</tr>
</table>
<input type="reset" class="resetbtn" value="Reset" />
<input type="button" id="btnAddProduct" value="Add New Product" >
</form>
<table border="1|1" id="products-table">
<tr>
<th>Product ID</th>
<th>Product Description</th>
<th>Quantity</th>
<th>Price</th>
<th>Action</th>
</tr>
</table>
<br />
</body>
</html>
-
\$\begingroup\$ Wouldn't it make sense to use HTML5 inputs like
number
for quantity and price (where for price, thestep
could be 0.01) \$\endgroup\$Icepickle– Icepickle2017年07月12日 21:57:14 +00:00Commented Jul 12, 2017 at 21:57 -
\$\begingroup\$ @Icepickle you are correct, I have added the number type in. \$\endgroup\$Chris Wright– Chris Wright2019年05月07日 11:14:32 +00:00Commented May 7, 2019 at 11:14
You are already using quite a lot of ES6 features (const
, arrow functions, Array.prototype.find
, etc)
Here's a few more places you could use some ES6 features:
Array.prototype.findIndex
/ Array.prototype.filter
Inside removeProduct
you are finding the product that has the same id as product_id
and then finding the index of that through indexOf
- this can be simplified through findIndex
:
const index = products.findIndex(p => p.id === product_id)
Alternatively, we could just filter products and not worry about the index altogether:
products = products.filter(product => product.filter !== product_id)
Array.from
/ ...
You can use Array.from
or the spread operator to convert the NodeList
instead of [].slice.call
:
Array.from(productsTable.children).slice(1).forEach(...)
Or, using spread operator:
[...productsTable.children].slice(1).forEach(...)
Arrow function over bind
In my opinion, the following is easier to read than using bind
:
deleteButton.addEventListener('click', () => removeProduct(product.id))
Non ES6/General comments
More generally, I'd recommend being consistent with your style of camel case and renaming to productId
I find not abbreviating variable names helps avoid context switch. It's quite clear that desc
is description but using p
for product
can become not so obvious once your codebase increases.
-
\$\begingroup\$ Sir can you make changes on my code on the snippet. I would gladly appreciate it. Thank you \$\endgroup\$Thomas– Thomas2017年07月10日 16:09:09 +00:00Commented Jul 10, 2017 at 16:09
Explore related questions
See similar questions with these tags.