What is the best way to hide the drop down menu after it has been opened by clicking on the same element

My attempt to create a code that toggles a drop-down menu on every click and closes any other open menus is not working as expected. The menu doesn't close upon clicking it again.

$(document).ready(function(){ 
    "use strict";
    $(".dropdown").hide();
    $("#smpg-cat-list li span").click(function() {

      $(".dropdown").hide();

      $("#smpg-cat-list li span").html('<i class="fa fa-plus" aria-hidden="true"></i>');

      if( $(this).next('.dropdown').css('display') == 'none' ){

         $(this).next('.dropdown').show();

         $(this).html('<i class="fa fa-minus" aria-hidden="true"></i>');

      }else{

        $(this).next('.dropdown').hide();

        $(this).html('<i class="fa fa-plus" aria-hidden="true"></i>');
      }

  });
});

I intend for the code to:

  1. Hide all instances of the class .dropdown.
  2. When #smpg-cat-list li span is clicked, close any open menus.
  3. Change the hidden elements' HTML to display a plus icon.
  4. Determine if the next .dropdown element has a display of none.
  5. If true, display the element and change the icon to minus.
  6. If false, hide the element and change the icon to plus.

The issue remains where the element shows but does not hide when clicked again.

HTML

<ul id="smpg-cat-list">
<li><a href="/web-design/">Web Design</a>
</li>
<li><a href="/robots/">Robots</a></li>
<li>
    <a href="/programming/">Programming</a>
    <span class="toggle" style="cursor:pointer"><i class="fa fa-plus" aria-hidden="true"></i></span>
    <ul class="dropdown">
        <li><a href="/programming/php/">PHP</a></li>
        <li><a href="/programming/c/">C#</a></li>
    </ul>
</li>
<li>
    <a href="/frameworks/">Frameworks</a>
    <span class="toggle" style="cursor:pointer"><i class="fa fa-plus" aria-hidden="true"></i></span>
    <ul class="dropdown">
        <li><a href="/frameworks/laravel/">Laravel</a></li>
    </ul>
</li>
<li><a href="/data-analysis/">Data Analysis</a></li>
<li>
    <a href="/cms/">CMS</a>
    <span class="toggle" style="cursor:pointer"><i class="fa fa-plus" aria-hidden="true"></i></span>
    <ul class="dropdown">
        <li><a href="/cms/wordpress/">WordPress</a></li>
        <li><a href="/cms/joomla/">Joomla</a></li>
    </ul>
</li>
</ul>

No special CSS involved.

Answer №1

After selecting a span element in the code snippet below, I utilized the [.find()][1] function to locate the i tag and verify if it contains a specific class using [.hasClass()][1]. Following this, I replaced the class from fa-plus to fa-minus, or vice versa, and then displayed the adjacent dropdown menu.

This script should guide you:

$(document).ready(function() {
  "use strict";
  $(".dropdown").hide();
  $("#smpg-cat-list li span").click(function() {
    
    $(".dropdown").hide();
   
    var $element = $(this).find("i");
    console.log($element);
    if ($element.hasClass("fa-plus")) {
      $element.removeClass("fa-plus").addClass("fa-minus");
      $(this).next('.dropdown').show();
    } else {
      $element.removeClass("fa-minus").addClass("fa-plus");
      $(this).next('.dropdown').hide();
    }
  });
});
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="smpg-cat-list">
  <li><a href="#">Web Design</a>
  </li>
  <li><a href="#">Robots</a></li>
  <li>
    <a href="#">Programming</a>
    <span class="toggle" style="cursor:pointer"><i class="fa fa-plus" aria-hidden="true"></i></span>
    <ul class="dropdown">
      <li><a href="#">PHP</a></li>
      <li><a href="#">C#</a></li>
    </ul>
  </li>
  <li>
    <a href="#">Frameworks</a>
    <span class="toggle" style="cursor:pointer"><i class="fa fa-plus" aria-hidden="true"></i></span>
    <ul class="dropdown">
      <li><a href="#">Laravel</a></li>
    </ul>
  </li>
  <li><a href="#">Data Analysis</a></li>
  <li>
    <a href="#">CMS</a>
    <span class="toggle" style="cursor:pointer"><i class="fa fa-plus" aria-hidden="true"></i></span>
    <ul class="dropdown">
      <li><a href="#">WordPress</a></li>
      <li><a href="#">Joomla</a></li>
    </ul>
  </li>
</ul>

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

Restrict the sorting functionality in a jQuery list

I have a project that involves scheduling individuals into different rooms, and I'm using jQuery sortables to accomplish this. The challenge I am facing is that each room has a maximum capacity limit. For example, some rooms can only hold 3 people, wh ...

What is the best way to calculate the number of div elements with a specific class that are contained within parent div elements with another specific class?

Is there a way to count the number of elements with the class '.child' in each container and then add a sentence containing that count inside each container? <div class='container'> <div class='child'></di ...

Animating Text with CSS for Different Message Lengths

I have been exploring alternatives to the marquee tag and discovered a way to achieve this through CSS. However, the messages I am working with vary in length. Is there an alternative to setting the '45s' attribute to maybe 100% so that regardles ...

Compatibility with IE9: Using jQuery to send an AJAX POST request

I'm currently facing an issue with making a POST request from my website to a server that is not on the same domain. The functionality is working seamlessly on Chrome, Firefox, and IE10+, but I need to ensure it works on IE9 as well. Below is the cod ...

JavaScript drop-down menu malfunctioning

I am currently in the process of learning web development languages, and I'm attempting to create a dropdown list using JavaScript (I previously tried in CSS without success). I would greatly appreciate it if you could review my code and let me know ...

Leveraging jQuery event listeners within a Javascript class initialization

Recently delving into OOP in JavaScript, I've been revamping some of my old code to make it more reusable. Instead of leaving them as inline scripts, I decided to encapsulate them within JavaScript classes. Here is an example of one of my classes: ...

Steps for transforming this grid into a single-column list for mobile viewing

I have designed a unique menu grid with a center text and other menu options surrounding it. I am looking to make this grid display as a single line on mobile devices, with the center large text space disappearing on smaller screens. To achieve this, I cr ...

What steps do I need to take in order to successfully make a checkbox?

I am attempting to use Angularjs to set a checkbox to true. When saved, it should store an integer value (1 or 0) in my field. Below is the code snippet for the view: <input type="checkbox" ng-model="lis.SMSPromotion" id="SMSPromotion" ng-init="checke ...

Tips for avoiding the initial rendering of react components on a page when styled-components are not yet loaded

I have developed a unique custom component library using React and styled-components for creating reusable components. I then imported this library into my nextJS project, but I noticed that the styles from the custom component library are not applied duri ...

After developing a new like button feature, I noticed that upon refreshing the page, the total like count resets to zero

Imagine creating a like button that, when clicked, first checks if the user is logged in. Only users who are logged in can click the like button and have the like count increase by 1. However, every time the page is refreshed, the like count resets to 0. W ...

I encountered a SyntaxError indicating a missing ")" right before utilizing jQuery in my code

When trying to run the code below, I encountered an error in the console stating SyntaxError: missing ) after argument list. $(document).ready(function() { $(".blog-sidebar-form form").before("<p class="blog-sidebar-inform>Dummy Text</ ...

Chrome displaying an extJs Button image

Could it be that Chrome is evolving into the new IE in terms of CSS issues? Here is the code I have for creating ExtJS buttons within an accordion: var button = Ext.create('Ext.Button', { text: '<img src="'+resp.sellers.externa ...

Is there a way to slow down the falling effect on my navigation bar?

As I was working on my personal website, I had a creative idea to add a falling-down animated effect instead of keeping the layout fixed. Utilizing bootstrap for navigation, I encountered some difficulty in controlling the speed of the falling effect. Any ...

A pair of buttons each displaying a unique div block

I am facing an issue with my jQuery script. I want to be able to click on one of the previewed text associated with a button and then have the other one close automatically. The desired effect is for the text to slide down using slideDown() and disappear ...

What are some ways to customize the player for Youtube videos?

I'm looking to recreate the design of Youtube videos on my website when I embed them. The image below is just an example, but it reflects the simplicity I am aiming for. Any guidance or examples would be greatly appreciated, as I am unsure where to be ...

Any tips on how to personalize the loading animation for single pages using CSS and GIFs?

presentLoading(message) { this.loading = this.loadingCtrl.create({ dismissOnPageChange: false, spinner:'hide', content:`<img class="load" src="assets/dual.gif" />`, }); this.loading.present(); } Hello there! I am working with the ...

It is impossible to replicate the toggle functionality of the navbar-collapse feature from Bootstrap's official website

Currently, I'm delving into Bootstrap by attempting to replicate the 'Company' theme showcased on W3schools. My main struggle lies with getting the navbar-collapse feature to work properly. Despite creating the toggle, clicking on it fails t ...

stopping the collapsible animation of bootstrap before the medium breakpoint

I recently developed a website using Bootstrap. On my site, there is a navigation bar with menu options including 'About,' 'My Projects,' and 'Contact Me' that are hidden behind an expandable menu when the page width is less t ...

Adjust the jQuery resizable handlers on the fly

I am encountering an issue when attempting to change the handler on a resizable element. Initially, I used : $(line) .draggable({containment:"parent"}) .resizable({ containment:"parent", handles: "e, w" }); N ...

Eliminate the jQuery AJAX timestamp from the URL parameters

Is there a way to eliminate the jQuery AJAX cache buster code (_=3452345235) from string URLs? While working on a global AJAX fail handler, I need to identify which URL failed. However, every time I locate the failed request's URL, the jQuery cache q ...