Home > Back-end >  How to reverse the order of a set of date-sorted objects?
How to reverse the order of a set of date-sorted objects?

Time:12-15

I'm able to properly sort the objects in the list below by date. I also want to be able to sort them in reverse order on button click.

How do I sort the objects in reverse on click?

//array of objects
const cards = [
  {
    title: 'One Fish',
    sub: '(hover me)',
    isGreen: true,
    datePub: `November 11, 2021`
  },
  {
    title: 'Two Fish',
    sub: '(hover me)',
    isGreen: false,
    datePub: `November 11, 2020`
  },
  {
    title: 'Red Fish',
    sub: '(hover me)',
    isGreen: true,
    datePub: `December 21, 2021`
  },
  {
    title: 'Blue Fish',
    sub: '(hover me)',
    isGreen: true,
    datePub: `January 11, 2019`
  },
  {
    title: 'By Dr. Seuss',
    sub: '(hover me)',
    isGreen: false,
    datePub: `March 05, 2018`
  }  
];

//sorts by year, then month, then day
cards.sort((a, b) => new Date(b.datePub) - new Date(a.datePub));

//reverses date order on click
reverse.addEventListener('click', function() {
  cards.sort((b, a) => new Date(a.datePub) - new Date(b.datePub));
});

//create html
let cardsTemplate = (cardData) => {
  return `
    <div >
      <h2>${cardData.title}</h2>
      <h4>${cardData.sub}</h4>
      <p>${cardData.datePub}</p>
    </div>  
  `;  
}

//output
cardGroup.innerHTML = `
  ${cards.map(cardsTemplate).join('')}
`;
.container {
  display: flex;
  flex-direction: row;
  padding: 0.5rem;
}

.card {
  display: flex;
  justify-content: center;
  align-items: center;
  background: lightblue;
  flex-wrap: wrap;
  flex-direction: column;
  margin: 0 0.5em;
  padding: 0.5em;
  border-radius: 4px;
  transition: all 0.3s ease-in-out;
}
.card.green {
  background: lightgreen;
}
.card:hover {
  background: darkblue;
  color: white;
  cursor: pointer;
}
<div  id="cardGroup"></div>
<button type="button" id="reverse">Reverse Order</button>

CodePudding user response:

You need to swap a and b in your comparison function and re-render your HTML.

reverse.addEventListener('click', function() {
  cards.sort((a, b) => new Date(a.datePub) - new Date(b.datePub));

  cardGroup.innerHTML = `
    ${cards.map(cardsTemplate).join('')}
  `;
});

CodePudding user response:

Wrapped everything in outer function and made the button toggle a class: .reverse which determines how the event handler will sort the array.

const cards = [{
    title: 'One Fish',
    sub: '(hover me)',
    isGreen: true,
    datePub: `November 11, 2021`
  },
  {
    title: 'Two Fish',
    sub: '(hover me)',
    isGreen: false,
    datePub: `November 11, 2020`
  },
  {
    title: 'Red Fish',
    sub: '(hover me)',
    isGreen: true,
    datePub: `December 21, 2021`
  },
  {
    title: 'Blue Fish',
    sub: '(hover me)',
    isGreen: true,
    datePub: `January 11, 2019`
  },
  {
    title: 'By Dr. Seuss',
    sub: '(hover me)',
    isGreen: false,
    datePub: `March 05, 2018`
  }
];

function main(array) {
  const cG = document.querySelector('#cardGroup');
  const toggle = document.querySelector('#toggle');

  const dateOrd = array => array.sort((a, b) => new Date(a.datePub) - new Date(b.datePub));

  const dateRev = array => array.sort((a, b) => new Date(b.datePub) - new Date(a.datePub));

  const buildDeck = array => {
    cG.innerHTML = '';
    array.forEach(obj => {
      cG.insertAdjacentHTML('beforeEnd', `<div ><h2>${obj.title}</h2><h4>${obj.sub}</h4><p>${obj.datePub}</p></div>`);
    });
  };

  toggle.addEventListener('click', function() {
    this.classList.toggle('reverse');
    let data;
    if (this.classList.contains('reverse')) {
      data = dateOrd(array);
    } else {
      data = dateRev(array);
    }
    buildDeck(data);
  });
  buildDeck(dateOrd(array));
  toggle.classList.toggle('reverse');
};

main(cards);
.container {
  display: flex;
  flex-direction: row;
  padding: 0.5rem;
}

.card {
  display: flex;
  justify-content: center;
  align-items: center;
  background: lightblue;
  flex-wrap: wrap;
  flex-direction: column;
  margin: 0 0.5em;
  padding: 0.5em;
  border-radius: 4px;
  transition: all 0.3s ease-in-out;
}

.card.green {
  background: lightgreen;
}

.card:hover {
  background: darkblue;
  color: white;
  cursor: pointer;
}

#toggle {
  display: inline-block;
  width: 150px;
  cursor: pointer;
}
#toggle.reverse::before {
  content: 'Reverse ';
}
<div id="cardGroup" ></div>
<button id="toggle" type="button">Order</button>

  • Related