0

I have a series of divs that display data on different people. The data for each person is stored in an array of objects, and there are a lot of values for each person. There is a button for each property, and I would like to be able to sort the divs in ascending or descending order of a property by clicking on a button. Each div is given an id, that corresponds to an id of the associated person in the array.

The data looks like (but it is much larger than this):

people = [
   {
     id: 'xde234',
     height: '196',
     weight: '100',
     age: '34'
  },
  {
     id: 'sbd451',
     height: '176',
     weight: '140',
     age: '26'
  },
  {
     id: 'loe489',
     height: '156',
     weight: 'NA',
     age: '54'
  }]

The data for each person is displayed by looping through the data, creating a div for each person, assigning their id as the id of the div, and defining the inner html of a span with each property value. The class name of the span is the same as the property. So the HTML looks likes:

<div id="peopleContainer">
  <div id='xde234'>
     <span class="height">196</span>
     <span class="weight">100</span>
     <span class="age">34</span>
  </div>
  <div id='sbd451'>
     <span class="height">176</span>
     <span class="weight">140</span>
     <span class="age">26</span>
  </div>
  <div id='loe489'>
     <span class="height">156</span>
     <span class="weight">NA</span>
     <span class="age">54</span>
  </div>
</div>

Each button is created with an eventlistener e.g:

heightButton = document.getElementById('heightButton')
heightButton.addEventListener('click', function(){
   // sortingFunction
}

I have been retrieving the divs and writing a sorting function using :

function sortingFunction(property){

   peopleContainer = document.getElementById('peopleContainer')
   allPeople =  peopleContainer.children
}

I have 3 questions really, the main one being the first:

  1. What is the most efficient way to sort and display this data in javascript for any property in the data, considering there will be many people and a large number of properties

  2. How do I implement ascending and descending sort into one button, so it alternates between the two.

  3. When a button is clicked, regardless of if it is ascending or descending, I would like all the NA values to be at the bottom, i.e. they are ignored in the sort but appended to the end.

Any help is greatly appreciated.

1
  • 3
    Don't sort the HTML. Sort the data, and then update the HTML. Commented Nov 2, 2021 at 10:53

2 Answers 2

2

It may help to create a new data structure holding references to the DOM elements.

const peopleElements = {}
[...allPeople].forEach(node=>{
  peopleElements[node.id] = node;
});

Next you can sort your people array however you like. Once that's done, you can refresh the container:

people.forEach(person=>{
  const node = peopleElements[person.id];
  peopleContainer.append(node);
});

Note that appending an element that's already on the page will simply move it to the end. Moving each person to the end in turn will result in the elements appearing in sorted order.

Sign up to request clarification or add additional context in comments.

Comments

0

thanks to @NiettheDarkAbsol his answer combined with the following sort functions has led me to a working answer. I use the data attribute to store the last type of sort (asc or desc). I use @NiettheDarkAbsol suggestion to append nodes, but do it twice, the second time with a condition to check for NAs, then move them to the bottom which works as desired. The sorting function now is :

function sortingFunction(e, property){

    peopleContainer = document.getElementById('peopleContainer');
    allPeople =  peopleContainer.children;

    const peopleElements = {};

    [...allPeople].forEach(node=>{
    peopleElements[node.id] = node;
    });
  
    if(e.target.getAttribute('data-lastSort') === 'desc'){
        e.target.setAttribute('data-lastSort','asc')
        people.sort(function(a,b){
            return a[property] - b[property]
        });
    }else{
        e.target.setAttribute('data-lastSort','desc')
        people.sort(function(a,b){
            return b[property] - a[property]
        });
    };
   
    people.forEach(person=>{
    const node = peopleElements[person.id];
    peopleContainer.append(node);
    };

    people.forEach(person=>{
       if(person[property] === 'NA'){
       const node = peopleElements[person.id];
       peopleContainer.append(node);
       };
    });

};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.