Maintain the expanded menu even after selecting a sub-item using jQuery

After conducting a thorough search, I was unable to find exactly what I needed.

I have successfully implemented cookies on my menu so that when the page is reloaded, it remembers which menus were open.

However, I noticed that clicking on a sub-item of Hyperlink 2 will close Hyperlink 2 entirely. Is there a way to keep it open?

This link may provide some insight.

I attempted to use the simulate click method from this source, but it did not work as expected, possibly due to incorrect placement.

While I am still fairly new to JavaScript/jQuery, I am gradually improving my skills!

Thank you

<ul class="nav">
<li><a>Hyperlink 1</a>

</li>
<li class="drop"><a>Hyperlink 2</a>

    <ul id="m1">
        <li><a href="#">Hyperlink Sub</a>

        </li>
        <li><a href="#">Hyperlink Sub</a>

        </li>
    </ul>
</li>
<li class="drop"><a>Hyperlink 3</a>

    <ul id="m2">
        <li><a href="#">Hyperlink Sub</a>

        </li>
        <li><a href="#">Hyperlink Sub</a>

        </li>
    </ul>
</li>
<li class="drop"><a>Hyperlink 4</a>

    <ul id="m3">
        <li><a href="#">Hyperlink Sub</a>

        </li>
        <li><a href="#">Hyperlink Sub</a>

        </li>
    </ul>
</li>

jQuery(function ($) {
// jQuery code in here can safely use $
$('.nav li')
    .css({
    cursor: "pointer"
});

$(".drop")
    .on('click', function () {
    $(this).toggleClass('open');
    $(this).find('ul').toggle();
    $.cookie('open_items', 'the_value');
    openItems = new Array();
    $("li.drop").each(function (index, item) {
        if ($(item).hasClass('open')) {
            openItems.push(index);
        }
    });
    $.cookie('open_items', openItems.join(','));
});

if ($.cookie('open_items') && $.cookie('open_items').length > 0) {
    previouslyOpenItems = $.cookie('open_items');
    openItemIndexes = previouslyOpenItems.split(',');
    $(openItemIndexes).each(function (index, item) {
        $("li.drop").eq(item).addClass('open').find('ul').toggle();
    });
}
});

Answer №1

Prevent click event from affecting children elements:

VIEW DEMO


$(".drop li a")
    .on('click', function (e) {
        e.stopPropagation();
    });

Answer №2

Try changing the selector for the click event to ".drop>a" and see if that resolves the issue. Make sure to adjust the way you handle the li element like shown below:

$(".drop>a").on('click', function (eventData) {
    var $listItem = $(this).closest('li');

    $listItem.find('ul').toggle();
    $listItem.toggleClass('open');

    $.cookie('open_items', 'the_value');
    openItems = new Array();

    $("li.drop").each(function (index, item) {
        if ($(item).hasClass('open')) {
            openItems.push(index);
        }
    });
    $.cookie('open_items', openItems.join(','));
});

Check out the DEMO here - It shows how to keep the menu open when an inner link is clicked.


Answer №3

In order to make the click event work properly, it is recommended not to apply it directly to the .drop elements but to their children instead. You can achieve this by implementing the following structure:

<div class="drop">
   <a class="click-to-open">Click here to open</a>
      <ul>
         <li>Sub links etc...</li>
         <li>...</li>
      </ul>
 </div>


 $('.drop .click-to-open').click(function() {

   //toggle the open class and perform other actions if needed

   //utilize .parent() to target the .drop div
   $(this).parent().toggleClass('open');

 });

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 fixed table header is misaligned with the body columns' width

I was looking for a way to add a vertical scrollbar to my table, and I ended up wrapping the entire table in a div. The result was that the table head was fixed in position. Is there a simpler method to include a scrollbar in a table without affecting the ...

Tips for displaying live data in the rows of Element UI's Table

Recently, I've been working with a table that looks like this. <v-table :data="data"> <v-table-column prop="data.attribute" label="Attribute"> </v-table-column> </v-table> Instead of displaying data.attribute in the co ...

Tips for selectively executing a script based on whether the DIV is within the viewport

I have a created a script as shown below: jQuery(function($) { $('.count').countTo({ from: 0, to: '400', speed: '3000', refreshInterval: 50, onComplete: func ...

Dimensional adjustments for Semantic-ui dropdowns

Currently, we are attempting to transform bootstrap into semantic-ui. <select id="sayfaArama" class="ui search dropdown"> <option value="">Searching in pages...</option> </select> Take a look at this image I have encountered ...

Creating a deferred object in jQuery programmatically with parameters

As a beginner in javascript and jquery, I am currently exploring the use of jquery's Deferred object to ensure a loop completes before executing a specific action. The functions within the loop do not have any specific order dependency, meaning functi ...

What is the best way to transfer a value from state to a function as a parameter?

I have been struggling to find a way to pass the value from state (personId) as a parameter to the function (fetchPersonInfo). Despite my efforts, nothing seems to be working. That's why I decided to seek your assistance on this matter. class Page ex ...

The iframe is not large enough to contain all the HTML content

I'm encountering a problem with a website I'm currently developing - specifically, I am struggling to embed an HTML document into an iframe in a manner that fills the entire page. Additionally, I am utilizing Angular to retrieve the HTML document ...

Book Roulette: Your Next Random Read

I created a code for a random quote generator and now I want to create something similar, but with images this time. I am looking to add a feature on my page where it can recommend a book by displaying its cover image when a button is clicked. For the pre ...

What is the relationship between $.when, apply(), and $.done() within the scope of this function?

I recently received this function from a helpful SO user that allows for returning a variable number of jQuery $.get() requests. The initial part seems pretty straightforward, but I am struggling to understand how $.when(), apply(), and $.done() are inte ...

Setting up the foundation for a Bootstrap footer: A step-by-step guide

I've been struggling to implement the HTML5 structure within Bootstrap 4 grid system to match the design shown in the attached images. The layout should resemble the top image when viewed on a phone, phablet, or tablet in portrait mode, and the bottom ...

What is the best way to show the response data in an input text field within an HTML form?

I'm new to working with node.js and I've encountered an issue. I need to display the data of the currently logged in user in input fields. With the following code, I can access the data of the logged-in user and display it on the console: See O ...

Utilizing jQuery DataTable with an AJAX call to retrieve data from a JSON

I am facing an issue while trying to retrieve data from Entity Framework in ASP.NET MVC using a jQuery data table with AJAX. The data is not displaying in the table as expected. I need assistance in identifying the mistake in my approach. Upon executing t ...

Different option for positioning elements in CSS besides using the float

I am currently working on developing a new application that involves serializing the topbar and sidebar and surrounding them with a form tag, while displaying the sidebar and results side by side. My initial attempt involved using flex layout, but I have ...

Utilize Angular to Transfer HTTP Array Data from a Service to a Component

As I work on developing an app with Angular, my current challenge involves a service that retrieves an Array of Data from an online source. My goal is to make this array accessible in other components but I'm facing difficulty in passing the data to t ...

Ways to modify the .MuiSelect-nativeInput element within Material-UI

const styles = makeStyles((theme) => ({ root: { margin: "0px 20px" }, textStyle: { fontFamily: "Comfortaa", }, container: {}, textField: { fontFamily: "Comfortaa", }, dropDownFormSize: { width: &qu ...

Utilize npm node to dynamically adjust screen resolution

Currently developing a game using electron. I'm experiencing FPS drops when running it in full-screen mode. To improve the game's performance, I need to change the screen resolution programmatically. My current resolution is 1280x800, but I would ...

Transforming a Bootstrap 4 dropdown navbar by replacing the caret with Fontawesome 5 icons for Plus and Minus

After spending several days trying to find a solution, I am still struggling. I have managed to create a responsive Navbar with Dropdowns using Bootstrap 4. Now, my goal is to replace the caret with a Plus and Minus sign at the end of each row on small dev ...

The function to automatically refresh the page upon the user receiving a new message is currently malfunctioning

Having trouble with the page reloading when a new message is received by the user. I have been working on developing a PHP chat application that allows both admins and users to chat with each other. Whenever a new message is sent, the user has to manuall ...

Tips on dividing a div into two separate pages when converting to PDF

I am working on an asp.net MVC project and I need to convert a HTML div into a PDF with two separate pages. Here is an example of my code: HTML Code <div class="row" id="mycanvas"> <p>This is the first part of my content.</p> <p ...

Ways to receive attributes prior to the Render event

I am a beginner in React and encountering an issue with retrieving props from the parent before the child is rendered. https://i.sstatic.net/CLAdH.png My problem involves an Editor component that passes a string as props to a button. The string is collect ...