0
votes

I'M using a custom wordpress menu as a sidebar element (Sidebar made in visual composer lay-out).

Now the problem is that the complete box is a trigger for opening the dropdown menu, This means the main item link can never be activated.

I would love to make only the arrow a trigger for the submenu to open, but can't find any way as the arrow and menu item text are in the same 'ahref'.

This forces me to duplicate menu items in my menu. enter image description here

Markup created by wordpress

<li id="menu-item-333" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-325 current_page_item menu-item-333"><a href="http://www.site.nl/link/" target="_blank">Dorp</a></li>

The down arrow is added using an "after:" css statement.

#PB .widget_nav_menu .menu-item-has-children a:after {
    content: "\f107";
    font-family: FontAwesome;
}

Code i THINK is asociated with it

 /**
         * Custom menu widget toggles
         *
         * @since 2.0.0
         */
        customMenuWidgetAccordion: function() {
            var self = this;

            // Open toggle for active page
            $( '.widget_nav_menu .current-menu-ancestor', self.config.$siteMain ).addClass( 'active' ).children( 'ul' ).show();

            // Toggle items
            $( '.widget_nav_menu', self.config.$siteMain ).each( function() {
                var $hasChildren = $( this ).find( '.menu-item-has-children' );
                $hasChildren.each( function() {
                    $( this ).addClass( 'parent' );
                    var $links = $( this ).children( 'a' );
                    $links.on( 'click', function( event ) {
                        var $linkParent = $( this ).parent( 'li' );
                        var $allParents = $linkParent.parents( 'li' );
                        if ( ! $linkParent.hasClass( 'active' ) ) {
                            $hasChildren.not( $allParents ).removeClass( 'active' ).children( '.sub-menu' ).slideUp( 'fast' );
                            $linkParent.addClass( 'active' ).children( '.sub-menu' ).stop( true, true ).slideDown( 'fast' );
                        } else {
                            $linkParent.removeClass( 'active' ).children( '.sub-menu' ).stop( true, true ).slideUp( 'fast' );
                        }
                        return false;
                    } );
                } );
            } );

        },

In a nutshell: how can i make only the icon clickable for activating the dropdown menu and make the rest of the button send me to the correct page.

1

1 Answers

1
votes

Without seeing the markup, I assume the <a> is something like this?

<a href="page.html">Dorp <i class="arrow-down"></i></a>

With the arrow-down being the arrow, you can do something like:

$(document).ready(function(){
   $(document).on('click', function(e){
         if($(e.target).hasClass('arrow-down')){

              // If the target has the class 'arrow-down' preventDefault to stop normal behavior
              e.preventDefault();

              // Function to display dropdown

         }
    });
})

You can see it in action on this JsFiddle.

UPDATE: Since this arrow is created with a pseudo class on a WordPress menu, things aren't so simple. I recommend a custom walker to achieve your goal. Unfortunately I'm unable to quickly put together an example myself, but I can point you to this link which covers exactly what you're trying to do

Another possible solution I just thought of, not necessarily and ideal one though, would be to use jQuery to add that arrow to all <a> containing sub-menus once the page is loaded.

I've updated this answer to elaborate on how I would accomplish it, using the code you provided:

Change the CSS that creates the pseudo element to a class:

#PB .widget_nav_menu .menu-item-has-children a .arrow-down {
    content: "\f107";
    font-family: FontAwesome;
}

After that, take a look below, I commented where I put the code appending the arrows, etc. This should work, but I wasn't able to build a jsFiddle to provide a working example:

/**
* Custom menu widget toggles
*
* @since 2.0.0
*/
        customMenuWidgetAccordion: function() {

            var self = this;

            // Append the arrows here
            var i = $('<i>').attr({
                class: 'arrow-down'
            });
            $('.menu-button-has-children a').append(i);

            // Open toggle for active page
            $( '.widget_nav_menu .current-menu-ancestor', self.config.$siteMain ).addClass( 'active' ).children( 'ul' ).show();

            // Toggle items
            $( '.widget_nav_menu', self.config.$siteMain ).each( function() {

                var $hasChildren = $( this ).find( '.menu-item-has-children' );

                $hasChildren.each( function() {

                    $( this ).addClass( 'parent' );
                    var $links = $( this ).children( 'a' );

                    $links.on( 'click', function( event ) {

                        // Here is our preventDefault if the target is arrow-down
                        if($(event.target).hasClass('arrow-down')){
                            // If the target has the class 'arrow-down' preventDefault to stop normal behavior
                            event.preventDefault();
                        }

                        var $linkParent = $( this ).parent( 'li' );
                        var $allParents = $linkParent.parents( 'li' );

                        if ( ! $linkParent.hasClass( 'active' ) ) {
                            $hasChildren.not( $allParents ).removeClass( 'active' ).children( '.sub-menu' ).slideUp( 'fast' );
                            $linkParent.addClass( 'active' ).children( '.sub-menu' ).stop( true, true ).slideDown( 'fast' );
                        } else {
                            $linkParent.removeClass( 'active' ).children( '.sub-menu' ).stop( true, true ).slideUp( 'fast' );
                        }

                        return false;
                    } );
                } );
            } );

        },

Depending on how the <i> is positioned, things might jump out of place once it's appended to the <a>. I'd set it with absolute positioning and fade it in.

If you're still unable to get it working, can you create a jsFiddle I can work on?