Set navigation menu item active in Handlebars partial - javascript

Currently, I am repeating code for my navigation menu on every single tab, but I want to use partials so there's no duplicate code.
This is what I am using (below), with the active class on a different list element depending on the file. Instead, I'd like to use a partial {{> fruits-nav}}, but I can't find any information on how I would set the active class depending on which file is including the partial.
<div id="table-nav-tabs">
<ul class="nav nav-tabs">
<li class="apple">apple</li>
<li class="active orange">orange</li>
<li class="mango">mango</li>
<li class="pineapple">pineapple</li>
</ul>
</div>

I think you can even make it slightly simpler and more readable:
<div id="table-nav-tabs">
<ul class="nav nav-tabs">
<li class="{{#if active.apple}}active{{/if}} apple">apple</li>
<li class="{{#if active.orange}}active{{/if}} orange">orange</li>
<li class="{{#if active.mango}}active{{/if}} mango">mango</li>
<li class="{{#if active.pineapple}}active{{/if}} pineapple">pineapple</li>
</ul>
</div>
and while rendering:
active: { pineapple: true }

You can pass data to a partial so you can do this in your partial:
<div id="table-nav-tabs">
<ul class="nav nav-tabs">
<li class="{{#if active_apple}}active{{/if}} apple">apple</li>
<li class="{{#if active_orange}}active{{/if}} orange">orange</li>
<li class="{{#if active_mango}}active{{/if}} mango">mango</li>
<li class="{{#if active_pineapple}}active{{/if}} pineapple">pineapple</li>
</ul>
</div>
and then pull it in like this:
{{> fruits-nav active}}
and just make sure active has he appropriate flag set for the current fruit.
Demo: http://jsfiddle.net/ambiguous/GesND/

Related

jQuery, toggle menu item

I have the following nav menu.
If I click h1, t1, t2, t3 need to toggle (hide or show), other things stay as it is.
If I click h3, t6, t7, t8 need to toggle, other things stay.
Basically, h1, h2, h3 is the header and rest is children.
$(document).ready(function() {
/* In mobile menu, heading click, toggle sub */
$('.slicknav_nav li.heading').click(function() {
//$(this).find('ul').slideToggle();
$('.slicknav_nav li:not(.heading)').toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="heading">h1</li>
<li class="first">t1</li>
<li class="">t2</li>
<li class="">t3</li>
<li class="heading">h2</li>
<li class="first">t4</li>
<li class="">t5</li>
<li class="heading">h3</li>
<li class="first">t6</li>
<li class="">t7</li>
<li class="">t8</li>
</ul>
I have made some code. Obviously, it toggles other peer as well. Is it a way to only toggle the current item's "children"?
You can use nextUntil of jQuery method like below.
$(this).nextUntil(".heading").toggle();
Example:
$(document).ready(function() {
/* In mobile menu, heading click, toggle sub */
$('.slicknav_nav li.heading').click(function() {
$(this).nextUntil(".heading").toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="slicknav_nav">
<li class="heading">h1</li>
<li class="first">t1</li>
<li class="">t2</li>
<li class="">t3</li>
<li class="heading">h2</li>
<li class="first">t4</li>
<li class="">t5</li>
<li class="heading">h3</li>
<li class="first">t6</li>
<li class="">t7</li>
<li class="">t8</li>
</ul>
One thought would be to wrap each heading group in a div, then wrap the children in another div inside that one. Could do something like this for layout:
<ul>
<div class="headingContainer">
<li class="heading">h1</li>
<div class="childContainer">
<li class="first">t1</li>
<li class="">t2</li>
<li class="">t3</li>
</div>
</div>
<div class="headingContainer">
<li class="heading">h2</li>
<div class="childContainer">
<li class="first">t4</li>
<li class="">t5</li>
</div>
</div>
<div class="headingContainer">
<li class="heading">h3</li>
<div class="childContainer">
<li class="first">t6</li>
<li class="">t7</li>
<li class="">t8</li>
</div>
</div>
</ul>
Then, in your jQuery, you could use the .siblings() selector to select the sibling div in the dom. Run toggleClass("heading") on the selection and that should do the trick if I'm understanding this correctly.

Dropdown in nav bar not working - items in dropdown all link to the same thing (UIKit framework)

What I would like to happen: The first three list items in the nav bar should correspond to the first three content items in the content area. The three list items in the dropdown should correspond to the remaining three content items. Hovering over the dropdown icon should display the list but the dropdown icon shouldn't link to anywhere.
What's actually happening: The first three list items work properly and link to the first three content items. The dropdown box animates properly, but the items in it all link to the 4th content item. Clicking the dropdown box's icon also links to the 4th item.
Here is the code (A lot of the code is generated, so I grabbed the code from FireBug, which is why the "uk-active" classes and "aria-hidden" attributes are there):
<nav class="uk-navbar">
<ul class="uk-navbar-nav" data-uk-switcher="{connect:'#content-area'}">
<li class="uk-active" aria-expanded="true">
Dashboard
</li>
<li aria-expanded="false">
Summary
</li>
<li aria-expanded="false">
Details
</li>
<li id="settings-btn-container" class="uk-parent" data-uk-dropdown="" aria-expanded="false" aria-haspopup="true">
<a href="">
<i class="uk-icon-cog"></i>
</a>
<div id="settings-dropdown-container" class="uk-dropdown uk-dropdown-navbar uk-dropdown-bottom" aria-hidden="true" style="top: 40px; left: 0px;" tabindex="">
<ul id="settings-dropdown" class="uk-nav uk-nav-navbar">
<li>
Upgrade
</li>
<li>
Configure
</li>
<li>
Settings
</li>
</ul>
</div>
</li>
</ul>
</nav>
<ul id="content-area" class="uk-switcher">
<li id="content-dashboard" class="parent.uk-container uk-container-center uk-active" aria-hidden="false">...</li>
<li id="content-summary" aria-hidden="true">...</li>
<li id="content-details" aria-hidden="true">...</li>
<li id="content-upgrade" aria-hidden="true">...</li>
<li id="content-config" aria-hidden="true">...</li>
<li id="content-settings" aria-hidden="true">...</li>
</ul>
Basically, the "on click" event handler for the 4th content item is getting added to the "settings-btn-container" list item and no event handlers are getting added to the list items under the dropdown. I can't figure out how to get the event handlers to bind to the dropdown list items instead.
Try being more explicit to the UIkit Switcher component about what constitutes a "toggle".
In the snippet below, I've used these settings:
{
connect: '#content-area',
toggle: '.toggle-link'
}
The default value for toggle, in the UIkit Switcher component is >*, which you'll probably recognize as a selector for "the first immediate child element of any type". Since the links in your dropdown are not immediate descendants, no Switcher events were fired when they were clicked.
By broadening the "toggle" definition to all .toggle-link elements in the switcher, each of your links gets mapped to the corresponding <li> in the #content-area element.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.2/js/uikit.js"></script>
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.2/css/uikit.min.css'>
<nav class="uk-navbar">
<ul id="switcher-menu" class="uk-navbar-nav" data-uk-switcher="{connect: '#content-area', toggle: '.toggle-link'}">
<li class="uk-active toggle-link">Dashboard</li>
<li class="toggle-link">Summary</li>
<li class="toggle-link">Details</li>
<li id="settings-btn-container" class="uk-parent" data-uk-dropdown>
<i class="uk-icon-cog"></i>
<div id="settings-dropdown-container" class="uk-dropdown uk-dropdown-navbar uk-dropdown-bottom">
<ul id="settings-dropdown" class="uk-nav uk-nav-navbar">
<li class="toggle-link">Upgrade</li>
<li class="toggle-link">Configure</li>
<li class="toggle-link">Settings</li>
</ul>
</div>
</li>
</ul>
</nav>
<div class="uk-container uk-container-center">
<ul id="content-area" class="uk-switcher">
<li class="uk-active">... (Dashboard)</li>
<li>... (Content Summary)</li>
<li>... (Content Details)</li>
<li>... (Content Upgrade)</li>
<li>... (Content Config)</li>
<li>... (Content Settings)</li>
</ul>
</div>

Collapsible menu has all drop down menu's expanded

I'm creating a website for a project and i'm not allowed to use frameworks (so no bootstrap), i've now run into a problem where the navigation bar when collapsed (screen width under 800px) has all the individual links expanded, rather than being in individual categories.
I've uploaded this website to
here
The Html nav bar
<nav role="navigation" id="cssmenu">
<ul>
<li class="active">Home</li>
<li class="has-sub">Courses
<ul>
<li>Digital Media</li>
<li>Web Development</li>
<li>Journalism</li>
<li class="last">Information & Communications</li>
</ul>
</li>
<li class="has-sub">Facilities
<ul>
<li>Societies</li>
<li>Jobs and Placements</li>
<li class="last">Library</li>
</ul>
</li>
<li class="has-sub">Manchester & Student Life
<ul>
<li>Travel</li>
<li>Attractions</li>
<li class="last">Nightlife</li>
</ul>
</li>
<li class="has-sub">Student Help
<ul>
<li>Finance</li>
<li>Student Union</li>
<li class="last">Assistance</li>
</ul>
</li>
<li class="last">Contact</li>
</ul>
</nav>
The Jquery script
( function( $ ) {
$( document ).ready(function() {
// Cache the elements we'll need
var menu = $('#cssmenu');
var menuList = menu.find('ul:first');
var listItems = menu.find('li').not('#responsive-tab');
// Create responsive trigger
menuList.prepend('<li id="responsive-tab">Digi-Co</li>');
// Toggle menu visibility
menu.on('click', '#responsive-tab', function(){
listItems.slideToggle('fast');
listItems.addClass('collapsed');
});
});
} )( jQuery );
The css can also be found
here
Any help will be appreciated, i'm sure its just a simple overwriting syntax, but i can't be too sure, whether it's that or if it's a scripting problem.
Thank you.

How to swap css class depending on the page the user is on

<nav id="navMenu" class="navMenu">
<ul>
<li class="active homePage">
Home
</li>
<li class="resourcesPage">
Resources
<ul>
<li><span class="icon elem0"></span>Restaurants</li>
<li><span class="icon elem0"></span>Businesses</li>
<li><span class="icon elem0"></span>Events</li>
<li><span class="icon elem0"></span>e-Learning</li>
<li><span class="icon elem0"></span>Other</li>
</ul>
</li>
<li class="spiPage">
Spi
<ul>
<li><span class="icon elem1"></span>Q&A</li>
<li><span class="icon elem1"></span>Knowledge</li>
</ul>
</li>
<li class="aboutPage">
About Us
</li>
<li class="contactPage">
Contact Us
</li>
</ul>
</nav>
How can I modify the below script so if any of the resources page is in the Url, the LI with the class resourcesPage will have the active class. Only one of the parent LI will have the active class.
$(function() {
var pathName = getPageName(window.location.pathname);
if (pathName.split("_").toLowerCase() == 1) { //if the path is anything related to the home page
$("."+pathName+"Page").addClass("active"); //add the 'active' class to the homePage LI and remove it from the rest
}
else if (pathName.split("_").toLowerCase() == 1) { //if the path is anything related to the resources page
$("."+pathName+"Page").addClass("active"); //add the 'active' class to the resourcePage LI and remove it from the rest
}
else if (pathName.split("_").toLowerCase() == 1) { //if the path is anything related to the spi page
$("."+pathName+"Page").addClass("active"); //add the 'active' class to the spiPage LI and remove it from the rest
}
else if (pathName.split("_").toLowerCase() == 1) { //if the path is anything related to the about page
$("."+pathName+"Page").addClass("active"); //add the 'active' class to the aboutPage LI and remove it from the rest
}
else if (pathName.split("_").toLowerCase() == 1) { //if the path is anything related to the contact page
$("."+pathName+"Page").addClass("active"); //add the 'active' class to the contactPage LI and remove it from the rest
}
});
UPDATE:
<nav id="navMenu" class="navMenu">
<ul>
<li class="active homePage" id="home">
Home
</li>
<li class="resourcesPage" id="resources">
Resources
<ul>
<li id="resources_ins"><span class="icon elem0"></span>Institutions</li>
<li id="resources_restaurants"><span class="icon elem0"></span>Restaurants</li>
<li id="resources_businesses"><span class="icon elem0"></span>Businesses</li>
<li id="resources_events"><span class="icon elem0"></span>Events</li>
<li id="resources_elearn"><span class="icon elem0"></span>e-Learning</li>
<li id="resources_other"><span class="icon elem0"></span>Other</li>
</ul>
</li>
<li class="spiPage" id="spi">
Spi
<ul>
<li id="spi_qa"><span class="icon elem1"></span>Q&A</li>
<li id="spi_knowledge"><span class="icon elem1"></span>Knowledge</li>
<li id="spi_marriage"><span class="icon elem1"></span>Family</li>
<li id="spi_dwif"><span class="icon elem1"></span>Inter</li>
</ul>
</li>
<li class="expressionPage" id="expression">
Expression
<ul>
<li id="expression_multimedia"><span class="icon elem3"></span>Multimedia</li>
<li id="expression_eduact"><span class="icon elem3"></span>Education/Activity</li>
<li id="expression_ouwo"><span class="icon elem3"></span>Our World</li>
<li id="expression_poems"><span class="icon elem3"></span>Poems</li>
<li id="expression_other"><span class="icon elem3"></span>Other</li>
</ul>
</li>
<li class="aboutPage" id="about">
About Us
</li>
<li class="contactPage" id="contact">
Contact Us
</li>
</ul>
</nav>
So for example, in the code above, if I am on the homepage, the home LI ID will be set to active (as shown above). If I am on the resources or any of the sub resources page, the resources LI ID will be set to active class and all the other LI will remove the active class.
A script that would do what you are looking for is essentially
$(function() {
var pathName = window.location.pathname.split('/')[1];
$('li[href='+pathName+']').addClass('active').parents('li').addClass('active');
});
This is generally considered bad design and non-performant but it will do exactly what I think you are trying to do.
The reason it will be non-performant is because you aren't using efficient selectors (you don't have id attributes directly derived from the page name for example so you can't map 1:1). These kind of jquery selectors traverse the entire DOM looking for matches, and as such can't get exactly what you want. In contrast, if you have an id which is just a parsed version of the page name, then you don't have to traverse the entire DOM, and you can use $('#'+idName) which will be very fast.
More information about jquery performance: http://24ways.org/2011/your-jquery-now-with-less-suck
EDIT: Added more about actually refactoring the original document:
Rewriting the original document with ids which are the pathnames without the .php gets you:
<nav id="navMenu" class="navMenu">
<ul>
<li class="active homePage" id="index">
Home
</li>
<li class="resourcesPage" id="resources">
Resources
<ul>
<li id="resources_restaurants"><span class="icon elem0"></span>Restaurants</li>
<li id="resources_businesses"><span class="icon elem0"></span>Businesses</li>
<li id="resouces_events"><span class="icon elem0"></span>Events</li>
<li id="resouces_elearning"><span class="icon elem0"></span>e-Learning</li>
<li id="resouces_other><span class="icon elem0"></span>Other</li>
</ul>
</li>
<li class="spiPage">
Spi
<ul>
<li id="spi_qa"><span class="icon elem1"></span>Q&A</li>
<li id="spi_knowledge"><span class="icon elem1"></span>Knowledge</li>
</ul>
</li>
<li class="aboutPage">
About Us
</li>
<li class="contactPage">
Contact Us
</li>
</ul>
</nav>
With that you could rewrite your javascript to be:
$(function() {
//This double split is an easy way to parse out just the filename portion
//it equivalently means "id" in this case
var pathName = window.location.pathname.split('/')[1].split('.')[0];
//find limits results to only li tags, it is a safety method which can be
//ignored if you're confident in your html structure
$('#'+pathName).find('li').addClass('active').parents('li').addClass('active');
});
you can also use PHP to do so in case the user has JS disabled:
<?php if(expression) $style = "active"; else $style="";
<div class="something <?php echo $style ?>" >
</div>
some people disable JS, some browsers don't have good JS functions, it is a good practice to make important stuff be server side.
This is what solved the issue for me:
<nav id="navMenu" class="navMenu">
<ul>
<li class="active homePage" id="home">
Home
</li>
<li class="resourcesPage" id="resources">
Resources
<ul>
<li id="resources_ins"><span class="icon elem0"></span>Institutions</li>
<li id="resources_restaurants"><span class="icon elem0"></span>Restaurants</li>
<li id="resources_businesses"><span class="icon elem0"></span>Businesses</li>
<li id="resources_events"><span class="icon elem0"></span>Events</li>
<li id="resources_elearn"><span class="icon elem0"></span>e-Learning</li>
<li id="resources_other"><span class="icon elem0"></span>Other</li>
</ul>
</li>
<li class="spiPage" id="spi">
Spi
<ul>
<li id="spi_qa"><span class="icon elem1"></span>Q&A</li>
<li id="spi_knowledge"><span class="icon elem1"></span>Knowledge</li>
<li id="spi_marriage"><span class="icon elem1"></span>Family</li>
<li id="spi_dwif"><span class="icon elem1"></span>Inter</li>
</ul>
</li>
<li class="expressionPage" id="expression">
Expression
<ul>
<li id="expression_multimedia"><span class="icon elem3"></span>Multimedia</li>
<li id="expression_eduact"><span class="icon elem3"></span>Education/Activity</li>
<li id="expression_ouwo"><span class="icon elem3"></span>Our World</li>
<li id="expression_poems"><span class="icon elem3"></span>Poems</li>
<li id="expression_other"><span class="icon elem3"></span>Other</li>
</ul>
</li>
<li class="aboutPage" id="about">
About Us
</li>
<li class="contactPage" id="contact">
Contact Us
</li>
</ul>
</nav>
Script:
var pathName = getPageName(window.location.pathname);
var getSubPath = pathName.split("_")[0];
$('.ulHeaderMenu li').removeClass('active');
$('.ulHeaderMenu li.'+getSubPath+'Page').addClass('active');
Thanks to #lassombra for the pointer to have it working.

Javascript Get active menu item data-option-value and put it into a VAR

<div class="option-combo department">
<span class="label_menu">Department:</span>
<ul id="filters" class="option-set clearfix" data-option-key="filter">
<li class="department-button">All</li>
<li class="department-button">Sales</li>
<li class="department-button">Marketing</li>
<li class="department-button">Training</li>
<li class="department-button">Communications</li>
</ul>
</div>
I want to get the active list items attribute, data-option-value, and add it to the commiunication data-option-value dynamically
I am using isotope
Try this to filter out the other classes and just show the specific communications for each department
<li class="department-button">Communications</li>

Categories

Resources