In the sortProductsByPrice (sortOrder) method, sorting does not work when I delete or add products to the dom using listeners ( buttAdd.addEventListener , buttDelete.addEventListener ), sorting works only for products that are in the default array of this.products .
(Products are sorted by clicking on <th> Price: </ th> .
It is necessary that the sorting also works after the removal / addition of goods.
I tried to move all the listeners with their variables to the show() method, but after that, when the buttAdd.addEventListener is triggered, the product is added, the next time the quantity is added, which has already been added, +1, and the price filter still did not work :)
//Product Creation Class class Product { constructor(name, count, price) { this.name = name; this.count = count; this.price = price; } } Product.SORT_ORDER_ASC = 1; Product.SORT_ORDER_DESC = -1; // Сlass where products are recorded class Shop { constructor() { this.products = []; } //method for adding a product addProduct(newProduct) { this.products.push(newProduct); } //method for remove product by name deleteProductByName(productName) { let i = this.products.length; while (i--) { if (productName === this.products[i].name) { this.products.splice(i, 1); } } } // get total price by all products get totalProductsPrice() { return this.products.map(product => product.price).reduce((p, c) => p + c); } //method for sorting the product at its price sortProductsByPrice(sortOrder) { const sorted = this.products.sort((a, b) => { return a.price > b.price ? sortOrder : -sortOrder; }); this.products = sorted; } // method to draw the table with product property ( // name, count, price) show() { const rows = document.querySelectorAll("#shop .data"); for (let i = rows.length - 1; i >= 0; i--) { const e = rows.item(i); e.parentNode.removeChild(e); } const table = document.getElementById("shop"); const tFoot = table.querySelector('tfoot'); if (tFoot) tFoot.remove(); for (let i = 0; i < this.products.length; i++) { //create table table.innerHTML += `<tbody><tr class="data"><td>${this.products[i].name}</td> <td>${this.products[i].price}</td> <td>${this.products[i].count}</td></tr></tbody>`; } //show total price by all products table.innerHTML += `<tfoot><tr><td colspan="3" id="total-price">Total price: ${shop.totalProductsPrice}</td></tr></tfoot>`; } } // add new product by click const formAdd = document.forms[0]; const inputsAdd = formAdd.elements; const buttAdd = formAdd.elements[3]; buttAdd.addEventListener('click', (e) => { e.preventDefault(); shop.addProduct(new Product(inputsAdd[0].value, parseInt(inputsAdd[2].value), parseInt(inputsAdd[1].value))); shop.show(); }, false); // delete product by name after click const formDelete = document.forms[1]; const nameDelete = formDelete.elements[0]; const buttDelete = formDelete.elements[1]; buttDelete.addEventListener('click', (e) => { e.preventDefault(); shop.deleteProductByName(nameDelete.value); shop.show(); }, false); let shop = new Shop(); shop.addProduct(new Product("product", 1, 2000)); shop.addProduct(new Product("product1", 2, 500)); shop.addProduct(new Product("product2", 3, 1000)); shop.show(); const priceFilter = document.getElementById("filter"); //filter products by price priceFilter.addEventListener("click", (e) => { shop.sortProductsByPrice(Product.SORT_ORDER_ASC); shop.show(); }, false); console.log(shop.products); <div class="Shop"> <div class="add-product"> <h1>Add product</h1> <form id="addForm"> <label for="name" >Name of product</label> <input type="text" id="name" class="input-product"> <label for="price">Price of product</label> <input type="text" id="price" class="input-product"> <label for="count">Count of product</label> <input type="text" id="count" class="input-product"> <button id="add">Add</button> </form> </div> <div class="product-table"> <h2>Products</h2> <form id="delete-form"> <label for="name-delete">Delete product by name</label> <input type="text" id="name-delete" class="input-delete"> <button id="delete" type="button">Delete</button> </form> <table id="shop"> <caption>Products that are available in the store</caption> <tr> <th>Name:</th> <th id="filter">Price:</th> <th>Count:</th> </tr> </table> </div> </div>
a.price > b.pricedoes not work for strings. Therefore, it is better to replace the price comparison condition for(sortOrder == Product.SORT_ORDER_ASC) ? a.price - b.price : b.price - a.price(sortOrder == Product.SORT_ORDER_ASC) ? a.price - b.price : b.price - a.price- mr NAE