VueJS Error: Unable to access the 'className' property of an undefined variable

I'm currently working on a menu design project where I need to highlight the active tab/page that the user is on by adding a color class and utilizing JavaScript to update the active link. Here's a snippet of my template:

<div class="menu-container">
  <button
    class="menu-item active-tab"
    onclick="activateTab(event,'Home')"
  >
    Home
  </button>
  <button
    class="menu-item"
    onclick="activateTab(event,'About')"
  >
    About
  </button>
  <button
    class="menu-item"
    onclick="activateTab(event,'Contact')"
  >
    Contact
  </button>
</div>

<div id="Home" class="tab-content active-tab">
  <h2>Home</h2>
  <p>This is the homepage.</p>
</div>

<div id="About" class="tab-content" style="display:none">
  <h2>About</h2>
  <p>Learn more about us here.</p>
</div>

<div id="Contact" class="tab-content" style="display:none">
  <h2>Contact</h2>
  <p>Reach out to us for any queries.</p>
</div>

Additionally, I've included the following JavaScript code in my 'methods':

methods: {
    activateTab: function(evt, tabName) {
      var i, tabs, tabLinks;
      tabs = document.getElementsByClassName("tab-content");
      for (i = 0; i < tabs.length; i++) {
        tabs[i].style.display = "none";
      }
      tabLinks = document.getElementsByClassName("menu-item");
      for (i = 0; i < tabLinks.length; i++) {
        tabLinks[i].classList.remove('active-tab');
      }
      document.getElementById(tabName).style.display = "block";
      evt.currentTarget.classList.add('active-tab');
    }
  }

However, I encountered an error in console saying 'TypeError: Cannot read property 'className' of undefined' and the button doesn't get highlighted as intended. I would appreciate any help or suggestions you can provide. Thank you!

Answer №1

The issue lies in passing event instead of $event, which is causing it to be undefined. Additionally, there is a lot of unnecessary code present. I have cleaned it up for you below:

HTML

<div class="w3-bar w3-black">
  <button
    v-for="city in cities"
    class="w3-bar-item w3-button tablink"
    @click="openCity($event, city)"
    :class="{ 
      'w3-red': city.name === selectedCity,
      'w3-black': city.name !== selectedCity 
    }"
  >
    {{city.name}}
  </button>
</div>

<div 
  v-for="city in cities" 
  :id="city.name" 
  class="w3-container w3-border city"
  :class="{ 
    'visible': city.name === selectedCity,
    'hidden': city.name !== selectedCity 
  }"
 >
  <h2>{{city.name}}</h2>
  <p>{{city.description}}</p>
</div>

script

data () {
  return {
    selectedCity: 'London',
    cities: [
      { 
        name: 'London', 
        description: 'London is the capital city of England'
      },
      { 
        name: 'Paris', 
        description: 'Paris is the capital of France',
      },
      { 
        name: 'Tokyo', 
        description: 'Tokyo is the capital of Japan',
      }
    ] 
  }
},
methods: {
  openCity (event, city) {
    this.selectedCity = city.name
  }
}

styles

.hidden {
  display: none
}

.visible {
  display: block
}

Method 2

To simplify and avoid using CSS classes, you can utilize v-show to show only the selected city based on city.name === selectedCity:

<div 
  v-for="city in cities" 
  v-show="city.name === selectedCity"
  :id="city.name" 
  class="w3-container w3-border city"
 >
  <h2>{{city.name}}</h2>
  <p>{{city.description}}</p>
</div>

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

Is there a reason why Social Bar isn't appearing at the top?

My challenge is to position the bar close to the black footer. It appears correctly in Chrome, but not in Firefox and Opera. The screenshot shows how it looks in Chrome. However, in Firefox and Opera, the social bar is positioned lower and does not align ...

Trigger a function when the browser automatically populates an input field

I am attempting to trigger a function that can detect if the browser has autofilled a field and then add a specific class to it. After finding a thread with a solution that mostly works, mentioned here: Here is how I implemented it: $.fn.allchange = fun ...

Choosing options from an API response in a REACT-JS application

I have a Select Component in my application and I want it to automatically show the selected data once the response is received. import Select from "react-select"; <Select menuPlacement="auto" menuPosition="fixed" ...

Complete a form when a link or button on the webpage is clicked

I have a variety of links and buttons on my webpage, and they are generated dynamically. I am unable to assign an onclick event to each one individually. My goal is to submit form data to the next page whenever any link or button on the page is clicked. ...

Change a Python string in the format 'min:sec' into a time object so it can be displayed correctly and sorted by the jQuery tablesorter

Currently, I am facing an issue where tablesorter is only working correctly on string representations of time that are below '25:00'. Any values above this are being sorted lower than strings like '24:12' or '09:24'. It seems ...

React-easy-crop simply provides a blob url as a result

Currently, I am utilizing the react-easy-crop package to enable users to make adjustments to their profile pictures post uploading. However, I have encountered an issue where the cropped image is returned in the form of a blob URL such as blob:http://local ...

Array containing two objects in a two-dimensional format

In the example provided, I am working with a 2D array. Link to the example: https://codesandbox.io/s/v0019po127 I am noticing different results depending on whether I use the browser console or Codesandbox's console. I have attempted using JSON.str ...

Is there a way to prevent a page from rendering until the necessary data is retrieved?

I am facing an issue where my page is attempting to render before the data is available. I have used async/await in my code, but I keep getting an error saying that the data is undefined. Interestingly, when I comment out the page elements and check the Re ...

Maintain dropdown menu visibility while navigating

I'm having an issue with my dropdown menu. It keeps sliding up when I try to navigate under the sub menu. I've spent all day trying to fix it, testing out various examples from the internet but so far, no luck. Any help would be greatly apprecia ...

Applying CSS Styles to a Single Class Only

I have been using Zurb's Foundation to customize the navbar with my own styles, which has been successful so far. However, I encountered an issue with the responsive behavior of the navbar when the viewing container size changes. The navbar adds a sec ...

The process of selecting particular words from a data-attribute value

Is it possible to extract specific words from a data attribute in a web application while preserving spaces? I am looking to: Select the first word Select the last word Select the word that precedes... Select the word that follows... Select everything t ...

How to Display Prices in Euros Currency with Angular Filter

Can someone help me figure out how to display a price in euros without any fractions and with a dot every 3 digits? For example, I want the price 12350.30 to be shown as 12.350 €. I attempted to use the currency filter but it only worked for USD. Then ...

Utilize React JS to dynamically render JSON array of images onto a JSX page in React

state = { products: [ { img: "'./images/heartstud.jpg'", name: "Heart Earrings", price: "1.99", total: "3.98", count: 2, description: "Yellow Chimes Crystals from Classic Designer Gold Plated Styl ...

Trouble deploying Firebase Cloud Functions

I am attempting to implement the following two functions: exports.increaseWaitinglistCounters = functions.database .ref('waitinglists/$iid/$uid') .onCreate(async () => { await admin .database() .ref(`waitinglistCounters/$ii ...

Resolving conflicting event handlers within vue.js

I have a situation where I'm trying to use two buttons on a page to navigate to different sections. When I include only one button, everything works fine. But when I include both buttons, only one of them functions properly. Upon debugging, I noticed ...

Adjust the quantity of divs shown depending on the value entered in a text input field

It seems like I am on the right track, but there is something simple that I am missing. I'm currently utilizing the jQuery knob plugin to update the input field. $('document').ready(function() { $(".knob").knob({ c ...

H3 Tag Embraced by a Repetitive Image

As I'm developing a website, I've encountered an interesting challenge... I have an h3 tag that requires a repeating background on both sides. It's a bit difficult to describe, so I created this graphic to illustrate... Essentially, it&apo ...

Creating HTML input elements dynamically using Javascript

<body> <form action="insertquestion.php" method="POST"> <script> function generateInputs(){ var prefix = "answer"; var number = 1; for(var i = 0; i < 5; i++){ ...

If the color of the border matches and the width of the border is equal to

As I navigate through multiple divs, my goal is to identify those with a distinct blue border. Furthermore, if a main div possesses a blue border, I need to check for any inner divs that also have a blue border or a border width of 3px. If the main div has ...

Exploring JavaScript Regular Expressions in Internet Explorer 11

I am attempting to eliminate all non-digit characters from a string using JavaScript. While this code works properly in FF and Chrome, it does not work in IE11 and no characters are removed. var prunedText = pastedText.replace(/[^\d\.]/g,""); ...