skip to Main Content

I have two dimensions of data, one is the purchase itself and the second is the referral reference. Orders are produced with PDO and taken from a MySQL database:

<div rfrnc="joe" id="1" class="order"><div>1 Laptop $220</div><div class="time">10.25</div></div>
<div rfrnc="bill" id="2" class="order"><div>1 Phone $520</div><div class="time">10.10</div></div>
<div rfrnc="joe" id="3" class="order"><div>1 Headset $220</div><div class="time">9.20</div></div>
<div rfrnc="bill" id="4" class="order"><div>1 Laptop $220</div><div class="time">9.02</div></div>
<div rfrnc="joe" id="5" class="order"><div>1 Laptop $220</div><div class="time">11.02</div></div>

Using ajax the above html would be parsed directly into a live feed on my website, sorted desc by orderid or date purchased, through 3 types of api calls of the same function (depending on the parameters to identify each operation):

  1. initial load (5 entries) & load more button (+5 each time)

    $(".wrapper").append(html);  
    
  2. websocket ping which only triggers the same api call and retrieval from mysql (returning just one order – live feed)

    $(".wrapper").prepend(html); 
    
  3. websocket update when the order is already on the live feed but the status changes

    $("#" + orderid).replaceWith(html);
    

The problem I have is how to convert the html divs to display and group it per reference as below.

<div rfrnc="joe">
<div id="5" class="order">...</div>
<div id="3" class="order">...</div>
<div id="1" class="order">...</div>
</div>
<div rfrnc="bill">
<div id="4" class="order">...</div>
<div id="2" class="order">...</div>
</div>

I tried all sort of things, like rewriting the source php html, rewriting the sql query to use group_concat as well as using wrapAll and similar jquery stuff to modify the html after it already comes back from ajax call but no luck. There is further ajax action when clicking on either the order to change the status of it. I need the same on the group level for all the orders having the same reference. Sorry if I did not explain it well.

2

Answers


  1. This solution loops the existing entries and groups them by the data-rfrnc property:

    const people = {};
    
    const html = `<div data-rfrnc="joe" id="1" class="order"><div>1 Laptop $220</div><div class="time">10.25</div></div>
    <div data-rfrnc="bill" id="2" class="order"><div>1 Phone $520</div><div class="time">10.10</div></div>
    <div data-rfrnc="joe" id="3" class="order"><div>1 Headset $220</div><div class="time">9.20</div></div>
    <div data-rfrnc="bill" id="4" class="order"><div>1 Laptop $220</div><div class="time">9.02</div></div>
    <div data-rfrnc="joe" id="5" class="order"><div>1 Laptop $220</div><div class="time">11.02</div></div>
    `
    const domParser = new DOMParser();
    const doc = domParser.parseFromString(html, "text/html")
    
    
    Array.from(doc.querySelectorAll('body > div')).forEach(div => {
      const person = div.getAttribute('data-rfrnc');
      if (!people[person]) {
         people[person] = [];
      }
      people[person].push(div)
    })
    
    
    const docFrag = document.createDocumentFragment();
    for(let [person, elements] of Object.entries(people)) {
      const personElement = document.createElement('div');
      personElement.setAttribute('data-rfrnc', person);
      elements
        .sort((a,b) => a.getAttribute('id') < b.getAttribute('id'))
        .forEach(element => personElement.appendChild(element));
      docFrag.appendChild(personElement);
    }
    
    document.body.appendChild(docFrag)
    
    Login or Signup to reply.
  2. I fully support @firstlast in his comment that sending JSON data and processing it in the front end would be the better solution.

    Just in case it is of interest to anyone, here is another way of converting the received html string back to a JavaScript array of arrays:

    const html=`<div rfrnc="joe" id="1" class="order"><div>1 Laptop $220</div><div class="time">10.25</div></div>
    <div rfrnc="bill" id="2" class="order"><div>1 Phone $520</div><div class="time">10.10</div></div>
    <div rfrnc="joe" id="3" class="order"><div>1 Headset $220</div><div class="time">9.20</div></div>
    <div rfrnc="bill" id="4" class="order"><div>1 Laptop $220</div><div class="time">9.02</div></div>
    <div rfrnc="joe" id="5" class="order"><div>1 Laptop $220</div><div class="time">11.02</div></div>`;
    
    const dom=document.createElement("div");
    dom.innerHTML=html
      
    const data=[...dom.children].map(d=>[d.id,d.getAttribute("rfrnc")].concat([...d.children].flatMap(c=>c.textContent.split(" ")))
    );
    
    // show the result:
    console.log(["id","rfrnc","qty","descr","price","time"]);
    console.log(data);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search