0

So I am trying to grey out an HTML table row upon expiry date. I don't want the data to disappear or hide. I just want the row to fade grey or something similar. Maybe make it unclickable? Is this possible with javascript. Apologies for this, but I am not very well versed in javascript, however I do have a light grasp of how it works.

Here's a basic example of my html table (the original is in a div with the bootstrap class: col-lg-8)

<table class="table table-striped">
    <thead class="table-dark" align="center">
        <th scope="col" align="center" width="400">Training Description</th>
        <th scope="col" align="center">Cost (Excl Vat)</th>
        <th scope="col" align="center">Location</th>
        <th scope="col" align="center">Training Date</th>
        <th scope="col" align="center"></th>
    </thead>
    <thead><th colspan="5" align="center">JUNE 2021</th></thead>
    <tbody>
        <tr>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">11-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
    </tbody>
</table>

I'd like to grey out and disable the register link a day after the training date. Not sure if this would require the use of a class="" or id="". The data is obviously static data written in html code, as displayed above.

If this question has been asked, I'm sorry, I just haven't been able to find anything on this. Any help is highly appreciated.

Hien Nguyen
  • 24,551
  • 7
  • 52
  • 62
  • It is possible, You need to add a class to the row that you need to disable and make colour arrangements as required, and make `pointer-events: none` to the button/cell – Abin Thaha Jul 16 '21 at 06:42
  • You have shown us your html but we will need some more info. From you description (and date format) I think that you don't have to gray out those fields in real time but rather when data is rendered. What are you using to render data? Or correct me that you need in in real time. – ciekals11 Jul 16 '21 at 06:43
  • When the page load, you compare the current date with the expiry date and, if they expiry date if before or equal to the current date, you can add a CSS class to "grey out" the row – secan Jul 16 '21 at 06:45
  • @ciekals11 The data is stored statically as text in the html file that has the table. I know this is quite basic, but it's all I can do. Not sure if this is what you meant by "rendered data" – Justin de Gois Jul 16 '21 at 06:55

6 Answers6

1

A javascript approach would be something like this:

  • Find all <tr> elements in your table body
  • For each of those elements, look up the 4th cell, which has the date in it
  • Parse that date text to a timestamp
  • Compare the timestamp to the browser time
  • If the timestamp is earlier than the current time, add a class indicating that the row is expired
  • Style the expired class in CSS

Here's how that works in code:

const rowIsExpired = tr => {
  const dateCell = tr.querySelector("td:nth-child(4)");
  const dateString = dateCell.innerText;
  const timestamp = Date.parse(dateString);
  
  return timestamp < Date.now();
}

const tableRows = document.querySelectorAll("tbody > tr");
tableRows.forEach(tr => {
  tr.classList.toggle("expired", rowIsExpired(tr));
});
.expired {
  opacity: .4;
}
<table class="table table-striped">
    <thead class="table-dark" align="center">
      <tr>
        <th scope="col" align="center" width="400">Training Description</th>
        <th scope="col" align="center">Cost (Excl Vat)</th>
        <th scope="col" align="center">Location</th>
        <th scope="col" align="center">Training Date</th>
        <th scope="col" align="center"></th>
      </tr>
    </thead>
    <thead><th colspan="5" align="center">JUNE 2021</th></thead>
    <tbody>
        <tr>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">11-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
        <tr>
            <td align="left" valign="middle"><b>Another Computer Training</b></td>
            <td align="center" valign="middle"><b>expensive</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">11-August-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
    </tbody>
</table>

Watch out!

There are some catches here:

  • You need to disable the link if you want to make sure it can't be clicked. It's best to not only use pointer-events in css for that, but actually disable it in the HTML source
  • This uses the browser's time. If the user loading the page has a wrong system clock or weird timezone, results may vary!
  • Parsing dates from strings can give unexpected results. Make sure your cell's text is formatted in a way that gives you the right outcomes.
  • The way I find the expiry date is brittle. If you change the order of your columns, it will break. It's best to add a specific attribute or class in the HTML so you can be sure it's easy to find in javascript.
user3297291
  • 22,592
  • 4
  • 29
  • 45
  • Maybe this is a dumb question, but would the ``` – Justin de Gois Jul 16 '21 at 07:27
  • You add the javascript inside a `

    `

    – user3297291 Jul 16 '21 at 07:28
  • Really appreciate the help this did the trick. marked as answer. Had training session times in some of the other "date" cells but I have moved these over make the date column only date-specific. – Justin de Gois Jul 16 '21 at 07:49
1

You can use jquery to iterate your table tr to find what tr has time expired as below code.

Use addClass method to add grey class with expired row.

Use can use Date.parse to get extract time to compare, and add class disable-click to disable Register button.

$('tr').each(function(index, tr) { 
   let date = $(tr).find("td:eq(3)").text();
   let day = date.split('-')[0];
   
   if(day != undefined && index > 1 && day < 11){ // assume that 11 is expired day
    $(tr).addClass('grey');
   }
});

$('tr').each(function(index, tr) { 
   let date = $(tr).find("td:eq(3)").text();
   let day = date.split('-')[0];
   let datetime = Date.parse(date);
   console.log(datetime);
   
   if(day != undefined && index > 1 && datetime < new Date()){ // assume that 11 is expired day
    $(tr).addClass('grey');
    //alert($(tr).find("td:eq(4)").find("a").text())
    $(tr).find("td:eq(4)").find("a").addClass("disable-click");
   }
});
.grey{
background-color: grey;
}

.disable-click{
    pointer-events:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-striped">
    <thead class="table-dark" align="center">
        <th scope="col" align="center" width="400">Training Description</th>
        <th scope="col" align="center">Cost (Excl Vat)</th>
        <th scope="col" align="center">Location</th>
        <th scope="col" align="center">Training Date</th>
        <th scope="col" align="center"></th>
    </thead>
    <thead><th colspan="5" align="center">JUNE 2021</th></thead>
    <tbody>
        <tr class='disabled'>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">11-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
        <tr>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">13-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
        <tr>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">10-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
        <tr>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">19-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
    </tbody>
</table>
Hien Nguyen
  • 24,551
  • 7
  • 52
  • 62
  • Okay this does something and I think I am on the right track with this. However, it also blocks out anything before the 11th of July. I am assuming I need to use a date format in the html code that can be picked up by the jquery code and compare it to the current date. Is this possible? Again I appreciate the help! – Justin de Gois Jul 16 '21 at 07:15
  • I updated answer, you can use Date.parse to convert to Date and compare with current date. – Hien Nguyen Jul 16 '21 at 07:26
0

If you check this example, the first row of the table is disabled, while others are clickable. If the data is static, you can give the classname to any row based on your requirement, and if not, give the classname to the row specifically from the code.

tbody tr {
  background-color: #eee;
}
tbody tr.disabled {
  background-color: gray;
  pointer-events: none;
}
<table class="table table-striped">
    <thead class="table-dark" align="center">
        <th scope="col" align="center" width="400">Training Description</th>
        <th scope="col" align="center">Cost (Excl Vat)</th>
        <th scope="col" align="center">Location</th>
        <th scope="col" align="center">Training Date</th>
        <th scope="col" align="center"></th>
    </thead>
    <thead><th colspan="5" align="center">JUNE 2021</th></thead>
    <tbody>
        <tr class='disabled'>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">11-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
        <tr>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">11-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
        <tr>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">11-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
        <tr>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">11-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
    </tbody>
</table>
Abin Thaha
  • 4,493
  • 3
  • 13
  • 41
0

I am not sure if you want to disable the link like this:

and then you can change the link color to grey by CSS & JavaScript or whatsoever

0

// calculate the difference, in days, between 2 dates
const dd=(d1,d2)=>Math.ceil( ( d1 - d2 ) / (1000 * 3600 * 24 ) );

//find all suitable anchor tags - of type button
document.querySelectorAll('td a[type="button"]').forEach(a=>{
  // find the date from previous table cell and create as a Date object
  let date=new Date(a.parentNode.previousElementSibling.textContent);
  // calculate the difference
  let diff=dd( new Date(), date );

  // if beyond the threshold - do stuff
  if( diff > 1 ){
    a.parentNode.parentNode.classList.add('expired');
    a.onclick=(e)=>{
      e.preventDefault();
      return false;
    };
  }
})
.expired td{
  background:rgba(0,0,0,0.25);
  color:rgba(0,0,0,0.5);
  font-style:italic;
  text-decoration:line-through;
}
<table class="table table-striped">
    <thead class="table-dark" align="center">
        <th scope="col" align="center" width="400">Training Description</th>
        <th scope="col" align="center">Cost (Excl Vat)</th>
        <th scope="col" align="center">Location</th>
        <th scope="col" align="center">Training Date</th>
        <th scope="col" align="center"></th>
    </thead>
    <thead><th colspan="5" align="center">JUNE 2021</th></thead>
    <tbody>
        <tr>
            <td align="left" valign="middle"><b>Basic Computer Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Zoom</td>
            <td align="center" valign="middle">11-June-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
        
        <tr>
            <td align="left" valign="middle"><b>Basic Banana Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">Online - Banana</td>
            <td align="center" valign="middle">16-July-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr>
        
        <tr>
            <td align="left" valign="middle"><b>Intensive Banana Training</b></td>
            <td align="center" valign="middle"><b>free</b></td>
            <td align="center" valign="middle">classroom</td>
            <td align="center" valign="middle">18-July-2021</td>
            <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
        </tr> 
        
    </tbody>
</table>
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • May I ask you why you care to calculate the difference between two dates if all you need to know is whether one comes before or after the other? Wouldn't a simple `if (expiryDate <= currentDate) { // disable row }` do? – secan Jul 16 '21 at 07:33
  • If they are converted to numbers ( `getTime()` ) then yes - there is not, imo, much of a difference either way – Professor Abronsius Jul 16 '21 at 15:17
0

If you can add a data-expdate custom attribute to your rows, it would greatly simplify your life; it would be something like this:

const rows = document.querySelectorAll('tr[data-expdate]');
const today = new Date();

rows.forEach(row => {
  const expDate = new Date(row.dataset.expdate);
  if (expDate <= today) {
    row.classList.add('expired');
    row.querySelector('a').parentElement.innerHTML = '<span>Expired<span>';
  }
})
.expired {
  background-color: #efefef;
  color: #999;
}
<table class="table table-striped">
  <thead class="table-dark" align="center">
    <th scope="col" align="center" width="400">Training Description</th>
    <th scope="col" align="center">Cost (Excl Vat)</th>
    <th scope="col" align="center">Location</th>
    <th scope="col" align="center">Training Date</th>
    <th scope="col" align="center"></th>
  </thead>
  <thead>
    <th colspan="5" align="center">JUNE 2021</th>
  </thead>
  <tbody>
    <tr data-expdate="2021-06-11">
      <td align="left" valign="middle"><b>Basic Computer Training</b></td>
      <td align="center" valign="middle"><b>free</b></td>
      <td align="center" valign="middle">Online - Zoom</td>
      <td align="center" valign="middle">11-June-2021</td>
      <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
    </tr>
    <tr data-expdate="2021-08-30">
      <td align="left" valign="middle"><b>Basic Computer Training</b></td>
      <td align="center" valign="middle"><b>free</b></td>
      <td align="center" valign="middle">Online - Zoom</td>
      <td align="center" valign="middle">30-August-2021</td>
      <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
    </tr>
    <tr data-expdate="2021-07-16">
      <td align="left" valign="middle"><b>Basic Computer Training</b></td>
      <td align="center" valign="middle"><b>free</b></td>
      <td align="center" valign="middle">Online - Zoom</td>
      <td align="center" valign="middle">16-July-2021</td>
      <td align="center" valign="middle"><a class="btn btn-dark" href="#" target="_blank" type="button">Register</a></td>
    </tr>
  </tbody>
</table>
secan
  • 2,622
  • 1
  • 7
  • 24