Toggle class based on the open status of a div element

I am working on some HTML code that utilizes the following jQuery script:

<nav class="navigation">
    <ul>
        <li class="has-sub">iPad <i class="fa fa-angle-down"></i>
            <ul class="sub-menu">
                <li><a href="iPadAir2.php">iPad Air 2 Review</a></li>
                <li><a href="iPadAir.php">iPad Air Review</a></li>
                <li><a href="iPadMini2.php">iPad mini 2 Review</a></li>
            </ul>
        </li>
        <li class="has-sub">iPhone <i class="fa fa-angle-down"></i>
            <ul class="sub-menu">
                <li><a href="iPhone6.php">iPhone 6 Review</a></li>
                <li><a href="iPhone5s.php">iPhone 5s Review</a></li>
                <li><a href="iPhone5c.php">iPhone 5c Review</a></li>
                <li><a href="iPhone5.php">iPhone 5 Review</a></li>
                <li><a href="iPhone4s.php">iPhone 4s Review</a></li>
            </ul>
        </li>
        <li class="has-sub">Mac <i class="fa fa-angle-down"></i>
            <ul class="sub-menu">
                <li><a href="MacBook.php">MacBook Review</a></li>
                <li><a href="MacBookProRetina.php">MacBook Pro w/ Retina display Review</a></li>
                <li><a href="MacBookPro.php">MacBook Pro Review</a></li>
                <li><a href="MacBookAir.php">MacBook Air Review</a></li>
            </ul>
        </li>
    </ul>
</nav>

$(document).ready(function() {
    $(".has-sub").click(function() {
        $(this).find(".sub-menu").slideToggle(500);
        $(this).parent().children(".has-sub").not(this).find(".sub-menu").slideUp(500);
    });
});

In this code snippet, the `i` element has a class of fa-angle-down. When clicked, the corresponding `li` item expands. However, I want to modify it by removing the fa-angle-down class and replacing it with fa-angle-up. Can someone provide me with guidance on how to achieve this?

Thank you.

CSS for the navigation menu is provided below:

nav {
    background : #034893;
    height : 50px;
}

nav ul,
nav li,
nav a { 
    margin : 0; 
    padding : 0;
}

nav > ul > li {
    color : white;
    display : block;
    float : left;
    font-size : 18px;
    line-height : 50px;
    position : relative;
    transition : all .3s linear;
    width : 25%;
    z-index : 999;
}

nav > ul > li:hover {
    background : #88bffc;
    color : #333;
    cursor : pointer;
}

nav > ul > li > ul {
    background : #034893;
    left : 0;
    margin : 0 auto;
    position : absolute;
    right : 0;
    text-align : left;
}

nav ul ul a {
    color : white;
    display : block;
    font-size : 14px;
    padding : 6px 12px;
}

nav ul ul a:hover {
    background : #88bffc;
}

Answer №1

UPDATED I have verified that the classes are toggling correctly in the DOM. The modification made was to initially toggle the .fa class, which switches between the down and up arrows for the clicked menu item.

$(".has-sub").click(function(e) {
    e.preventDefault;
    $this = $(this);
    $this.find(".sub-menu").slideToggle(500);
    $this.siblings(".has-sub").not(this).find(".sub-menu").slideUp(500);
    $this.find(".fa").toggleClass('fa-angle-down fa-angle-up');
    $this.siblings(".has-sub").not(this).find(".fa-angle-up").toggleClass('fa-angle-up fa-angle-down');
});

Answer №2

When incorporating an anchor tag <a> for a purpose other than navigation, remember to utilize preventDefault();. The fa-angle-down class was mistakenly applied to an italicized <i> element instead of the intended list item <li>. It appears to create an accordion effect, am I correct? Toggling the required classes on and off is accomplished using toggleClass. If the links are meant to lead to actual destinations, make sure to comment out the e.preventDefault();

$(document).ready(function() {

  $(".has-sub").click(function(e) {
    // e.preventDefault();

    $(this).find(".sub-menu").slideToggle(500);
    $(this).parent().children(".has-sub").not(this).find(".sub-menu").slideUp(500);
    $('.fa').not(this).removeClass('fa-angle-down').addClass('fa-angle-up');
    $(this).find('.fa').toggleClass('fa-angle-down fa-angle-up');

  });
});
nav {
  background: #034893;
  height: 50px;
}
nav ul,
nav li,
nav a {
  margin: 0;
  padding: 0;
}
nav > ul > li {
  color: white;
  display: block;
  float: left;
  font-size: 18px;
  line-height: 50px;
  position: relative;
  transition: all .3s linear;
  width: 25%;
  z-index: 999;
}
nav > ul > li:hover {
  background: #88bffc;
  color: #333;
  cursor: pointer;
}
nav > ul > li > ul {
  background: #034893;
  left: 0;
  margin: 0 auto;
  position: absolute;
  right: 0;
  text-align: left;
}
nav ul ul a {
  color: white;
  display: block;
  font-size: 14px;
  padding: 6px 12px;
}
nav ul ul a:hover {
  background: #88bffc;
}
.fa.fa-angle-up:before {
  content: '\f106 ';
}
.fa.fa-angle-down:before {
  content: '\f107 ';
}
<link href="http://fortawesome.github.io/Font-Awesome/assets/font-awesome/css/font-awesome.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<meta charset="utf-8">
<nav class="navigation">
  <ul>
    <li class="has-sub"><i class="fa fa-angle-up">iPad</i>
      <ul class="sub-menu">
        <li><a href="iPadAir2.php">iPad Air 2 Review</a>
        </li>
        <li><a href="iPadAir.php">iPad Air Review</a>
        </li>
        <li><a href="iPadMini2.php">iPad mini 2 Review</a>
        </li>
      </ul>
    </li>
    <li class="has-sub"><i class="fa fa-angle-up">iPhone</i>
      <ul class="sub-menu">
        <li><a href="iPhone6.php">iPhone 6 Review</a>
        </li>
        <li><a href="iPhone5s.php">iPhone 5s Review</a>
        </li>
        <li><a href="iPhone5c.php">iPhone 5c Review</a>
        </li>
        <li><a href="iPhone5.php">iPhone 5 Review</a>
        </li>
        <li><a href="iPhone4s.php">iPhone 4s Review</a>
        </li>
      </ul>
    </li>
    <li class="has-sub"><i class="fa fa-angle-up">Map</i>
      <ul class="sub-menu">
        <li><a href="MacBook.php">MacBook Review</a>
        </li>
        <li><a href="MacBookProRetina.php">MacBook Pro w/ Retina display Review</a>
        </li>
        <li><a href="MacBookPro.php">MacBook Pro Review</a>
        </li>
        <li><a href="MacBookAir.php">MacBook Air Review</a>
        </li>
      </ul>
    </li>
  </ul>
</nav>

Answer №3

If you want to dynamically add and remove classes using jQuery, you can do so easily with the following example:

Check out this JSFiddle demo for a live demonstration.

This is how your HTML structure would look like:

<ul>
    <li class="fa-angle">Test (Click me to toggle classes)</li>
</ul>

Here's the corresponding CSS styling:

.fa-angle{
    color: red;
    cursor: pointer;
}

.fa-angle-up{
    color: blue;
    cursor: pointer;
}

And here is the jQuery script that handles the class toggling:

$(document).ready(function(){
    $(document).on('click', '.fa-angle', function(){
        $(this).addClass('fa-angle-up');
        $(this).removeClass('fa-angle');                     
    });

    $(document).on('click', '.fa-angle-up', function(){
        $(this).addClass('fa-angle');
        $(this).removeClass('fa-angle-up');                     
    });
});

In this example, I'm simply changing font colors by adding and removing classes, but you can customize the classes to suit your needs, such as adding or removing icons or other styles. I hope this explanation helps!

Answer №4

    $(document).ready(function() { 
$(".has-sub").click(function() {
$(this).find('i.fa-angle-down').toggleClass('fa-angle-down fa-angle-up');
    $(this).find(".sub-menu").slideToggle(500);
 $(this).parent().children(".has-sub").not(this).find(".sub-menu").slideUp(500).parents('li').find('i.fa-angle-up').toggleClass('fa-angle-up fa-angle-down'); 
}); 
});

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

Creating a layered effect with CSS: Combining color gradients and images for an eye-catching background

I developed a Flutter app and now I want to convert it into a website. Everything is going smoothly, but I really want the background of the website to match the background of the app. Check out this screenshot of the app's background: background im ...

Dimensions of table in Internet Explorer and Microsoft Outlook

I am currently working on creating a mailing list and I am facing some challenges in setting the width of a table element in IE/Outlook. Despite trying various solutions that I found in other inquiries, none of them seem to be effective. The code snippet ...

Dragging a DIV element continuously through repeated clicks and long mouse button presses

Is there a usual method in jQuery to move a DIV 1px every time I click an arrow icon, and then continue moving it left 1px every 100ms when I hold down the mouse button? Thank you. Thanks ...

Clicking an ASP.NET Button without any code will cause the page to reload in a new window

I am working on a straightforward ASP.NET project consisting of only two pages. The first page, named FirstPage.htm, contains the following HTML markup: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xh ...

How to efficiently store data using ajax and php techniques

I'm currently working on sending data via ajax for the user_question and language input fields. Can anyone help me with the correct way to include this element in the ajax JavaScript code so that I can save the table element value in my database? Tha ...

CSS: Floating navigation bar that becomes fixed upon reaching the top of the page

Looking for a creative approach to achieve the following: An innovative navigation bar that initially appears on a page regularly but then becomes fixed at the top as I scroll down. An alternative perspective: imagine a navigation bar that starts off unf ...

Issue with jQuery not retrieving clicked text values correctly

In my current project, I am using a PHP script to retrieve values from the database. The code snippet looks like this: <div class="col-md-4" > <?php $query = "SELECT * FROM product_categories"; $r ...

Clear PHP variable following AJAX post

I am facing an issue with the code in my script file: $.ajax({ url: "server.php?saveEvent", data: "myEvent=" + JSON.stringify(myEvent), dataType: "json", type: "post", success: function (data) { if (data) { $("#log" ...

ajaxform is not providing the correct response

There is a form below that logs into Instagram based on the response it receives. If the login is successful (returns "ok"), then it shows success, otherwise it should display an error state. However, in my case, it always returns a null state for some un ...

Website experiencing issues with image sizing

On my website, in the Current Books section, I have a row of images. To ensure that all the images are the same height, I initially set the height of the HTML book image to 378 using: <img alt="HTML & CSS" height= "378" src="html.jpg"> Using ...

substituting the text in a Django-rendered template

Dealing with a template that pulls values from a database and presents them using template tags. Unfortunately, the data returned is limited to 0 & 1 which I cannot control, so my aim is to utilize jquery to dynamically change these values to 'no& ...

Corrupting the structure of XML data

Utilizing a jQuery object to append elements and update the values of an XML document, initializing it with an XML string containing nodes like <tgroup>, <table>, <row>, <tbody>, etc. as shown below. var str = "<txml> <tab ...

Error: The specified object does not contain the 'tableRow' method

I am currently working on a contacts book project and I need a table to update as the user inputs data. However, I keep encountering an error related to 'tableRow'. I have tried changing function names and other solutions but haven't been ab ...

"When attempting to submit edits, the value is returning as null from the dialog box

I have a code snippet here that I am having trouble with. Whenever I try to submit, the value turns null and I am unable to edit it. $("#opendialog").click(function () { var clonetext = $('#infor').clone(true); $('#previewDiv') ...

How to retrieve the query string in VueJS

Recently, I've delved into the world of VueJS and so far, it's been a great experience! :) One thing I'm trying to figure out is how to save querystring values to a VueJS variable. It seems like a straightforward task in handlebars + express ...

Issue with AJAX causing form data not to be passed to controller

Recently, I encountered an issue with a form in my view: <form id="MyForm"> <input type="text" name="myinput" /> <button type="submit" /> </form> In my view's JavaScript code, which is executed upon page load, I have the foll ...

Dimensions of Bootstrap carousel

I am attempting to create a Bootstrap carousel with full-width images (width: 100%) and a fixed height. However, when I set the width to 100%, the height automatically takes on the same value. I am unsure if the issue lies within my files. <div id="m ...

What is the best way to trigger a function exclusively upon clicking a particular element?

My goal is to enable the user to interact with the model by positioning cubes in space upon clicking the "Cubes Mode" button. I currently have a script from the three.js website that achieves this, but I want it to only run when the mentioned button is cli ...

Achieve a polished and radiant illumination using Cascading Style Sheets

Looking to achieve a cool light effect using just CSS and HTML, similar to this image https://i.sstatic.net/TEwYF.png Not sure if it can be done or how to go about it. Any assistance would be greatly appreciated. .circle { border: 10px solid; bo ...

By simply clicking a button, you can input a value into a field without the need for the page to refresh

Can someone please help me figure out how to insert a specific value into an input field without refreshing the page? I have tried the following code but it doesn't seem to work. Basically, when I click the button, I want the value "1234567" to be aut ...