Editing And Deleting Products
Selecting the save-edit button
We now have a modal that displays the selected product title and price. The modal also has a button to save these changes:
<!-- dashboard.html -->
<div class="modal-content">
<label for="edit-name">Name:</label>
<input id="edit-name" type="text" />
<label for="edit-price">Price:</label>
<input id="edit-price" type="number" step=".01" />
<div class="modal-buttons">
<!-- save changes button -->
<button id="save-edit">Save</button>
<button id="cancel-edit">Cancel</button>
</div>
</div>
Back to the script.js
we can select this button, listen for a click, and call a function to edit the product. Add the following to the end of the script:
document.getElementById("save-edit")?.addEventListener("click", editProduct);
function editProduct() {
}
Editing the product
Use this function to select the name and price input
elements:
function editProduct() {
const nameInput = document.getElementById("edit-name");
const priceInput = document.getElementById("edit-price");
}
Not only do these input
elements contain the current product information, we can also type into them to update. Use the value
of these inputs to set the product from the filteredProducts
array:
function editProduct() {
const nameInput = document.getElementById("edit-name");
const priceInput = document.getElementById("edit-price");
if (currentEditIndex !== null) {
filteredProducts[currentEditIndex].name = nameInput.value;
filteredProducts[currentEditIndex].price = priceInput.value;
}
closeEditModal();
renderProducts();
}
if (currentEditIndex !== null)
: When the modal is opened we store the index position of the selected product, thisif
statement will first check we have a value before proceeding.filteredProducts[currentEditIndex].name = nameInput.value
: This index position is used to select the current product from the array, and we update thename
property to be the updated value. This is repeated for the price.- The final stage is to close the modal and re-render the products with the update.
The products should now update in the browser after an update. Remember, since we are fetching products from and API, a new set of products will be created after a page refresh. To permanently store products we would need to expand the project to use a database.
Deleting the product
To delete the product we listen for a click on the Delete button inside of the renderTableRows
function:
function renderTableRows(container, products) {
products.forEach(function (product, index) {
const row = document.createElement("tr");
row.innerHTML = `
<td>${product.name}</td>
<td>$${product.price}</td>
<td>
<button class="edit-btn" onclick="openEditModal(${index})">Edit</button>
// add onclick attribute:
<button class="delete-btn" onclick="deleteProduct(${index})">Delete</button>
</td>
`;
container.appendChild(row);
});
}
This also uses the index
position to find the selected product. Create the deleteProduct()
function in the script:
function deleteProduct(index) {
filteredProducts.splice(index, 1);
renderProducts();
createPaginationButtons();
}
This uses the splice
array method to remove an array item. The first parameter is the starting position, which is the index
position. The second parameter of 1 means we only want to remove one value.
The products are then re-rendered with the product removed, and the pagination buttons are re-generated to account for less products.
Final script.js
code
let products = [];
let filteredProducts = [];
const API_URL = "https://fakerapi.it/api/v2/products?_quantity=20";
let currentPage = 1;
const ITEMS_PER_PAGE = 5;
let currentEditIndex = null;
async function fetchProducts() {
const response = await fetch(API_URL);
const data = await response.json();
products = data.data;
filteredProducts = products;
createPaginationButtons();
renderProducts();
}
fetchProducts();
function renderProducts() {
const productList = document.getElementById("product-list");
const productTable = document.getElementById("product-table");
const start = (currentPage - 1) * ITEMS_PER_PAGE;
const end = start + ITEMS_PER_PAGE;
const currentProducts = filteredProducts.slice(start, end);
if (window.location.pathname.includes("dashboard.html")) {
productTable.innerHTML = "";
renderTableRows(productTable, currentProducts);
} else {
productList.innerHTML = "";
renderProductCards(productList, currentProducts);
}
}
function renderProductCards(container, products) {
products.forEach(function (product) {
const card = document.createElement("article");
card.setAttribute("class", "product-card");
card.innerHTML = `<section class="product-image">
<img
src="images/t-shirt-blue.png"
alt="blue t-shirt with short sleeves"
class="product-image"
/>
</section>
<section class="product-details">
<h3>${product.name}</h3>
<p>${product.description}</p>
<p class="price">$${product.price}</p>
</section>`;
container.appendChild(card);
});
}
function renderTableRows(container, products) {
products.forEach(function (product, index) {
const row = document.createElement("tr");
row.innerHTML = `
<td>${product.name}</td>
<td>$${product.price}</td>
<td>
<button class="edit-btn" onclick="openEditModal(${index})">Edit</button>
<button class="delete-btn" onclick="deleteProduct(${index})">Delete</button>
</td>
`;
container.appendChild(row);
});
}
function createPaginationButtons() {
const totalPages = Math.ceil(filteredProducts.length / ITEMS_PER_PAGE);
const pagination = document.getElementById("pagination");
pagination.innerHTML = "";
for (let i = 1; i <= totalPages; i++) {
const button = document.createElement("button");
button.textContent = i;
if (i === currentPage) {
button.classList.add("active");
}
button.addEventListener("click", function () {
currentPage = i;
renderProducts();
createPaginationButtons();
});
pagination.appendChild(button);
}
}
document.getElementById("search")?.addEventListener("input", function (e) {
const searchTerm = e.target.value.toLowerCase();
filteredProducts = products.filter(function (product) {
return product.name.toLowerCase().includes(searchTerm);
});
renderProducts();
createPaginationButtons();
});
function openEditModal(index) {
const modal = document.getElementById("edit-modal");
const nameInput = document.getElementById("edit-name");
const priceInput = document.getElementById("edit-price");
currentEditIndex = index;
nameInput.value = filteredProducts[index].name;
priceInput.value = filteredProducts[index].price;
modal.style.display = "flex";
}
function closeEditModal() {
const modal = document.getElementById("edit-modal");
modal.style.display = "none";
}
document
.getElementById("cancel-edit")
?.addEventListener("click", closeEditModal);
document.getElementById("save-edit")?.addEventListener("click", editProduct);
function editProduct() {
const nameInput = document.getElementById("edit-name");
const priceInput = document.getElementById("edit-price");
if (currentEditIndex !== null) {
filteredProducts[currentEditIndex].name = nameInput.value;
filteredProducts[currentEditIndex].price = priceInput.value;
}
closeEditModal();
renderProducts();
}
function deleteProduct(index) {
filteredProducts.splice(index, 1);
renderProducts();
createPaginationButtons();
}
Congratulations!
We hope you have enjoyed this practical course and gained some valuable skills. You have now completed the course!