Changing the class in the calendar component using the element Id will result in the selected date being highlighted in each month

I have created a basic Vue calendar where the days of the month are shown using a v-for loop that generates an array of $refs. Each date element has a unique ID assigned to it. The issue I am facing is that when I try to highlight a particular day by clicking on it, the same day in every other month also gets highlighted. For example, if I click on May 25th, the 25th of every other month ends up being highlighted as well, even though I am toggling the class based on the specific element's ID.

Is there a way to only highlight the selected day without affecting others?

Below is the code snippet for the highlight method:

highlightDay(index) {
                let selected = this.$refs.day[index].id;
                if (!this.$refs.day[index].classList.contains("today")) {
                    this.$refs.day.forEach(el => {
                        if (el.classList.contains("selected-day")) {
                            el.classList.toggle("selected-day");
                        }
                    });
                    document
                        .getElementById(selected)
                        .classList.toggle("selected-day");
                }
            }

For reference, here is a link to the full project: https://codepen.io/reticent67/pen/EzWomG

Answer №1

The issue you are encountering is due to relying on DOM elements, using $refs, to save your chosen day.

It would be beneficial to transition away from this approach (referred to as jQuery logic, which often results in complicated DOM changes, even for straightforward scenarios like yours) and instead adopt a methodology tailored to SPAs. This involves utilizing the virtual model (commonly denoted as vm) as the single source of truth 1.

In relation to your component, rather than storing the selected day as the id of the currently displayed day, I recommend storing it as an array composed of 3 elements: [day, month, year] 2.

To transmit this information to the display layer, you can create a method:

isSelected(index) {
  return this.selectedDay === [index, this.month, this.year];
}

The day markup should include something similar to this:

<div 
  v-for="(date, date_index) in months[month].days" 
  :key="date_index" 
  :class="[{ 'selected-day': isSelected(date_index) }]">{{ date }}
</div>

I have integrated this solution into your provided example here.
Additionally, I streamlined the highlightDay() function by simply assigning the selectedDay value with the aforementioned array or unsetting it if they match (to enable deselection by clicking on the selected item).


[1] - It is important to acknowledge that in more intricate scenarios where data needs to be shared across app components, Vue offers a dedicated data management module known as Vuex (however, we do not utilize it in this instance).

[2] - In order to eliminate observer data (used by Vue to monitor changes), I opted to store the array in selectedDay as a JSON string.

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

ESLint's no-unused-vars rule is triggered when Typescript object destructuring is employed

I'm encountering an issue with my Typescript code where I am destructuring an object to extract a partial object, but it's failing the linter check. Here is the problematic code snippet: async someFunction(username: string): Promise<UserDTO> ...

Encountering a blank page issue with react-router-dom v6 Routes

I am attempting to route a page to the root, but it keeps showing up as a blank page regardless of which JavaScript file I use. It seems like React Router DOM has been updated and no longer uses Switch. I haven't used React since last year, so I' ...

Retrieve the CSS selector for the element that my plugin has been implemented on

Currently, I am in the process of developing a jQuery Plugin that is designed to be applied on a specific container element like so. $('#container').myPlugin(); Within this plugin, my goal is to retrieve the same element from another page using ...

Guide on setting default attributes for all properties of an object at once

Currently, I'm in the process of developing an AngularJS service provider (function) that achieves the following objectives: Gathers data from multiple tables within an SQLite database Delivers the resulting object to various controller functions S ...

Troubleshooting Vue computed property access issues

Currently, I am in the early stages of learning Vue and have moved on to exploring validation. While looking at some older examples that utilize Vee-Validate, it seems that there has been recent changes to the library. How can I update this code to work w ...

What methods can I use to interpret this incorrect JSON data in jQuery?

Is it possible to access the different pieces of data within this specific data attribute? <div class="location" data="{id: 4, point: {lng: -71.413364, lat: 41.673681}, category: 'Restaurant'}"> While it's quite simple to retrieve th ...

implement an angular directive to apply a CSS element

I am utilizing AngularJS and ng-repeat to populate a dynamic list of studies. This list has the capability to toggle into child elements of each item, creating an accordion-style toggle list that can go up to three levels deep for each list item. I am curr ...

How to simulate axios in a vue3 typescript unit test with jest and vue-test-utils2 (Resolved)

When my component is mounted, it makes a call to this.axios.get() and passes a vuex-store variable to the API. The API responds with an array, which the component then displays after transitioning from a loading element. In my unit test, I want to simulat ...

Using AJAX to retrieve a specific JSON object from an array of JSON data

Data retrieved in JSON array from the API: [{"id":"001", "name":"john", "age":"40"}, {"id":"002", "name":"jane", "age":"30"}] Using Ajax: $.ajax({ url: 'interface_API.php', ...

I am facing an issue where an AJAX post to Express is not returning any data to req.query. I have tried various solutions but nothing seems to

I have encountered an issue with my setup where the body is empty when sending data through ajax. In Chrome's network tab, I can see the post and content with the correct payload: {"EventName":"asd","PrivacyLevel":1,"TypeInt":1,"ExpectedDate":"asd"," ...

What is the best way to split the vertices of a mesh in Three.js?

Is there a way to disassemble the vertices of a Three.js mesh? I am interested in tearing apart a 3D object using mouse input. Recently, I developed a GLSL vertex shader for this web application that shifts the vertices of a mesh based on the brightness of ...

Is there a way to verify if an email is already registered within a MERN stack application

I am in the process of creating a registration form and need to verify if an email already exists within the system. Below is the React code snippet showcasing the structure for better understanding. In the schema, emails are defined as unique. AuthContr ...

Guide to eliminating hashtags from the URL within a Sencha web application

I'm currently developing a Sencha web application and I need to find a way to remove the "#" from the URL that appears after "index.html". Every time I navigate to a different screen, I notice that the URL looks like this: ...../index.html#Controller ...

`The challenge of properly handling quotation marks within quotation marks in JavaScript string literals

I am having trouble displaying text in a JavaScript tooltip Despite my efforts to escape the quotes and eliminate any line breaks, I keep encountering unterminated string literals. The specific text I want to show is: "No, we can't. This is going t ...

The shared hosting environment encountered an error during the Next JS build process

When I execute the command "npm run build" on my shared hosting server, it throws an error message: spawn ENOMEM. Interestingly, this command runs perfectly fine on my localhost and has been running smoothly on the hosting server for a few weeks until yest ...

What is the best way to eliminate HTML <li> bullets using codebehind?

When working in codebehind, I often create an HTML list using the following method: HtmlGenericControl list = new HtmlGenericControl("ul"); for (int i = 0; i < 10; i++) { HtmlGenericControl listItem = new HtmlGenericControl("li"); Label textLabel ...

Connect an angular directive template to an event

In my Angular directive, the template structure is as follows: <Button id="testBtn">Test me<button> Within the directive controller, I have defined API functions for the directive. Now, I need to send an event to the parent module when the bu ...

Issue with updating the :value binding within a select tag in Vue 3 component template using Composition API

My dropdown menu has some unique functionality: the options are listed in a random order, with the selected option always appearing first. Here is the code snippet that achieves this: <div id="main"> <sub-select :subs="data" ...

What is preventing me from disabling the ordering feature on my DataTable?

I am facing an issue where I am unable to disable ordering in my JavaScript code. Despite several attempts, nothing seems to work. Below is the code snippet that I have been working on: <script src="//code.jquery.com/jquery-1.12.0.min.js"></scr ...

Combining multiple storageStates in a playwright context for efficient loading

I am trying to load multiple storageStates into a single context in playwright, but I am facing some issues. When using the following code: const context = await browser.newContext({ storageState: "telegram.json",storageState: "google. ...