skip to Main Content

Using JavaScript, I need to add a class to a HTML element depending on the current day and month. To do this, I would like to compare the data-date of the elements ("09-20", "09-21", …) with the day and month of the current date.
Unfortunately my script doesn’t work. I’m an absolute beginner in JS, so sorry for my rookie mistakes.

$(function() {
  var a = new Date();
  $(".grid-item").each(function() {
    var specifiedDate = $(this).data('date');

    if (a.getMonth() + "-" + a.getDay() == specifiedDate) {
      $(this).addClass('today');
    }
  });
});
.grid-item {
  height: 130px;
  width: 130px;
  float: left;
  background: red;
  margin: 10px;
}

.today {
  background: yellow;
  border: red 1px solid;
}
<div class="grid-item" data-date="09-20"></div>
<div class="grid-item" data-date="09-21"></div>
<div class="grid-item" data-date="09-22"></div>
<div class="grid-item" data-date="09-23"></div>
<div class="grid-item" data-date="09-24"></div>
<div class="grid-item" data-date="09-25"></div>
<div class="grid-item" data-date="09-26"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

2

Answers


  1. Your first steps are to use the browser’s development console to see what values are actually produced here:

    if (a.getMonth() + "-" + a.getDay() == specifiedDate) {
    

    For example:

    const a = new Date();
    console.log(a.getMonth());
    console.log(a.getDay());

    Are those values what you expect? Currently today the values are 8 and 5. Combined into a string in the format you’re using that would be "8-5". Which simply doesn’t match any of the HTML elements you’re using.

    Your next step is to look at documentation for these functions if the results are unexpected.

    For getMonth we learn that the values are 0-based. So September is 8. We’d need to either add 1 to the result or subtract 1 from the values in the data.

    For getDay we learn that it returns the current day of the week, not the current day of the month. For that we’d need to use getDate instead.

    Putting these things together, we can correct the logic:

    $(function() {
       var a = new Date();     
        $(".grid-item").each(function() {
            var specifiedDate = $(this).data('date');       
    
            if ((a.getMonth() + 1) + "-" + a.getDate() == specifiedDate) {
                $(this).addClass('today');
            }
        });
    });
    .grid-item {
      height: 130px;
      width: 130px;
      float: left;
      background: red;
      margin: 10px;
    }
    
    .today {
      background: yellow;
      border: red 1px solid;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <div class="grid-item" data-date="9-20"></div>
    <div class="grid-item" data-date="9-21"></div>
    <div class="grid-item" data-date="9-22"></div>
    <div class="grid-item" data-date="9-23"></div>
    <div class="grid-item" data-date="9-24"></div>
    <div class="grid-item" data-date="9-25"></div>
    <div class="grid-item" data-date="9-26"></div>

    Observe that the leading "0" has been removed from the months in the HTML, we’re adding 1 to getMonth(), and we’re using getDate().


    Though it’s of course also worth noting that as another user points out the loop isn’t even necessary. Additional improvements could also involve using template literals instead of concatenating strings. For example:

    $(function() {
       var a = new Date();
       $(`div.grid-item[data-date="${(a.getMonth() + 1)}-${a.getDate()}"]`).addClass('today');
    });
    .grid-item {
      height: 130px;
      width: 130px;
      float: left;
      background: red;
      margin: 10px;
    }
    
    .today {
      background: yellow;
      border: red 1px solid;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <div class="grid-item" data-date="9-20"></div>
    <div class="grid-item" data-date="9-21"></div>
    <div class="grid-item" data-date="9-22"></div>
    <div class="grid-item" data-date="9-23"></div>
    <div class="grid-item" data-date="9-24"></div>
    <div class="grid-item" data-date="9-25"></div>
    <div class="grid-item" data-date="9-26"></div>
    Login or Signup to reply.
  2. a way to do this…

    -> doc on .toISOString() method

    const dateRef = new Date().toISOString().substring(5,10); // -> `MM-DD` 
    
    document.querySelectorAll('.grid-item').forEach( elm =>
      {
      elm.classList.toggle('today', elm.dataset.date === dateRef);
      });
    .grid-item {
      width       : 4em;
      height      : 2em;
      float       : left;
      background  : #eba4c2;
      margin      : .3em;
      text-align  : center;
      line-height : 2em;
      box-sizing  : border-box;
      }
    .today {
      background  : yellow;
      border      : red 1px solid;
      }
    .grid-item::before {
      content     : attr(data-date);
      }
    <div class="grid-item" data-date="09-20"></div>
    <div class="grid-item" data-date="09-21"></div>
    <div class="grid-item" data-date="09-22"></div>
    <div class="grid-item" data-date="09-23"></div>
    <div class="grid-item" data-date="09-24"></div>
    <div class="grid-item" data-date="09-25"></div>
    <div class="grid-item" data-date="09-26"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search