What is the best way to add a CSS class to every <TD> element on an HTML page with just two clicks?

I am in the process of developing a scheduler web tool. Essentially, when a user clicks on two dates, all dates between those two selections will be automatically chosen.

Here is an example to illustrate this functionality:

If the user clicks on day 5: https://i.sstatic.net/dSlrp.png

Next, if they click on day 7: Days 6 and 7 are both magically highlighted.

This demonstration highlights how three consecutive days can be selected within the same week. However, it should also support selecting multiple days across weekends.

For instance, before the weekend starts with the first selection: https://i.sstatic.net/HgxhC.png

The second selection after the weekend, where day 12 is chosen: Weekend days 9 and 10 are not included in the selection.

The challenge in implementing this feature lies in defining the query to target the <td> elements in rows above the clicked element in the table.

So far, I have crafted the following jQuery code snippet for achieving this behavior:

 $(document).ready(function () {
    $("td.elegible").click(function () {
        $(this).children().filter("#event").toggleClass("event");
    });
});

The targeted HTML element is structured as follows:

<tr>
  <td class="elegible">
   <span class="number">@day.Date.Day</span>
   <span id="event"/>
  </td>
 </tr>

With this code, clicking on individual days toggles the green highlight accordingly. While this setup enables the selection of consecutive days like 5, 6, and 7, the challenge remains in automatically selecting day 6 upon choosing days 5 and 7. Additionally, preventing the selection of preceding days when no other selections have been made poses another obstacle.

Despite experimenting with various traversal functions (such as parent(), children(), find(), filter()), I have yet to solve this issue. Any guidance or tips in the right direction would be greatly appreciated.

Answer №1

In my previous comment, I mentioned that achieving this task would be fairly simple if you track the day number in the HTML using a data attribute.

Here is an example demonstrating how to do this. It allows for selecting only one date and enables selection in reverse order.

$(function() {

  var d1, d2; // Days
  var selectStarted = false; // Flag

  $('.day').on('click', function() {

    if (selectStarted === false) {

      // Select first day
      d1 = $(this).data('day');

      // Set flag
      selectStarted = true;

    } else {

      // Select second day
      d2 = $(this).data('day');

      var diff = 0;
      var selected = [];

      // Calculate days between
      if (d2 >= d1) {

        diff = d2 - d1;
        selected = Array.from(new Array(diff + 1), (x, i) => i + d1);
        
      } else {

        diff = d1 - d2;
        selected = Array.from(new Array(diff + 1), (x, i) => i + d2);
      }

      // Add selected class to each selected day
      selected.forEach(function(day) {
        $('[data-day="' + day + '"]').addClass('selected');
      });

      // Reset flag
      selectStarted = false;
    }

  });

});
td {
  cursor: pointer;
  text-align: center;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 12px;
}

td.selected {
  background-color: yellow;
}

td.weekend {
  background-color: lightgray;
}
<table border="3" cellspacing="3" cellpadding="3">
  <tr>
    <td>Mon</td>
    <td>Tue</td>
    <td>Wed</td>
    <td>Thu</td>
    <td>Fri</td>
    <td>Sat</td>
    <td>Sun</td>
  </tr>
  <tr>
    <td class="day"></td>
    <td class="day"></td>
    <td class="day"></td>
    <td class="day"></td>
    <td class="day"></td>
    <td class="day"></td>
    <td class="day weekend" data-day="1">1</td>
  </tr>
  <tr>
    <td class="day" data-day="2">2</td>
    <td class="day" data-day="3">3</td>
    <td class="day" data-day="4">4</td>
    <td class="day" data-day="5">5</td>
    <td class="day" data-day="6">6</td>
    <td class="day weekend" data-day="7">7</td>
    <td class="day weekend" data-day="8">8</td>
  </tr>
  <tr>
    <td class="day" data-day="9">9</td>
    <td class="day" data-day="10">10</td>
    <td class="day" data-day="11">11</td>
    <td class="day" data-day="12">12</td>
    <td class="day" data-day="13">13</td>
    <td class="day weekend" data-day="14">14</td>
    <td class="day weekend" data-day="15">15</td>
  </tr>
  <tr>
    <td class="day" data-day="16">16</td>
    <td class="day" data-day="17">17</td>
    <td class="day" data-day="18">18</td>
    <td class="day" data-day="19">19</td>
    <td class="day" data-day="20">20</td>
    <td class="day weekend" data-day="21">21</td>
    <td class="day weekend" data-day="22">22</td>
  </tr>
  <tr>
    <td class="day" data-day="23">23</td>
    <td class="day" data-day="24">24</td>
    <td class="day" data-day="25">25</td>
    <td class="day" data-day="26">26</td>
    <td class="day" data-day="27">27</td>
    <td class="day weekend" data-day="28">28</td>
    <td class="day weekend" data-day="29">29</td>
  </tr>
  <tr>
    <td class="day" data-day="30">30</td>
    <td class="day" data-day="31">31</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

To avoid adding or changing classes on weekend days, you can use a selector like:

$('[data-day="' + day + '"]:not(.weekend)')
.addClass('selected')`

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Element widths are displaying uneven alignment

I can't seem to wrap my head around what's happening here. I've got an HTML layout with a header, sidebar, and central content page. Both the sidebar and central content are within the same div acting as a clearfix. I floated the sidebar le ...

Are all the bootstrap columns displaying in a single row?

Despite my best efforts, I'm facing a puzzling issue as a newbie. I've meticulously set up the container > row > col structure in Bootstrap, but all my columns stubbornly remain on the same line. According to the Bootstrap guidelines, only ...

eliminating various arrays within a two-dimensional array

I need help with a web application that is designed to handle large 2D arrays. Sometimes the arrays look like this: var multiArray = [["","","",""],[1,2,3],["hello","dog","cat"],["","","",""]]; I am looking to create a function that will remove any array ...

Executing an Ajax form submission in React.js

Currently in the process of developing my initial application using React.js and aiming to send a contact form via email with Ajax. I've been referencing a solution from this source: . Unfortunately, only parts of the full component file are available ...

The gradual disappearance and reappearance of a table row

I am struggling with making a row fade out when a specific select value is chosen (such as "termination"), and fade in when any other option is selected. The code works perfectly fine when the div ID is placed outside the table, but once I encapsulate it w ...

Can the border become fainter and then more pronounced when hovered over?

Does anyone know of a simple method to create a fading effect for a CSS border-bottom when hovering over an image, and then have the border fade out once the hover is removed? <div class="hover"> <img src="images/ex.jpg"/> </div> ...

Issue with Bootstrap JQUERY Plugin in External Modal

product.php <a data-toggle="modal" data-target="#quick_edit" href="quick_edit.php?productid=<?php print $row['productid'];?>" class="btn btn-xs btn-success"><i class="fa fa-share"></i></a> <div class="modal" id= ...

JS/Electron Insert items individually

Apologies if my explanation is unclear. I have a function (shown below) that parses a JSON file and creates a grid of 1550 items. How can I add them one by one instead of all at once? Loading all 1500 items together is taking too long. function addItem () ...

Setting distinct fonts for input placeholder and value: A guide

Can different fonts be set for an input placeholder and value? I have a scenario where the input placeholder is in a right-to-left language while the value is in English. Is it achievable using CSS3? ...

managing json arrays within Laravel

I am currently working on a project where I am focusing on creating an ajax call and handling the data that comes back. Here is what my Ajax call looks like: $.ajax({ type: 'GET', dataType: "json", url: ****, ...

Retrieve every span element within the Hidden field by utilizing JQuery

Recently I started using Jquery and I have a hidden variable that contains all span tags within it. Can anyone guide me on how to access all the span elements inside the hidden field value? For instance, if there are 3 span elements within the hidden fiel ...

What could be causing my border to spill over into the adjacent div?

Trying to set up the contact section of my portfolio but running into an issue where the border of one div is overflowing into the next. Here's a snippet of the code: //CSS .contact-cont { padding: 4rem 12rem 0rem; height: 90vh; ...

The hyperlink is unclickable because of the menu

The code below contains a menu on the right side with a hover effect and some content with a link. However, the link is not clickable due to the menu. .menubar{position: fixed;right:0;top: 50%;transform: translateY(-50%);-webkit-transform: translateY(-5 ...

"Encountering issues with Instagram embeds.js library failing to load

I've been working on a JavaScript function that loads the HTML embed code for Instagram posts. When the post appears, the photo is replaced by a grey background and the Instagram logo. Even though the post contains other information like hashtags, tim ...

In what way could the border exceed the dimensions of the div?

<head> <meta charset="UTF-8"> <title>Document</title> <style> #Tri{ width:0px; height:0px; border-top: 50px solid yellow; border-right:50px solid red; border-bottom:50px solid green; border-left:50px solid blue; } </style&g ...

How can I apply a border to individual table cells in HTML without affecting the entire table?

Struggling to apply a border on table cells, especially when using rowspan. Desiring a table layout with 4 cells - one large cell on the left and three smaller cells on the right side of it. Below is the code snippet I attempted: jsfiddle[dot]net/1fv4dz ...

Using JQuery to send a post request to an iframe and receiving a

Currently, I am utilizing a form on a webpage to send data to an iFrame. This process can occur multiple times based on user requests. You can see an example of this process here: Target an iframe with a HTML Post with jQuery My goal is to implement speci ...

JavaScript program failing to execute

Seeking to incorporate a read more and read less feature that activates on click for my articles application using Django. However, encountering an issue where my JavaScript code does not work when the read more link is clicked. Below are the relevant fil ...

Disregard the CSS styling within the modal window

Currently, I am working with ReactJS and ANTD. My modal has been adjusted with paddings to center-align the text, but now I want to enhance the design. Here is the desired look: https://i.stack.imgur.com/qef7n.png This is how it appears at the moment: htt ...

Choosing <label> elements, while disregarding those <label> elements that include <input>

I need assistance with CSS rules to target only <label> elements that do not contain an <input> field inside of them. Is there a specific rule I can use for this? <label for="type">Regular Label</label> <label for="type"> ...