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>