Ways to dynamically assign a class to a single element within a group of identical elements

I have three identical items in the DOM. Specifically, I am referring to a moving line

<span class="caret"></span>

<ul>
  <li class="nav-item-1">
   <a href="#">ITEM 1</a>  
   <span class="caret"></span>
  </li>  
</ul>

<ul>
  <li class="nav-item-2">
   <a href="#">ITEM 2</a>  
   <span class="caret"></span>
  </li>  
</ul>

<ul>
  <li class="nav-item-3">
   <a href="#">ITEM 3</a>  
   <span class="caret"></span>
  </li>  
</ul>

Scenario: When I click on the first

<span class="caret"></span>
, it should receive the class "open", while the others remain with only the class "caret". When I click on the second
<span class="caret"></span>
, it should also receive the class "open", and the first one should lose this class. Is this achievable? My attempted solution is as follows:

$(".caret").click(function () {
  $(this).data('clicked', true);
  if ($('.caret').data('clicked')) {
    $(".caret").toggleClass('opened');
  }
});

Although this solution works, it applies the toggleClass('opened') to all elements with the class "caret" instead of just the one that was clicked.

Answer №1

Initially, you correctly utilized $(this) but then resorted back to using $('.caret'). Here is the amended solution:

$(".caret").click(function () {
     $(this).toggleClass('opened');
});

The asker has requested to close all other instances of .caret classes:

$(".caret").click(function () {
    $(".caret").removeClass('opened');
    $(this).addClass('opened');
});

Answer №2

Your HTML code contains errors that will result in incorrect display of the markup in the browser. Without knowing your desired outcome, I am unable to provide a specific solution for fixing it. However, once you address the issues, the basic code structure should be as follows:

$('.caret').on('click', function () {
    $('.caret.opened') 
      .not(this) 
      .removeClass('opened'); 
    $(this)
      .toggleClass('opened'); 
});

If you want one caret to always remain open:

$('.caret').on('click', function () {
    $('.caret.opened') 
      .removeClass('opened'); 
    $(this)
      .addClass('opened'); 
});

Answer №3

I have a hunch that maybe you intended this

It is not considered valid HTML to have a span within a ul tag

$(".nav-item a").on("click",function(e) {
  e.preventDefault();
  $(".caret").removeClass('opened');
  $(this).next(".caret").addClass('opened'); // could toggle if needed
});
.caret::after { content: "🡁" }
.opened::after { content: "🠿" }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="nav-item" id="nav-1"><a href="#">ITEM</a><span class="caret"></span></li>
</ul>
<ul>
  <li class="nav-item" id="nav-2"><a href="#">ITEM</a><span class="caret"></span></li>
</ul>

<ul>
  <li class="nav-item" id="nav-3"><a href="#">ITEM</a><span class="caret"></span></li>
</ul>

Answer №4

If you are not already using jQuery in your project, it is not necessary for this particular task.

const navItems = [...document.querySelectorAll("[class^=nav-item-")];

navItems.forEach(item => {
  item.addEventListener("click", () => {
    const opened = document.querySelector(".opened");

    if (opened) {
      opened.classList.remove("opened");
    }

    item.parentElement.querySelector(".caret").classList.add("opened");
  });
});
/* This code is for demonstration purposes only */

.caret.opened:after {
  content: "opened";
}
<ul>
  <li class="nav-item-1">
    <a href="#">ITEM</a>
  </li>
  <span class="caret"></span>
</ul>
<ul>
  <li class="nav-item-2">
    <a href="#">ITEM</a>
  </li>
  <span class="caret"></span>
</ul>
<ul>
  <li class="nav-item-3">
    <a href="#">ITEM</a>
  </li>
  <span class="caret"></span>
</ul>

Answer №5

There are some errors in the HTML code that need to be fixed. The correct syntax should look something like the example below. Let's also incorporate CSS to display what a caret looks like.

Then, we can use JavaScript to handle the toggle functionality.

$("ul").click(function (e) {
  var caret = $(this).find('.caret');
  $('.caret').data('clicked', false);
  $('.caret').removeClass('opened');

  caret.data('clicked', true);
  caret.toggleClass('opened');
});
.caret {
  background-color: red;
  border: 1px solid blue;
  width: 10px;
  height: 10px;
  display: none;
}

.opened {
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="nav-item-1">
    <a href="#">ITEM</a>
    <span class="caret"></span>
  </li>    
</ul>

<ul>
  <li class="nav-item-2">
    <a href="#">ITEM</a>
    <span class="caret"></span>
  </li>    
</ul>

<ul>
  <li class="nav-item-3">
    <a href="#">ITEM</a>
    <span class="caret"></span>
  </li>    
</ul>

Answer №6

Kindly double check your HTML tag for errors
ensure anchor closing tags are not missed out
include the .nav class in each li element

$(".nav").on('click', function() {
    if ($(this).next('.caret').hasClass('clicked opened')) {
        $('.caret').removeClass('clicked opened');
    } else {
        $('.caret').removeClass('clicked opened');
        $(this).next('.caret').addClass('clicked opened');
    }
});

https://jsfiddle.net/n56b84t9/2/

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

The number range filter in ng-table is malfunctioning

what I am trying to accomplish My goal is to create a column that can accommodate two numbers in order to filter numeric data within a specific range for that column. While sorting, pagination, and filtering by 'contain text' are working correct ...

Carousel issue with sliding on Bootstrap when deployed on various web servers

I am experiencing a strange issue with my website. I have it installed on two different servers, and while the Carousel works perfectly fine on the first server, it does not slide properly on the second server. Here are the links to each version of the we ...

What is the best way to align icons in the center alongside text or paragraphs using react?

I'm struggling with centering my icons like <GrTools size="30px"/> next to my text. It's causing some alignment issues with my styled components. Here is my JavaScript: <div id='paragraph' className="container"> ...

Extract specific form data to use in a jQuery.ajax request

Having trouble extracting the current selected value from a dropdown form in AJAX URL. The Form: <form name="sortby"> <select name="order_by" onchange="myFunction()"> <option<?php if(isset($_GET['order_by']) && ...

Vue appears to be having trouble waiting for the axios Post request

While testing a login request, I encountered an issue where jest did not call the mock: This is my test : const User = '123123' jest.mock('axios', () => ({ get: jest.fn(), post: (_url, _body) => new Promise((resolve, reject ...

Fundamentals of object property in jQuery and Javascript

Currently working on creating a new property named startPosition and setting the top property to equal the button's current top value in CSS. Below is the jQuery code snippet: var morphObject = { button: $('button.morphButton'), c ...

Change the color of the navbar when scrolling using bootstrap and jquery

Using Bootstrap to design a navigation bar, I have two main goals: I want the navbar to change color when the page is scrolled down by 20%, and then revert back to its original color when scrolling back to the top. When the collapse featu ...

Using jQuery to manipulate input arrays that are dynamically generated

My form is dynamic and consists of the following fields: <tr> <td><input name = "qty[]" /></td> <td><input name = "color[]" /></td> <td><input name = "price[]" /></td> <td><input nam ...

The Jquery map function is not returning selected options, always returning empty values. It seems to be avoiding the variable, although it functions properly on jsfiddle. There are

RESOLVED: Final solution: http://jsfiddle.net/AcfUz/220/ *applied the selector mentioned in the selected answer and adjusted the console.log value to appear before the text input, where the chosen options were supposed to be displayed, and voila--it&apo ...

Exploring methods to conduct testing on an AngularJS application using AngularJS end-to-end testing, specifically focusing on scenarios involving multiple inputs

Our program includes a directive that is repeated multiple times with an input field. The structure of our code resembles the following: <li> <label>AMI</label> <div class="searchbox" searchbox="" filter="search.ami"> ...

Ways to conceal the jqgrid thumbnail

I have a jqgrid that displays a large amount of dynamic data. I am looking for a way to hide the thumb of the vertical scrollbar in the jqgrid when scrolling using the mousewheel. Here is a basic example: var data = [ [48803, "DSK1", "", "02200220", "O ...

What is the best way to supply arguments to a generic handler function?

How can I send parameters to a generic handler in Asp.net using JavaScript/jQuery? I am working on a jQuery plugin called ajaxfileupload that utilizes a generic Handler. I need to pass certain arguments from the page using jQuery or JavaScript, such as Dy ...

Is there a way to update the href attribute within the script section in vue.js?

I need to dynamically set the href attribute of a link based on data retrieved from a database and rendered in the methods section. <template v-if="header.value == 'ApplicationName'"> <a id="url" href="#" target="_blan ...

Is it necessary to wait for CSS to fully load on a static site built with Next.js?

I am currently working on a Next.js static site. The JavaScript loads quickly, but there seems to be a delay in applying the styled-components CSS as seen in the screenshot. The CSS only kicks in after the page has fully loaded. Does anyone have any sugge ...

Shut down two modal windows and then open one anew

I am facing an issue with fancybox where I need to open 2 modals of a plugin and then close 2 and open 1 again... For example: closing 2 modals and opening 1 modal again... http://jsfiddle.net/g3R75/1/ I have tried the following code but it doesn't ...

Attempting to send a request from the front-end to the back-end is resulting in a 404 endpoint error

I encountered an issue while sending a post request from the front end to the backend. The error message I received was: " Error: Request failed with status code 404 " " Had Issues POSTing to the backend, endpoint " My main concern is ...

Issue with process.env.NODE_ENV not functioning appropriately in NodeJS when utilizing package.json scripts

I currently have three separate databases configured for testing, development, and production purposes. My goal now is to make my express app switch between these databases based on the script that is being executed. These are the scripts I am using: "s ...

Pass the initial value from a parent component to a child component in ReactJS without the need for state management

Initially, I have a parent Component A that calculates an initial value for its child Component B. The initial value is computed in the componentDidMount() of Component A and passed to B using props: <ComponentB initialValue={this.state.value} handleCha ...

Choosing a root element in a hierarchy without affecting the chosen style of a child

I am working on a MUI TreeView component that includes Categories as parents and Articles as children. Whenever I select a child item, it gets styled with a "selected" status. However, when I click on a parent item, the previously selected child loses its ...

When Select2 doesn't find a suitable option, the text "other" will be displayed

Is it possible to show a default option in select2 dropdown if the user's typed input does not match any available options? $("something").select2({ formatNoMatches: function(term) { //return a predefined search choice } }); I have searched ...