Почему сортировка по цене не работает?

164
31 августа 2018, 05:20

В методе sortProductsByPrice (sortOrder) сортировка не работает, когда я удаляю или добавляю продукты в dom при помощи слушателей(buttAdd.addEventListener,buttDelete.addEventListener), сортировка работает только для продуктов, находящихся в массиве this.products по умолчанию.

(Продукты сортируются, при клике на <th> Price: </ th>.

Необходимо, чтобы сортировка также работала после удаления / добавления товаров.

Я пробовал переместить всех слушателей с их переменными в метод show(), но после этого когда срабатывает buttAdd.addEventListener добавляется продукт, при следующем добавлении то количество, которое уже было добавлено и +1, а фильтр по цене все равно не работал :)

//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>

Answer 1

Что-то с построением таблицы, немного поправил

//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>

READ ALSO
Работа с функциями. как передать коллекцию в функции? [закрыт]

Работа с функциями. как передать коллекцию в функции? [закрыт]

Как реализовать данный код? Как сделать такие функции? (данный код менять нельзя)

169
JS Регулярное выражение - проверка URL

JS Регулярное выражение - проверка URL

Задача следующая - нужно составить регулярное выражение, которое проверит URL, и если оно имеет формат https://vkcom/[0-9A-z

161
[Vue warn]: Проблема с рекурсивным компонентом

[Vue warn]: Проблема с рекурсивным компонентом

[Vue warn]: Unknown custom element: <MyTreeList> - did you register the component correctly? For recursive components, make sure to provide the "name" option

175