{Javascript} dropdown menu (with submenus) stays open when opening another menu - javascript

I have a question about JS dropdown menus.
I have multiple menus button, each has submenus. Unfortunatly once I open a menu, it stays open even if I click on another menus buttons and they visually overlap.
I´ve tried different solutions found on here, but apparently I´m doing something wrong.
Here is what I have:
$( '.main-navigation .page_item_has_children > a, .main-navigation .menu-item-has-children > a, .widget_nav_menu .page_item_has_children > a, .widget_nav_menu .menu-item-has-children > a' ).append( '<button class="dropdown-toggle" aria-expanded="false"/>' );
$( '.dropdown-toggle' ).click( function( event ) {
event.preventDefault();
$( this ).toggleClass( 'toggle-on' );
$( this ).parent().next( '.children, .sub-menu' ).toggleClass( 'toggle-on' );
$( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );
} );
And:
jQuery(document).ready(function($){
$(window).resize(function(){
var socialHeight = $('.social-icons').outerHeight();
$('.social-icons').css('margin-top',-(socialHeight/2));
}).resize();
});
Any advice is appreciated!

Related

Dropdown Toggle Button disappears on IE 11

I created a custom them website in WordPress. http://www.seattlestormbasketball.com/stormcares/
Everything is working great, except in IE 11. The dropdown toggle on the navigation menu appears on the home page but not on any of the inside pages.
JS
(function( $ ) {
var masthead, menuToggle, siteNavContain, siteNavigation;
function initMainNavigation( container ) {
// Add dropdown toggle that displays child menu items.
var dropdownToggle = $( '<button />', { 'class': 'dropdown-toggle', 'aria-expanded': false })
.append( $( '<i />', { 'class': 'dropdown-symbol fa fa-plus-circle' }) )
.append( $( '<span />', { 'class': 'screen-reader-text', text: ezmacScreenReaderText.expand }) );
container.find( '.menu-item-has-children > a, .page_item_has_children > a' ).after( dropdownToggle );
container.find( '.dropdown-toggle' ).click( function( e ) {
var _this = $( this ),
screenReaderSpan = _this.find( '.screen-reader-text' );
e.preventDefault();
_this.toggleClass( 'toggled-on' );
_this.next( '.children, .sub-menu' ).toggleClass( 'toggled-on' );
_this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );
screenReaderSpan.text( screenReaderSpan.text() === ezmacScreenReaderText.expand ? ezmacScreenReaderText.collapse : ezmacScreenReaderText.expand );
});
}
initMainNavigation( $( '.main-navigation' ) );
masthead = $( '#masthead' );
menuToggle = masthead.find( '.menu-toggle' );
siteNavContain = masthead.find( '.main-navigation' );
siteNavigation = masthead.find( '.main-navigation > div > ul' );
// Enable menuToggle.
(function() {
// Return early if menuToggle is missing.
if ( ! menuToggle.length ) {
return;
}
// Add an initial value for the attribute.
menuToggle.attr( 'aria-expanded', 'false' );
menuToggle.on( 'click.ezmac', function() {
siteNavContain.toggleClass( 'toggled-on' );
$( this ).attr( 'aria-expanded', siteNavContain.hasClass( 'toggled-on' ) );
});
})();
// Fix sub-menus for touch devices and better focus for hidden submenu items for accessibility.
(function() {
if ( ! siteNavigation.length || ! siteNavigation.children().length ) {
return;
}
// Toggle `focus` class to allow submenu access on tablets.
function toggleFocusClassTouchScreen() {
if ( 'none' === $( '.menu-toggle' ).css( 'display' ) ) {
$( document.body ).on( 'touchstart.ezmac', function( e ) {
if ( ! $( e.target ).closest( '.main-navigation li' ).length ) {
$( '.main-navigation li' ).removeClass( 'focus' );
}
});
siteNavigation.find( '.menu-item-has-children > a, .page_item_has_children > a' )
.on( 'touchstart.ezmac', function( e ) {
var el = $( this ).parent( 'li' );
if ( ! el.hasClass( 'focus' ) ) {
e.preventDefault();
el.toggleClass( 'focus' );
el.siblings( '.focus' ).removeClass( 'focus' );
}
});
} else {
siteNavigation.find( '.menu-item-has-children > a, .page_item_has_children > a' ).unbind( 'touchstart.ezmac' );
}
}
if ( 'ontouchstart' in window ) {
$( window ).on( 'resize.ezmac', toggleFocusClassTouchScreen );
toggleFocusClassTouchScreen();
}
siteNavigation.find( 'a' ).on( 'focus.ezmac blur.ezmac', function() {
$( this ).parents( '.menu-item, .page_item' ).toggleClass( 'focus' );
});
})();
//Change Font-Awesome dropdown symbols on toggle
$(".dropdown-symbol").click(function(e) {
if( $(this).hasClass("fa-plus-circle") ) {
$(this).removeClass("fa-plus-circle").addClass("fa-minus-circle");
} else {
// if other menus are open remove open class and add closed
$(this).siblings().removeClass("fa-plus-circle").addClass("fa-minus-circle");
$(this).removeClass("fa-minus-circle").addClass("fa-plus-circle");
}
});
})( jQuery );
Like I mentioned before, works great in all other browsers and even older versions of IE but not IE 11
Any help would be greatly appreciated. Thanks!

If And statement in javascript?

I'm trying to have a statement 'if scroll and has a class, do an action.
however I don't manage to have it working . . .
I've tried below code:
$(document).scroll(function() {
if($(this).scrollTop() > 1 && $(".menu-toggle").hasClass(".toggle-on")) {
// $('.toggle-on')
$( 'body' ).removeClass( 'overlay-open' );
$( '.menu-toggle' ).removeClass( 'toggle-on hide' );
$( '.menu-toggle' ).attr( 'aria-expanded', 'false' );
$( '.overlay--menu' ).removeClass( 'show' ).resize();
$( '.search-toggle' ).removeClass( 'hide' );
$( '.chapter-toggle' ).removeClass( 'hide' );
$('.overlay--menu').addClass('hidemenu');
}
});
any help will be really amazing !!
Thanks for your time !
You almost had it!
You have your right parenthesis out of place.
Try changing the conditional from,
if($(this).scrollTop() > 1) && $(".menu-toggle").hasClass("toggle-on") {
to
if($(this).scrollTop() > 1 && $(".menu-toggle").hasClass("toggle-on")){
The basic idea is that you'd have both conditionals within the parenthesis, separated by &&, such as
if (this && that).

WordPress. Contact form 7. Set field required if value of another field > 0

I have a task for WordPress website which use Contact Form 7 plugin.
How do I set textarea as required only if value of another field ( [number* number-265 min:0 id:antala] ) > 0 ?
So, it should be not like [textarea* stelnummera id:stelnummera] because this textarea will be required every time.
I have created javascript code which add some classes, attributes and alert message (how it add Contact Form 7 plugin):
$( "#antala" ).change(function() {
if ( $( "#antala" ).val() > 0 ) {
$( "#stelnummera" ).addClass( "wpcf7-validates-as-required wpcf7-not-valid" ).attr( "aria-required", "true" ).attr( "aria-invalid", "true" );
} else {
$( "#stelnummera" ).removeClass( "wpcf7-validates-as-required wpcf7-not-valid" ).attr( "aria-required", "false" ).attr( "aria-invalid", "false" );
}
});
$( ".wpcf7-form" ).submit(function( event ) {
if ( $( "#antala" ).val() > 0 && $( "#stelnummera" ).val() == "" ) {
event.preventDefault();
$( "#stelnummera" ).attr( "aria-invalid", "true" );
$( "#stelnummera" ).after( "<span class='custom-alert' style='color: #f00;'>Dette felt skal udfyldes</span>" );
if ($ ( ".invalid" ).length == 0 ) {
$ ( ".wpcf7-form" ).addClass( "invalid" );
}
} else {
$( "#stelnummera" ).attr( "aria-invalid", "false" );
$( ".custom-alert" ).remove();
}
});
But the form still submitting
I have just hide this textarea until value of number field will be > 0.
Textarea is required [textarea* stelnummera id:stelnummera]
$("#stelnummera").parent().parent().hide();
$("#stelnummera").val('n/a');
$("#antala").change(function() {
if ($("#antala").val() > 0) {
$("#stelnummera").parent().parent().show();
$("#stelnummera").val('');
} else {
$("#stelnummera").parent().parent().hide();
$("#stelnummera").val('n/a');
}
});

How to add links to tabbing order when they're made visible with CSS?

Links that are subject to display: none aren't in the default tabbing order. However, when they're revealed - e.g. CSS for a drop-down menu reveals a sub-menu when a parent link gains focus - they still aren't in the tabbing order. Presumably JavaScript is required, but simply setting tabindex="0" does nothing.
The problem here is that as soon as you tab off the "Top level page with child" link, the CSS is updated and the parent of the anchor becomes display:none before the anchor can receive focus. You will need to use JavaScript to solve this problem and delay the change in the CSS using a timeout until you can determine whether the loss of focus has resulted in the focus shifting to the child element.
Setting tabindex="0" when the parent is display:none will not help, display:none means that the content might as well not be in the document.
I've come up with a solution that basically works: http://codepen.io/gyrus/pen/waKjKv/ There seem to be some issues in IE, I'm working on that. But the general idea is:
Add a small delay before hiding the drop-down
Set a data attribute to flag whether any links inside the drop-down have focus, and check this before hiding
This is just the jQuery, check the pen for more:
jQuery( document ).ready( function( $ ) {
$( '.nav' ).on( 'mouseenter focusin', '.menu-level-0.menu-item-has-children', function( e ) {
var el = $( this );
// Show sub-menu
el.attr( 'aria-expanded', 'true' )
.find( '.sub-menu-wrapper' ).show();
}).on( 'mouseleave focusout', '.menu-level-0.menu-item-has-children', function( e ) {
var el = $( this );
// Only hide sub-menu after a short delay, so links get a chance to catch focus from tabbing
setTimeout( function() {
var smw = el.find( '.sub-menu-wrapper' );
if ( smw.attr( 'data-has-focus' ) !== 'true' ) {
el.attr( 'aria-expanded', 'false' );
smw.hide();
}
}, 100 );
}).on( 'focusin', '.sub-menu-wrapper', function( e ) {
var el = $( this );
el.attr( 'data-has-focus', 'true' );
}).on( 'focusout', '.sub-menu-wrapper', function( e ) {
var el = $( this );
el.attr( 'data-has-focus', 'false' );
// Hide sub-menu on the way out
el.hide().parents( '.menu-level-0' ).attr( 'aria-expanded', 'false' );
});
});

Internet Explorer triggering js hover immediately after page load

I got a navigation menu that opens a submenu dropdown on hovering over the first level items. After a click on a first level link the mouse is on the same position on the new page .... so here's the thing:
On normal browsers (Firefox, Safari and Chrome) it triggers the hover effect only after the mouse moves.
On Internet Explorer it seems that the hover is triggered immediatly after load because the dropdown opens directly (which is pretty annoying). I even mapped the hover function in a mousemove but that doesn't change anything (does ie even trigger mousemove on load without even moving Oo).
Here the simplified code:
jQuery( '#mainmenucontainer' ).hoverIntent( {
over: function() {
jQuery( 'body' ).addClass( 'mainmenu_active' );
},
out: function() {
jQuery( 'body' ).removeClass( 'mainmenu_active' );
}
} );
jQuery( '#mainmenu > ul > li' ).hoverIntent( {
over: function() {
jQuery( '#mainmenu > ul > li' ).removeClass( 'active' );
jQuery( this ).addClass( 'active' );
}
} );

Categories

Resources