$(window).load(function(){ fNavHeightFixer(); fMobileResponsiveHandler(); // Add event handler to call fOnMenuDropdownOpen when a dropdown menu is opened $('.navbar .dropdown').on('shown.bs.dropdown', fOnDropdownOpen); // Add event handle to call fOnMenuDropdownClose when a dropdown menu is closed $('.dropdown').on('hidden.bs.dropdown', fOnDropdownClose ); // Loop through all the menus on the page $('.dropdown').each( function() { // Call the dropdown open menu incase user has a navigation bar already open fOnDropdownOpen( $(this), true ); }); }); $(window).resize(function(){ fNavHeightFixer(); fMobileResponsiveHandler(); }); function fMobileResponsiveHandler(){ if($(window).width() < 550){ $('#social-icon-container').removeClass('col-xs-7').addClass('col-xs-12'); $('#login-icon-container').removeClass('col-xs-5').addClass('col-xs-12'); $('#search-col').removeClass('col-xs-6').addClass('col-xs-12'); $('#nav-col').removeClass('col-xs-6').addClass('col-xs-12'); $('#nav-col').prependTo('#second-nav-row'); } else { $('#social-icon-container').removeClass('col-xs-12').addClass('col-xs-7'); $('#login-icon-container').removeClass('col-xs-12').addClass('col-xs-5'); $('#search-col').removeClass('col-xs-12').addClass('col-xs-6'); $('#nav-col').removeClass('col-xs-12').addClass('col-xs-6'); $('#nav-col').appendTo('#second-nav-row'); } /*if ($('#affiliate-logo-col').css('display') == 'none'){ $('#header-img-col').removeClass('col-xs-9').addClass('col-xs-12'); } else { $('#header-img-col').removeClass('col-xs-12').addClass('col-xs-9'); }*/ } $('#hamburger-menu-id').click(function(){ document.getElementById('hamburger-menu-id').style.pointerEvents = 'none'; $('#hamburger-span-container').toggleClass("span-container-rotate"); $('#hmbg-line-3').toggleClass("hmbg-span-3-trans"); $('#hmbg-line-2').toggleClass("hmbg-span-2-trans"); $('#hmbg-line-1').toggleClass("hmbg-span-1-trans"); setTimeout(function(){ document.getElementById('hamburger-menu-id').style.pointerEvents = 'auto'; }, 300) }); function fValidateEmail(email) { var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i; return re.test(email); } $('#emailinput1').on('keyup', function() { if(fValidateEmail($('#emailinput1').val())){ $(this).css('background-color','#c4e1ac'); } else { $(this).css('background-color','#ffc0c2'); } }); function fNavHeightFixer(){ $('#affiliate-logo-col').height($('#header-img-col').height()); $('#affiliate-logo').css('top','50%'); } /* * 8) Navigation Width Fixer Function * ================================== */ /* fOnDropdownOpen =============== This function is called when the navigation dropdown menu is opened, the function is called by detecting when we hover over a dropdown element. It applies width fixes to the navigation dropdown box, and ensures the text doesn't go off screen. We add an input of oDropdown, allowing us to call the function on every dropdown menu when the page loads, meaning if the user is hovering over a dropdown before the page has fully loaded then they will still see the correct navigation layout (rather than the min-width) If the input isn't set then we just get $(this) as it must of been passed from the hover event. If you want to call this function and don't have an input, then this will not work, you will need to loop through all .dropdown elements and call the function passing in the oDropdown paramater. */ function fOnDropdownOpen( oDropdown, bCalledFromInit ) { // Store the menu object, if the input is defined then we manually called, so use the input object, otherwise find the correct object var oMenu = oDropdown.jquery ? oDropdown.find(".dropdown-menu") : $(this).find(".dropdown-menu"); // Store all menu links var aLis = oMenu.find("li"); // Set the max-width for the dropdown menu oMenu.css("max-width", window.innerWidth - oMenu.offset().left + "px" ); // Set the max-width for the dropdown menu oMenu.css("max-height", window.innerHeight - oMenu.offset().top - 20 + "px" ); // If the called from init isn't true if( bCalledFromInit != true ) { // Set it to false, incase it is incorrectly assinged bCalledFromInit = false; } /* NAVIGATION DROPDOWN TEXT WIDTH - UPDATED ON 14/01/2019 - START ============================================================== Before this update, sub menu's on the navigation tab wrapped at a very small px, clients were complaining Result before update; Result after update; --------- ---------- |DROPDOWN| |DROPDOWN| ------------------ ------------------------------------------------------ |This is my inner | |This is my inner category, the sub menu for dropdown| |category, the sub| ------------------------------------------------------ |menu for dropdown| |This is another category | ------------------- ------------------------------------------------------ |This is another | |category | ------------------- We have to do this fix in JS otherwise it would reworking the navigation system for this theme or wouldn't support IE11, so we just simply apply this small fix. It's a bit hacky but it works. */ // Store the menu's text links var oLinkElement = oMenu.find(".navigation-dropdown-item"); // Store the max width of the text var nMenuText_MaxWidth = window.innerWidth / 2; // Store the current width of the text, this also stops the navigation text going off screen var nMenuTextWidth_Current = window.innerWidth - oMenu.offset().left - 40; // Add the no-wrap class to the element, this stops text being able to go on a new line oLinkElement.addClass("no-wrap"); // Loop through each link in the menu oLinkElement.each( function() { // Store the link locally oLink = $( this ); // If the calculated current width is greater than the max-width if( nMenuTextWidth_Current > nMenuText_MaxWidth ) { // Set the text current width to the max width nMenuTextWidth_Current = nMenuText_MaxWidth; } // If the text link (a tag)'s width is greater than the calculated width if( parseInt(oLink.css("width").replace("px", "") ) > nMenuTextWidth_Current ) { // Remove the no-wrap class so text can be wrapped onto a new line oLink.removeClass("no-wrap"); // Set the width of the navigation to the calculted width oLink.css("width", nMenuTextWidth_Current + "px"); // Set the a link to the new calculated length oLink.find("a").css("width", nMenuTextWidth_Current + "px"); } }); /* MULTIPLE NAVIGATION COLUMNS =========================== To ensure that sub menus with tons of content in don't look bad, we need to support multi column layouts. Result before update; Result after update; --------- --------- |DROPDOWN| |DROPDOWN| ------------------ ------------------------------------ |My Dropdown 1 | |My Dropdown 1 | My Dropdown 4 | ------------------ ------------------------------------ |My Dropdown 2 | |My Dropdown 2 | My Dropdown 5 | ------------------ ------------------------------------ |My Dropdown 3 | |My Dropdown 3 | My Dropdown 6 | ------------------ ------------------------------------ |My Dropdown 4 | ------------------ |My Dropdown 5 | ------------------ |My Dropdown 6 | ------------------ It's important to note though, that when the dropdown box is too big (as in all the categories wont fit on the screen) it simply overflows, or if on mobile it also overflows, this means that all categories can be seen but in a scrollable menu instead. This must be dont to cater for clients that might have a stupid amount of sub menu items. */ // If we are on mobile if(window.innerWidth <= 768) { // If the menu will overflow if( oMenu.height() + oMenu.offset().top > window.innerHeight ) { // Just add a scroll y oMenu.css("overflow-y", "scroll"); } // Loop through every list item aLis.each( function() { // Remove any padding left $(this).css("paddingLeft", ""); }); } // If the menu isn't on mobile else { // If there isn't a nav-column if( !oMenu.find(".nav-column").length && bCalledFromInit == false) { // Store teh amount of menu items var nNavMenuCount = aLis.length; // Store the max amount of menu items var nAmountPerColumn = 15; // The amount of padding to the left of the element we have var nLeftPadding = 20; // Store the number var nNumberOfColumns = Math.ceil(nNavMenuCount / nAmountPerColumn); // If the number of columns isn't 1 if( nNumberOfColumns != 1 ) { // Store if it the sub categories will fit var bWillItFit = 1; // Store the current itteration of the LIs var nLIIndex = 0; /* WIDTH ===== */ // Store the max menu width var nMaxMenuWidth = 0; // Store the total menu width var nMenuWidth = 0; // Loop through every list item aLis.each( function() { // Increment the LI index nLIIndex++; // If this list item is the biggest in the column if( $(this).width() > nMaxMenuWidth ) { // Set the max width nMaxMenuWidth = $(this).width(); } // If we have reached the maximum amount of items in a column if ( nLIIndex == nAmountPerColumn ) { // Increment the width by the max width nMenuWidth += nMaxMenuWidth; // Set the menu width (reset it) nMaxMenuWidth = 0; // Reset the index nLIIndex = 0; } }); // If we haven't added the last max menu width if( nLIIndex != 0 ) { // Add it nMenuWidth += nMaxMenuWidth; } // If there is more than 1 column if( nNumberOfColumns > 1 ) { // Then we need to take the padding into account for every column after the first 1 nMenuWidth += (nNumberOfColumns - 1) * nLeftPadding; } // If the menu width is in range if( oMenu.offset().left + nMenuWidth > window.innerWidth ) { // It wont fit, so set the overflow bWillItFit = 0; } /* HEIGHT ====== */ // If the width is fine, then calculate the height if( bWillItFit ) { // Store the current column height var nColumnHeight = 0; // Store the biggest column height var nGreatestColumnHeight = 0; // Loop through all list items for ( var i = 0; i <= aLis.length; i++ ) { // Incrmeent the column height by the list item's height nColumnHeight += aLis.eq(i-1).outerHeight(); // If we have reaced the max amount of items per column if(i % nAmountPerColumn === 0) { // If the column height is greater than the max height if(nColumnHeight > nGreatestColumnHeight) { // Store the max column height for later nGreatestColumnHeight = nColumnHeight } // Reset the column height nColumnHeight = 0; } } } // If the column wont fit if( ( ( (oMenu.offset().top - $(window).scrollTop() ) - 20 ) + (nGreatestColumnHeight) ) > window.innerHeight ) { // Set that it wont fit bWillItFit = 0; } /* MULTI COLUMN FIX ================ */ // If it won't fit, just make it scrollable.. if(!bWillItFit) { // Just make the element scrollable oMenu.css("overflow-y", "scroll"); } // If the colum wrap will fit on the screen else { // Store the left position of the columns var nLeft = 0; // Loop through all the columns (that we can make) for(var i = 1; i<= nNumberOfColumns; i++) { // Add the navigation column to the menu oMenu.append(''); } // Loop through all the LI items for(var i = 1; i <= nNavMenuCount; i++) { // Work out what column number we are on var nColumnNumber = Math.ceil( i / nAmountPerColumn ); // If this isn't the first column, add some padding if( nColumnNumber > 1 ) { // Set the padding of this LI item aLis.eq( i - 1).css("paddingLeft", nLeftPadding); } // Add the LI item to the correct column oMenu.find(".nav-column-"+nColumnNumber).append(aLis.eq(i-1)); } // Loop through all the columns for(var i = 1; i<= nNumberOfColumns; i++) { // Set the correct left position for the column $("#nav-col-" + i).css("left", nLeft); // Set the correct height for the column $("#nav-col-" + i).css("height", nGreatestColumnHeight + 5); // Incremnet the left position by the width of this column, we minus 1 to fix strange offset error nLeft += $("#nav-col-" + i).width() - 1; } } } } } } /* fOnDropdownClose ================ Function is called when the navigation dropdown is closed, this resets the navigation dropdown states to their default values */ function fOnDropdownClose() { // Store the dropdown-menu var oMenu = $(this).find(".dropdown-menu"); // Store the menus var oLinkElement = oMenu.find(".navigation-dropdown-item"); // Set the menus css width to empty oLinkElement.css("width", ""); // Set the a link to the new width of empty oLinkElement.find("a").css("width", ""); // Set the max-width for the dropdown menu oMenu.css("max-width", ""); // Set the max-height for the dropdown menu oMenu.css("max-height", ""); }