Toggle the sliding effect on click using jQuery

I'm currently working on a sidebar menu that involves a lot of javascript. The challenge I am facing is with the submenu items within some of the menu items. When I click on a menu item, its submenu opens using jQuery slideToggle, but when I click on another menu item, the submenus also toggle open. I want to make it so that only one submenu is open at a time.

Apologies if my description is confusing, but I hope you get the gist of what I'm trying to achieve.

You can view the code on jsFiddle

<script>
$(document).ready(function(){
    var guts = $('#guts').css('display');
    var guts2 = $('#guts2').css('display');
    var guts3 = $('#guts3').css('display');
  $("#click").click(function(){
        $("#guts").slideToggle("fast"); 
        if (guts2 == 'block')
            $("#guts2").slideToggle("fast");
        if (guts3 == 'block')
            $("#guts3").slideToggle("fast");
        $(this).addClass("active").siblings('.active').removeClass('active');
  });
  $("#click2").click(function(){
        $("#guts2").slideToggle("fast");
        if (guts == 'block')
            $("#guts").slideToggle("fast");
        if (guts3 == 'block')
            $("#guts3").slideToggle("fast");
        $(this).addClass("active").siblings('.active').removeClass('active');
  });
    $("#click3").click(function(){
        $("#guts3").slideToggle("fast");
                if (guts2 == 'block')
        $("#guts2").slideToggle("fast");
        if (guts == 'block')
            $("#guts").slideToggle("fast");
        $(this).addClass("active").siblings('.active').removeClass('active');
  });
    $("#home").click(function(){
        $(this).addClass("active").siblings('.active').removeClass('active');
        if (guts == 'block')
            $("#guts").slideToggle("fast");
        if (guts2 == 'block')
            $("#guts2").slideToggle("fast");
        if (guts3 == 'block')
            $("#guts3").slideToggle("fast");
  });
});
</script>       
    <div id="links">

        <a href="#/Home" id="home" class="active">Home</a>
        <a href="#/Staff" id="click">Staff</a>
            <div id="guts">
                <a href="#" class="guts">• Staff List</a>
            </div>
        <a href="#/Locations" id="click2">Locations</a>
            <div id="guts2">
                <a href="#" class="guts">• Location List</a>
            </div>
        <a href="#/Calendar" id="click3">Calendar</a>   
    </div>

Answer №1

The scope of your variables is causing the issue you are facing. By declaring them globally, they do not update as expected when each click function is called. Instead, they retain their initial values from page load, which is 'none'.

To resolve this, place the variables inside the functions so that they update when called.

Rather than:

var guts = $('#guts').css('display');
var guts2 = $('#guts2').css('display');
var guts3 = $('#guts3').css('display');
$("#click").click(function(){
    $("#guts").slideToggle("fast"); 
    if (guts2 == 'block')
        $("#guts2").slideToggle("fast");
    if (guts3 == 'block')
        $("#guts3").slideToggle("fast");
    $(this).addClass("active").siblings('.active').removeClass('active');
});

Use this instead:

$("#click").click(function(){
    var guts = $('#guts').css('display');
    var guts2 = $('#guts2').css('display');
    var guts3 = $('#guts3').css('display');
    $("#guts").slideToggle("fast");
    if (guts2 == 'block') {
        $("#guts2").slideToggle("fast");
    }
    if (guts3 == 'block') {
        $("#guts3").slideToggle("fast");
    }
    $(this).addClass("active").siblings('.active').removeClass('active');
});

Alternatively:

var guts, guts2, guts3;

$("#click").click(function(){
    guts = $('#guts').css('display');
    guts2 = $('#guts2').css('display');
    guts3 = $('#guts3').css('display');
    $("#guts").slideToggle("fast");
    if (guts2 == 'block') {
        $("#guts2").slideToggle("fast");
    }
    if (guts3 == 'block') {
        $("#guts3").slideToggle("fast");
    }
    $(this).addClass("active").siblings('.active').removeClass('active');
});

Check out the DEMO here

Answer №2

I decided to revamp the code using an unordered list menu, which happens to be my top choice for creating menus. Instead of assigning a click event handler to each individual menu item, I opted for a single event that manages all interactions (you can easily customize specific items by adding them within conditional statements).

Here is the updated HTML structure:

<ul id="links">
    <li><a href="#/">Home</a></li>
    <li><a href="#/locations">Locations</a>
        <ul class="submenu">
            <li><a href="#/locations/list">Location List</a></li>
        </ul>
    </li>
    <li><a href="#/staff">Staff</a>
        <ul class="submenu">
            <li><a href="#/staff/list">Staff List</a></li>
        </ul>
    </li>
    <li><a href="#/calendar">Calendar</a></li>
</ul>

Below is the JavaScript part:

$(document).ready(function () {

    $('#links a').click(function () {

        if (!$(this).hasClass('.active')) {
            $('.active').removeClass('active');
            $(this).addClass('active');
        }

        if ($(this).hasClass('toggled')) {

            $(this).removeClass('toggled');
            $(this).next().slideToggle(250);

        } else if ($(this).next('ul').length > 0) {

                $('.toggled').next().slideToggle(250);
                $('.toggled').removeClass('toggled');
                $(this).addClass('toggled');
                $(this).next().slideToggle(250);

        } else if(!$(this).parent().parent().hasClass('submenu')) {

                $('.toggled').next().slideToggle(250);
                $('.toggled').removeClass('toggled');

        }

    return false;

    })

});

Lastly, here are some CSS styles applied:

#links,
#links ul{
    display: block;
    padding: 0;
    margin: 0;
    list-style: none;
    text-align: center;
}

#links a {
  display: block;
  padding: 1px 0
}

#links a.active {
    background-color: rgb(0, 173, 255);
}

#links ul{
    display: none
}

You can view the DEMO to see it in action.

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

A completely css-based interpretation of google images

I am in the process of trying to recreate the layout found in Google Photos and stumbled upon this intriguing page https://github.com/xieranmaya/blog/issues/6 . I am particularly interested in the final result of the project, which can be viewed here: . U ...

The value of the comment box with the ID $(CommentBoxId) is not being captured

When a user enters data in the comment box and clicks the corresponding submit button, I am successfully passing id, CompanyId, WorkId, and CommentBoxId to the code behind to update the record. However, I am encountering an issue as I also want to pass the ...

The function does not modify the content of an element in Internet Explorer versions 10 to 11

I'm currently working on a layout that needs to support IE10-11. Everything seems to be functioning well overall, except for the .text jQuery method. My goal is to have certain elements change their text when a button on the page is clicked, based on ...

Error: The javascript function is unable to execute because undefined is not recognized as a function

I've been struggling with an error in my "bubble sort" function that I wrote to organize a list of images. Whenever I run the function, I keep getting the message "Uncaught TypeError: undefined is not a function". Can anyone provide some guidance? $j ...

Utilizing Angular for Custom Styling

I have a strange question that may sound silly, but I am having trouble separating two divs - one on the left and one on the right. I attempted to use the CSS float property, but it doesn't seem to be working. https://i.sstatic.net/OYLY4.png EDIT: ...

Having difficulty retrieving JSON data using Jquery

After receiving a JSON string as a response from the server, I encountered an issue when trying to access the objects within the response, only to receive an "undefined" message. Here is the AJAX request being made: $.ajax({ url: 'somefi ...

Learn how to use props in React with the PluralSight tutorial - don't forget to

While working through a React tutorial on PluralSight, I encountered an error that I'm not sure is my mistake or not. The tutorial directed me to the starting point at JS Complete using this URL: As I followed along, the tutorial led me to the follo ...

Understanding the readability of JavaScript arrays.ORDeciphering

Recently, I've been working with a JSON OBJECT that looks something like this { "kay1": "value1", "key2": "value2", "key3":{ "key31": "value31", "key32": "value32", "key33": "value33" } } However, I am interested in converting it ...

Looking for a way to locate specific cells within an HTML table? See how you can achieve this using either R or

I am working on an HTML page that contains a large table with multiple rows and columns. I only need to access one specific cell within this table. For instance, the code snippet below shows two rows of the table, each with 6 columns. <tr> <t ...

Utilizing Pusher to transfer user deposit and withdrawal information from client to Node.js (Express) server: A step-by-step guide

I have subscribed to "my-channel" and connected to "my-event" on the client side. pusher.html <!DOCTYPE html> <head> <title>Pusher Test</title> <script src="https://js.pusher.com/5.0/pusher.min.js"></script> < ...

CSS sidebars are failing to display on the website

Working on a supposedly simple template turned out to be more challenging than expected. The template lacked sidebars, so I attempted to add them myself. However, my test text isn't displaying as intended. Could someone please help me identify the mi ...

Error encountered in Bootstrap: Cannot access property 'fn' as it is undefined

I am currently working on developing an Electron application utilizing Bootstrap. However, I have encountered an error message that states: Uncaught TypeError: Cannot read property 'fn' of undefined at setTransitionEndSupport (bootstrap.js:122) ...

Implementing promises in my MEAN stack application

I have developed a controller that performs a Bing search based on the user's input in the URL. After testing the controller with console.log, it seems to be functioning correctly and I have set the variable to return the results. However, when trying ...

How can I select a checkbox dynamically during runtime?

I am working on a JavaScript code that needs to add the checked option to a checkbox if it has an id or value of 2 at runtime. I have tried the following code, but unfortunately, I am unable to check the checkbox. Do you have any ideas on how to solve th ...

Activate the q-file toggle for the Quasar framework when a different button is selected

How can I make the file selector q-file toggle in Quasar framework when a specific button is clicked? My current attempt: When this button is clicked, it should toggle the q-file: <button @click="toggleFileSelector">Toggle File Selector&l ...

If a user clicks on an element twice in a row, the div will be hidden. Otherwise, it will remain

My navigation bar consists of several items and a div located next to it, as shown below: <nav> <a id="a"></a> <a id="b"></a> <a id="c"></a> </nav> <div id="menu-col"></div> If the same li ...

choosing a section within a table cell

This seems like a simple task, but I'm encountering some difficulties $("#info-table tbody tr").each(function(){ $(this).find(".label").addClass("black"); }); .black{ font-weight:bold; } <script src="https://ajax.googleapis.com/ajax/libs/j ...

Encountering Datepicker Issue in Your Angularjs App?

I am currently working on a web application using Angular JS and I encountered an error when trying to incorporate a date picker. The error message displayed is "elem.datepicker is not a function" To implement the datepicker, I found reference code in thi ...

Combining two variables in AngularJS seamlessly, without explicit instruction

In the realm of Controllers resides my beloved home.js: angular.module("HomeApp", ["BaseApp"]) .controller("MainCtrl", ["$http", "$window", "BaseService", function($http, $window, BaseService) { var self = this; self.posts = BaseServ ...

Is it possible to achieve seamless image transitions in Firefox like it does in Chrome?

To achieve the desired effect, you may need to use some javascript. Visit aditagarwal.com for more information. Styling with CSS: .images-wrapper{ position: fixed; left: 0; top: 80px; bottom: 0; width: 100%; height: 100vh; an ...