Home > Software engineering >  Position Element in div based on its date
Position Element in div based on its date

Time:01-17

I have created a simplified version of the project I am working on. I want the divs in the past above the current date (in red), and the divs in the future below. I have tried using order in CSS but that didn't work.

<div >
  <div>04-10-2022</div>
  <div>05-02-2022</div>
  <div>06-12-2022</div>
  <div>07-26-2022</div>
  <div>01-15-2023</div>
  <div>02-01-2023</div>
</div>
const timeline = document.querySelector('.timeline')
const timeline_items = document.querySelectorAll('.timeline > div')
const today = new Date()

const s = new Intl.DateTimeFormat("en-uk", {
    dateStyle: "short"
})

timeline_items.forEach(dateitem => {
  const dateConvert = new Date(dateitem.textContent);
  const newDate = s.format(dateConvert);
  dateitem.innerHTML = newDate;
})

const date_container = document.createElement("div");
date_container.style.background = "red";
const DateText = document.createTextNode(s.format(today));
date_container.appendChild(DateText);

timeline.appendChild(date_container)

CodePudding user response:

Given a container (.timeline) you may:

  • collect all the dates available there;
  • add a new element, if not present yet, containing the date of today (formatted as MM-DD-YYYY) and setting its class as today;
  • sort all those dates in cronological order ascending from past to future;
  • unset the html content of the container and append to it the dates according to their new order;

The date of today will be styled according to the css rule selecting the .today elements.

main();

function main(){
  const timeline = document.querySelector('.timeline');

  const todayFormatted = getTodayFormatted();
  const today = addTodayToList(timeline, todayFormatted);
  const dates = [...timeline.children];

  sortDates(dates);
  refreshList(timeline, dates);
}

//returns today as MM-DD-YYYY
function getTodayFormatted(){
  const today = new Date();
  const dd = today.getDate().toString().padStart(2, '0');
  const mm = (today.getMonth()   1).toString().padStart(2, '0'); 
  const yyyy = today.getFullYear();
  return `${mm}-${dd}-${yyyy}`;
}

//adds today date to target if not present yet,
//and adds also the 'today' class (and returns the element)
function addTodayToList(target, today){
  //searches if the today date was present already in the list
  let dates = target.querySelectorAll(':scope > div');
  //isn't safe against duplicates existing in the html list
  let todayDate = [...dates].filter( date => date.textContent == today)?.[0];

  //if not, creates a new date and append to list
  if(!todayDate){
    todayDate = document.createElement('div');
    todayDate.textContent = today;
    target.append(todayDate);
  }
  
  //sets anyway its class 'today'
  todayDate.classList.add('today');
  
  return todayDate;
}

//sorts the elements in dates according to their date content
//(based on the fact the dates rearranged as YYYY-MM-DD follows alph. order)
function sortDates(dates){
  dates.sort((a, b) => {
    const [aMonth, aDayOfMonth, aYear] = a.textContent.split("-");
    const [bMonth, bDayOfMonth, bYear] = b.textContent.split("-");
    const aRearranged = `${aYear}-${aMonth}-${aDayOfMonth}`;
    const bRearranged = `${bYear}-${bMonth}-${bDayOfMonth}`;
    return aRearranged.localeCompare(bRearranged);
  });
}

//empties the target element and appends to it the passed dates
function refreshList(target, dates){
  target.innerHTML = '';
  target.append(...dates);
}
.today{
  background: red;
}
<div >
  <div>04-10-2022</div>
  <div>05-02-2022</div>
  <div>06-12-2022</div>
  <div>07-26-2022</div>
  <div>01-15-2023</div>
  <div>02-01-2023</div>
  <div>06-11-2023</div>
  <div>03-08-2023</div>
</div>

  • Related