0

On my responsive dropdown menu I want to be able to do the following when a menu item is clicked:

  • If link has no children then functions as normal
  • If parent link has children then default is prevented for parent and children are displayed
  • The parent and children links now function as normal (i.e. no preventDefault after click to show child items)

The (non-functining) JQuery I've done is below and here is my Fiddle (Edited - simplified the example)

var parentWithChildren = $('region-responsive-nav ul');
//var parentWithChildren = $('region-responsive-nav ul').children('has:ul').length > 0 );

$('.region-responsive-nav ul ul').hide();
//prevent default once
if (parentWithChildren.children('has:ul').length > 0 ) {
      $('.region-responsive-nav ul li').one(function(event) {
        $(this).children('ul').slideToggle();
        event.preventDefault();
      });
}else{
    //open link immediately 
}

See below for the markup. (Since simplified in my edit. Please note that it has two <ul> inside the same <li> and there is not much I can do about this.

<nav class="region-responsive-nav">
    <ul>
        <li>One</li>
        <li>Two
            <ul class="sub">
                <li>Two A</li>
                <li>Two B</li>
            </ul>
        </li>
    </ul>
    <ul>
        <li>Three</li>
        <li>Four
            <ul>
                <li>Four A</li>
                <li>Four B</li>
            </ul>
        </li>   
    </ul>
</nav>

I think I'm fairly close (at least in concept) so ainy pointers would be appreciated.

Thanks in advance

Bert Murphy
  • 37
  • 1
  • 7
  • It would really help if your fiddle wasn't filled with all the clutter of css and the open trigger – jcuenod May 14 '15 at 18:59
  • I'll admit that the HTML is cluttered but I tried to address this in my OP whilst also providing the real life example in the Fiddle. As for the trigger and accompanying CSS, I don't see the problem. They are key to functionality and therefore I included them. Do you have any constructive suggestion about how to solve the problem?. – Bert Murphy May 14 '15 at 20:57
  • 1
    To be honest, I was going to play around with the fiddle but just didn't feel like wading through all the extraneous muck to figure out what was going on. I get that you tried to articulate the problem in the question but when I hit the fiddle to see what you were working with I very quickly lost the patience to try to solve the problem - sorry, just saying it like it is. – jcuenod May 14 '15 at 20:59
  • OK, i'll strip it down and edit my OP. – Bert Murphy May 14 '15 at 21:01
  • As suggested I've simplified the fiddle and added it to the OP – Bert Murphy May 14 '15 at 21:17
  • I've had a go, let me know whether it does what you want. – jcuenod May 14 '15 at 21:23

2 Answers2

1

Try this event handler to handle onclick for the parent <li>'s:

$('.region-responsive-nav ul li').on('click', function(event) {
    // Check if the <li> has hidden children 
    if ($(this).children('ul:not(:visible)').length > 0) {
        event.preventDefault();
        // Display children
    } else {
        // Normal behaviour
    }
});

This will check whether the <li> has any child <ul> elements that are hidden when it's clicked and you can handle that accordingly.

Keep in mind this event handler will bind to the children <li>'s too. If you only want this behaviour for the first set of <li>'s in your code, use this selector instead: $('.region-responsive-nav > ul > li').


UPDATE:

JSFiddle demonstrating this solution based on your updated JSFiddle: https://jsfiddle.net/tadhbb3a/2/

I've made all the list items into links so you can see that the links with children just show the children without sending the user to the link, but those without children work as normal links.

Also as you've clarified in one of your comments you want the parent links that have children visible already to work as normal links, so that's added too.

Martin Charchar
  • 181
  • 1
  • 6
  • Thanks for the reply, Martin. I'll try it and report back. – Bert Murphy May 14 '15 at 21:02
  • I've just updated my answer with a JSFiddle based on yours above. I've also just seen your comment on jcuenod's answer and it seems like you want additional functionality - I'll update my answer to add that shortly. – Martin Charchar May 14 '15 at 21:37
  • Ok @BertMurphy I've changed my answer to have the parent behave normally if the children are already visible (i.e. if it's been clicked once already). Give that a try. – Martin Charchar May 14 '15 at 21:44
0

Okay, it's rudimentary but I think it does what you want:

$(document).ready(function () {
    // Hide the submenus that should be hidden
    $('li > ul').hide();

    // Make the li elements that don't have submenus do something
    $("li:not(:has(ul))").click(function() {
        alert("do something");
    });

    // I used hover to show and hide but any event will do
    // (only for li elements that have submenus)
    $("li:has(ul)").hover(function() {
        $(this).children("ul").slideToggle();
    }, function() {
        $(this).children("ul").slideToggle();
    });
});

See the fiddle

jcuenod
  • 55,835
  • 14
  • 65
  • 102
  • Hmmm, not quite but thanks. The problem for me all along is that ultimately I want the initial click on the parent div to open the children (i.e. preventDefault and also slide toggle) and thereafter the parent should behave like any other link in a menu. Maybe I'm misunderstanding your Fiddle but I don't think the above addresses this. Click on the parent once and it opens the child. Click on the parent the second time and it opens the link. If there is no child then open the link as normal. – Bert Murphy May 14 '15 at 21:33
  • @BertMurphy ahh, okay: you need to ignore the hover stuff and set up `$("li:has(ul)").click` to check whether the child is open. If the child is open, go somewhere, if not, open the child. Does that make sense? – jcuenod May 15 '15 at 06:55
  • Thanks jcuenod. Martin's method fit perfectly but I get what you are saying. Thanks for the advice. Also, point taken about my original fiddle being bloated. I'll aim to strip back any future examples I have. – Bert Murphy May 17 '15 at 17:40
  • @BertMurphy no problem. Also, the only reason I commented was so that you knew why you weren't getting help - it was really an attempt to be constructive. Glad that you seem to have taken it well. – jcuenod May 17 '15 at 18:28