Tengo dos dimensiones de datos, una es la compra en sí y la segunda es la referencia de referencia. Los pedidos se producen con PDO y se toman de una base de datos MySQL:
<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>Usando ajax, el html anterior se analizaría directamente en una transmisión en vivo en mi sitio web, ordenado desc por orderid o fecha de compra, a través de 3 tipos de llamadas api de la misma función (dependiendo de los parámetros para identificar cada operación):
carga inicial (5 entradas) y botón cargar más (+5 cada vez)
$(".wrapper").append(html);ping websocket que solo activa la misma llamada api y la recuperación de mysql (devolviendo solo un pedido - transmisión en vivo)
$(".wrapper").prepend(html);actualización de websocket cuando el pedido ya está en la transmisión en vivo pero el estado cambia
$("#" + orderid).replaceWith(html);El problema que tengo es cómo convertir los divs html para mostrarlos y agruparlos por referencia como se muestra a continuación.
<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>Intenté todo tipo de cosas, como reescribir el php html fuente, reescribir la consulta sql para usar group_concat, así como usar wrapAll y cosas similares de jquery para modificar el html después de que ya regresa de la llamada ajax, pero no tuve suerte. Hay más acciones de ajax al hacer clic en el pedido para cambiar su estado. Necesito lo mismo a nivel de grupo para todos los pedidos que tengan la misma referencia. Lo siento si no me expliqué bien.
Esta solución repite las entradas existentes y las agrupa por la propiedad data-rfrnc :
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)Apoyo totalmente a @firstlast en su comentario de que enviar datos JSON y procesarlos en el front-end sería la mejor solución.
En caso de que sea de interés para alguien, aquí hay otra forma de convertir la cadena html recibida nuevamente en una matriz de matrices de JavaScript:
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);