Search code examples
javascriptdatatabledatatablestabulator

How can I group the rows of a table (by the "Quantity" cell)?


I think this is a common problem, but I don't know of any obvious solution.

I have a table of items to order (i.e. a sales list). One of the columns in this table is "quantity". Is there a tool (library, or something) that would automatically group records (rows) by itself, and increase the cell "quantity"?

In short, I want the table to convert this (Row ID, Name, Price):

3, Red ball, 3 pieces, $ 5
3, Red ball, 3 pieces, $ 5
3, Red ball, 3 pieces, $ 5

into this (name, QUANTITY, price) :

Red ball, 3 pieces, $ 5

The details of the problem are below ... Why do I need this? I store each position (row) of the table on the server. But because of the "quantity" column, I have to create new records in the new model, in which I create duplicate records for each item. For example, the string (name, quantity, price):

Red ball, 3 pieces, $ 5

Duplicated to another model as (row id, name, price):

3, Red ball, 3 pieces, $ 5
3, Red ball, 3 pieces, $ 5
3, Red ball, 3 pieces, $ 5

This is done in order to be able to work with these records (for example, count their number, link to other records, etc.). But everything spoils the "Quantity" column, if it were not there, then I would not have to duplicate anything in different models of my application, I would just display the same records, and already "SOME ADDON/LIB/PLUGIN/SNIPPET WHICH I ASK YOU ABOUT" would display a table and automatically grouped identical rows into one, counting their number in the "Quantity" column on the client side (JS). Forgive me for description my problem, I think the first part of the question will be enough ...

I am currently using the TABULATOR (JS) tables, a very cool tool, but I have not found such a built-in function in it ...

Data format from server:

 var tabledata = [
    
    {
        order_item_id:6,
        name:'red ball',
        price:5,
        
     },

    {
        order_item_id:7,
        name:'red ball',
        price:5,
        
     },

    {
        order_item_id:8,
        name:'red ball',
        price:5,
        
     },

     ]

Solution

  • const tabledata = [{
      order_item_id: 5,
      name: 'blue ball',
      price: 3,
    }, {
      order_item_id: 6,
      name: 'red ball',
      price: 5,
    }, {
      order_item_id: 7,
      name: 'red ball',
      price: 5,
    }, {
      order_item_id: 8,
      name: 'red ball',
      price: 5,
    }, {
      order_item_id: 9,
      name: 'blue ball',
      price: 3,
    }, {
      order_item_id: 10,
      name: 'blue ball',
      price: 3,
    }, {
      order_item_id: 11,
      name: 'red ball',
      price: 5,
    }, {
      order_item_id: 12,
      name: 'yellow ball',
      price: 15,
    }]
    
    const grouped = tabledata.reduce((acc, item) => {
      /*
       * check whether the accumulator already contains a product with the same name
       * (if it does, return its index otherwise return -1)
       */
      const index = acc.findIndex(_item => _item.name === item.name);
    
      if (index > -1) {
        /*
         * if the product is already present, increase its quantity by 1
         */
        acc[index].quantity = acc[index].quantity + 1;
      } else {
        /*
         * if the product is not present, add it to the accumulator array
         */
        acc.push({
          name: item.name,
          unit_price: item.price,
          quantity: 1
        });
      }
    
      return acc;
    }, []);
    
    console.log('### TABLEDATA:\n', tabledata);
    console.log('### GROUPED:\n', grouped);