0

I have a table that is statically generated similar to below:

<table>
   <tr><td> Thing 1 </td><td> 2021-06-01 </td></tr>
   <tr><td> Thing 2 </td><td> 2021-06-01 </td></tr>
   <tr><td> Thing 3 </td><td> 2021-06-01 </td></tr>
</table>

I would like to highlight any date that is 'today' or potentially alter the text to say 'Today' or 'n Days Ago'. I'm assuming I need a function that iterates through the dates and alters/highlights them in some way.

The HTML is generated every 3 days so I cannot generate the 'today' value but I do control this generation. I do not know when users will look at the page so it might be day 3 for example so the JS needs to do the work.

Any tips? This is my first post so apologies for any mistakes in posting. I am not using JQuery but am using Bootstrap 4 and the popper.js. I am a relative noob to JS.

Neem
  • 13
  • 3

1 Answers1

1

If you prepare a date object for any date - today for instance - then you can check the innerText of the td cells in a loop and replace as needed

// get today's date ready
let today = new Date(), refDate = new Date();
today = today.toISOString().split("T").slice(0, -1)[0]

yesterday = new Date(refDate);
yesterday = new Date(yesterday.setDate(yesterday.getDate() - 1));
yesterday = yesterday.toISOString().split("T").slice(0, -1)[0];

tomorrow = new Date(refDate);
tomorrow = new Date(tomorrow.setDate(tomorrow.getDate() + 1));
tomorrow = tomorrow.toISOString().split("T").slice(0, -1)[0];

function isDate(v) {
  v = v.split("-");
  let isDate = true;
  v.forEach((d, i) => {
    if (i === 0 && (d.length != 4 || parseInt(d) === 0)) isDate = false;
    else if (i > 0 && (d.length != 2 || parseInt(d) === 0)) isDate = false
  })
  return isDate;
}

let tds = document.querySelectorAll('td');
tds.forEach(td => {
  let val = td.innerText.trim(),
    oneweek = (1000 * 60 * 60 * 24 * 7)
  if (val === today) td.innerText = "Today"
  else if (val === yesterday) td.innerText = "Yesterday"
  else if (val === tomorrow) td.innerText = "Tomorrow"
  else if (isDate(val) && new Date().getTime() - new Date(val).getTime() > oneweek) td.innerText = 'more than one week ago';
})
<table>
  <tr>
    <td> Thing 1 </td>
    <td> 2021-06-16 </td>
  </tr>
  <tr>
    <td> Thing 2 </td>
    <td> 2021-06-15 </td>
  </tr>
  <tr>
    <td> Thing 3 </td>
    <td> 2021-06-01 </td>
  </tr>
  <tr>
    <td> Thing 4 </td>
    <td> 2021-06-17 </td>
  </tr>
  <tr>
    <td> Thing 4 </td>
    <td> 2021-07-17 </td>
  </tr>
</table>
Kinglish
  • 23,358
  • 3
  • 22
  • 43
  • *toISOString* returns the UTC date which will be different from the local date for the period of the user's timezone offset at the start or end of the day depending on whether they are east or west of Greenwich respectively. The *isDate* function is ineffective, see [*How to validate a date?*](https://stackoverflow.com/questions/5812220/how-to-validate-a-date). – RobG Jun 16 '21 at 20:37
  • This totally worked and I’ve been using it for months. I have some problems in that it curiously doesn’t work on Linux or iOS based browsers but my audience is predominantly windows. Thanks so much. Sorry I didn’t respond sooner. Was my first post for years and forgot my manners. – Neem Aug 25 '21 at 21:24