StephD
StephD

Reputation: 304

javascript: how to sort divs by contents of children

saw some similar questions but they were for jquery or unanswered. Was wondering if it's possible, or even worth it, to sort divs by the innerHTML of their children in vanilla js. Maybe it's something I should leave to a plugin like list js.

I was hoping to sort the rendered elements, I don't want to rewrite all the divs as json objects, if possible.

Here's a template I set up of what I'm trying to do: https://jsfiddle.net/ssccdd/9Lo2xy0s/4/

window.onload = function() {
  const  desc = false;
  const divs = document.getElementsByClassName("item"); 
  let arr=[];
  for(let i=0; i< divs.length; i++){
    arr.push(divs[i].getAttribute('data-ticker'));
  }
  console.log(arr)

  sortName = () => {
    console.log('sorting by name');
  }

  sortNumber = () => {
    console.log('sorting by number');
  }

  sortPrice = () => {
    console.log('sorting by price');
  }

  trimChars = (word) => {
    return parseFloat(word.replace(/[^0-9.]/g, ""));
  }
  
  document.getElementById("name").addEventListener("click", sortName);  
  document.getElementById("number").addEventListener("click", sortNumber);  
  document.getElementById("price").addEventListener("click", sortPrice); 
}
.item{
  font-family: Arial;
  font-size: 1.5rem;
  border: 4px solid cornflowerblue;
  margin: 2rem 0;
  padding: 1rem;
  width: 90%;
}
Sort by 
<button id="Name">name</button>
<button id="Number">number</button>
<button id="Price">price</button>

<div id="container">
  
  <div class="item" data-ticker="AAR">
    <div class="name">Asparagus salad</div>
    <div class="number">1</div>
    <div class="price">$10</div>
  </div>
  
  <div class="item" data-ticker="BUT">
    <div class="name">Bacon sandwich</div>
    <div class="number">6</div>
    <div class="price">$3.23</div>
  </div>
  
  <div class="item" data-ticker="CAT">
    <div class="name">Carrot cake</div>
    <div class="number">9</div>
    <div class="price">$4.12</div>
  </div>
  
  <div class="item" data-ticker="WHA">
    <div class="name">Whiskey</div>
    <div class="number">5</div>
    <div class="price">$12</div>
  </div>
  
</div>

Any suggestions on how to approach this?

Upvotes: 0

Views: 236

Answers (1)

Mister Jojo
Mister Jojo

Reputation: 22265

this way:

const
    containerRef = document.querySelector('#container')
  , items = [...containerRef.querySelectorAll('div.item')]
              .map(item=>
                ({ name  : item.querySelector('.name').textContent
                , number : Number(item.querySelector('.number').textContent)
                , price  : parseFloat(item.querySelector('.price').textContent.replace(/[^0-9.]/g,''))
                , itmRef : item
                }))

document.getElementById('Name').onclick = () =>
  {
  items.sort((a,b)=>a.name.localeCompare(b.name))
        .forEach(el=>containerRef.appendChild(el.itmRef) )
  } 
document.getElementById('Number').onclick = () =>
  {
  items.sort((a,b)=>a.number - b.number)
        .forEach(el=>containerRef.appendChild(el.itmRef) )
  } 
document.getElementById('Price').onclick = () =>
  {
  items.sort((a,b)=>a.price - b.price)
        .forEach(el=>containerRef.appendChild(el.itmRef) )
  }
.item{
  font-family: Arial;
  font-size: 1.5rem;
  border: 4px solid cornflowerblue;
  margin: 2rem 0;
  padding: 1rem;
  width: 90%;
}
Sort by 
<button id="Name">name</button>
<button id="Number">number</button>
<button id="Price">price</button>

<div id="container">
  
  <div class="item" data-ticker="AAR">
    <div class="name">Asparagus salad</div>
    <div class="number">1</div>
    <div class="price">$10</div>
  </div>
  
  <div class="item" data-ticker="BUT">
    <div class="name">Bacon sandwich</div>
    <div class="number">6</div>
    <div class="price">$3.23</div>
  </div>
  
  <div class="item" data-ticker="CAT">
    <div class="name">Carrot cake</div>
    <div class="number">9</div>
    <div class="price">$4.12</div>
  </div>
  
  <div class="item" data-ticker="WHA">
    <div class="name">Whiskey</div>
    <div class="number">5</div>
    <div class="price">$12</div>
  </div>
  
</div>

Upvotes: 1

Related Questions