0

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 Answers1

1

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?

Jeramiah Harland
  • 854
  • 7
  • 15
  • Yeah thats exactly how its supposed to work! but the problem is that the icon is placed with an :after css statement. And i don't know how to overwrite the default javascript and or html of wordpress (So i can disable the current system). Do you know how i can do this? – Jurjen Folkertsma Jul 28 '17 at 16:12
  • Unfortunately not, I actually was wondering if you were using a pseudo element or a custom walker to add that arrow in. I tried to quickly see how to target pseudo elements and found only disappointment. What I can recommend is looking into "nav_menu_link_attributes" filter in WordPress, I will update my answer and try to help further. – Jeramiah Harland Jul 28 '17 at 16:21
  • Thanks! already much appreciated that you are looking into it. Let me know if there are any updates! :) – Jurjen Folkertsma Jul 28 '17 at 16:47
  • Or do you know another way this is indeed possible? (Maybe another type of wp element) – Jurjen Folkertsma Jul 28 '17 at 16:47
  • Without using a custom walker I couldn't find a simple solution really. Please see my updated answer though. – Jeramiah Harland Jul 28 '17 at 17:03
  • I will checkout the custom walker, the jquery didnt work for me. Maybe this piece of code in functions.php can change anything? put the code in my question. – Jurjen Folkertsma Jul 28 '17 at 18:06
  • 1
    Still at it, I've updated my answer to elaborate on the jQuery solution. Otherwise I'm afraid a walker is the best way to go. Even with that you'd be doing something similar where you create an actual element you can target instead of a pseudo one. The biggest difference of course is that the Walker would do it with PHP on the server as part of the menu building process and jQuery would do it client once the page is ready. – Jeramiah Harland Jul 31 '17 at 14:41