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> 

  • Please specify, did the sorting not work at all or didn’t work correctly? Alternatively, a.price > b.price does 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
  • Sorting does not work for new products, that is, when I click on the <th> Price: </ th field in the newly created table with values ​​from the default array, the sorting works, but when I add or delete products, the html table is overwritten and the click is no longer Worker - Igor Shvets

1 answer 1

Something with the construction of the table, a little corrected

 //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 table = document.getElementById("shop"); const tbody = table.querySelector('tbody'); tbody.innerHTML = ''; for (let i = 0; i < this.products.length; i++) { //create table tbody.innerHTML += `<tr><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 tbody.innerHTML += `<tfoot><tr><td colspan="3" id="total-price">Total price: ${shop.totalProductsPrice}</td></tr>`; } } // 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> <thead> <tr> <th>Name:</th> <th id="filter">Price:</th> <th>Count:</th> </tr> <thead> <tbody></tbody> </table> </div> </div> 

  • You misunderstood me sorting works by clicking on <th> Price: </ th>, it works when creating a table with default goods, but I delete or add a product code, html tables are overwritten and click on <th> Price: < / th> is no longer working, that is, the goods are not sorted. I tried to solve this by adding listeners and their variables to the show () method? but it didn't help, I described it upstairs - Igor Shvets
  • You took the cycle const rows = document.querySelectorAll ("# shop .data"); for (let i = rows.length - 1; i> = 0; i--) {const e = rows.item (i); e.parentNode.removeChild (e); } At which the line with the parameters of the goods is overwritten, after you took it away, it rubs the last html in the form of headers - Igor Shvets