How to programmatically open my accordion menu - javascript

I'm using a very simple jQuery accordion script but what I'd like to achieve is a way to programmatically open a menu item on page load. Ultimately this will be when a user browses directly to a page within a submenu, that menu opens to identify where they are. I just cannot figure out how to trigger the opening on load... Any help appreciated.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JQuery navigation test 2</title>
<script src="js/jquery-1.11.1.min.js" type="text/javascript"></script>
<style>
#nav {
float: left;
width: 280px;
border-top: 1px solid #999;
border-right: 1px solid #999;
border-left: 1px solid #999;
}
#nav li a {
display: block;
padding: 10px 15px;
background: #ccc;
border-top: 1px solid #eee;
border-bottom: 1px solid #999;
text-decoration: none;
color: #000;
}
#nav li a:hover, #nav li a.active {
background: #999;
color: #fff;
}
#nav li ul {
display: none;
}
#nav li ul li a {
padding: 10px 25px;
background: #ececec;
border-bottom: 1px dotted #ccc;
}
</style>
</head>
<body>
<ul id="nav">
<li>Menu 1
<ul>
<li>Sub-Item 1 a</li>
<li>Sub-Item 1 b</li>
<li>Sub-Item 1 c</li>
</ul>
</li>
<li>Link 1
</li>
<li>Menu 2
<ul>
<li>Sub-Item 3 a</li>
<li>Sub-Item 3 b</li>
<li>Sub-Item 3 c</li>
<li>Sub-Item 3 d</li>
</ul>
</li>
<li>Menu 3
<ul>
<li>Sub-Item 4 a</li>
<li>Sub-Item 4 b</li>
<li>Sub-Item 4 c</li>
</ul>
</li>
<li>Link 2
</li>
</ul>
<script type="text/javascript">
$(document).ready(function () {
$('#nav > li > a').click(function(){
if ($(this).attr('class') != 'active'){
$(this).next().slideToggle();
$(this).addClass('active');
}
else {
$(this).next().slideToggle();
$('#nav li a').removeClass('active');
}
});
});
</script>
</body>
</html>

You can manually apply the active class to the element and then when document is ready slideToggle the element with active class. For instance:
In the HTML:
<li>Menu 3
<ul>
<li>Sub-Item 4 a</li>
<li>Sub-Item 4 b</li>
<li>Sub-Item 4 c</li>
</ul>
</li>
And in the Javascript part:
$(document).ready(function () {
$('#nav > li > a').click(function(){
if ($(this).attr('class') != 'active'){
$(this).next().slideToggle();
$(this).addClass('active');
}
else {
$(this).next().slideToggle();
$('#nav li a').removeClass('active');
}
});
var toActivate = $('.activate-on-load');
toActivate.next().slideToggle();
toActivate.addClass('active');
});
This should work.
What I'd also suggest is adding additional classes for those menu elements instead of using such complexed selectors.

Just putting code within the $(document).ready(function() { ... }); will make it run on load (once the document is ready). To open the correct accordion, you can use window.location to get your URL to determine what page the user is on and open the accordion accordingly.
This could be made easier by adding ids to your menus so you can easily select and open it.

You have to use locationor pathname(it's up to you) in order to compare your current page with your accordion HREFs.
Here is an exemple
Added JS:
var pagePath = window.location.pathname; // To be used
var splitedPath = pagePath.split("/"); //Split to match your href formating
//Find A tag that match your path, find its parent UL and the A tag before (the one which has click event);
$("#nav > li > ul > li > a[href='" + splitedPath[splitedPath.length - 1] + "']").closest("ul").prev("a").trigger("click");
First get the location/pathname
Split it in order to match your current href formating
Select the parent A to simulate a click

Related

Menu active element with li class istead of a class java script adaption

How is it possible that the menu-item with li class "active" stays open?
At the moment the script is written for the "active" class in the a element. I wonder if it is possible to keep the "active" class in the li element.
$(document).ready(function () {
$('#nav > li > a').click(function(){
if ($(this).attr('class') != 'active'){
$('#nav li ul').slideUp();
$(this).next().slideToggle();
$('#nav li a').removeClass('active');
$(this).addClass('active');
}
});
if($(".active").parent().parent().is('#nav')){
$(".active").next().slideToggle();
}else{
$(".active").parents('ul').siblings('a').click();
}
});
$(document).ready(function () {
$('#nav > li > a').click(function(){
if ($(this).attr('class') != 'active'){
$('#nav li ul').slideUp();
$(this).next().slideToggle();
$('#nav li a').removeClass('active');
$(this).addClass('active');
}
});
if($(".active").parent().parent().is('#nav')){
$(".active").next().slideToggle();
}else{
$(".active").parents('ul').siblings('a').click();
}
});
#nav {
float: left;
width: 280px;
}
#nav li a {
display: inline-block;
padding: 10px 15px;
text-decoration: none;
color: #000;
list-style:none;
}
#nav li a:hover, #nav li a.active {
}
#nav li ul {
display: none; // used to hide sub-menus
list-style:none;
}
#nav li ul li a {
padding: 10px 25px;
}
#nav li.sub {
padding-left: 35px;
}
ul{
list-style:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="nav">
<li class="active">Item 1
<ul>
<li><a href="#" >Sub-Item 1 a</a></li>
<li>Sub-Item 1 b</li>
<li>Sub-Item 1 c</li>
<li class="sub"><a href="#" >Sub-sub-Item 1 a</a></li>
<li class="sub"><a href="#" >Sub-sub-Item 2 a</a></li>
</ul>
</li>
<li>Item 2
<ul>
<li>Sub-Item 2 a</li>
<li>Sub-Item 2 b</li>
</ul>
</li>
<li>Item 3
<ul>
<li>Sub-Item 3 a</li>
<li>Sub-Item 3 b</li>
<li>Sub-Item 3 c</li>
<li>Sub-Item 3 d</li>
</ul>
</li>
<li>Item 4
<ul>
<li>Sub-Item 4 a</li>
<li>Sub-Item 4 b</li>
<li>Sub-Item 4 c</li>
</ul>
</li>
</ul>
Thank you in advance for your answers!
By Default load page open first items then put this code
$('#nav > li > a:first').click();
inside code in document ready function
Live Demo Here
Update Your Script
$(document).ready(function () {
$('#nav > li > a').click(function(){
if ($(this).attr('class') != 'active'){
$('#nav li ul').slideUp();
$(this).next().slideToggle();
$('#nav li a').removeClass('active');
$('#nav li a').parent().removeClass('active');
$(this).addClass('active');
$(this).parent().addClass('active'); // li tag insert active class
}
});
if($(".active").parent().parent().is('#nav')){
$(".active").next().slideToggle();
}else{
$(".active").parents('ul').siblings('a').click();
}
$('#nav > li > a:first').click();
});
Snippet Example Below
$(document).ready(function () {
$('#nav > li > a').click(function(){
if ($(this).attr('class') != 'active'){
$('#nav li ul').slideUp();
$(this).next().slideToggle();
$('#nav li a').removeClass('active');
$('#nav li a').parent().removeClass('active');
$(this).addClass('active');
$(this).parent().addClass('active'); // li tag inside active class
}
});
if($(".active").parent().parent().is('#nav')){
$(".active").next().slideToggle();
}else{
$(".active").parents('ul').siblings('a').click();
}
$('#nav > li > a:first').click();
});
#nav {
float: left;
width: 280px;
}
#nav li a {
display: inline-block;
padding: 10px 15px;
text-decoration: none;
color: #000;
list-style:none;
}
#nav li a:hover, #nav li a.active {
}
#nav li ul {
display: none; // used to hide sub-menus
list-style:none;
}
#nav li ul li a {
padding: 10px 25px;
}
#nav li.sub {
padding-left: 35px;
}
ul{
list-style:none;
}
.active
{
background:#c2c2c2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="nav">
<li class="active">Item 1
<ul>
<li><a href="#" >Sub-Item 1 a</a></li>
<li>Sub-Item 1 b</li>
<li>Sub-Item 1 c</li>
<li class="sub"><a href="#" >Sub-sub-Item 1 a</a></li>
<li class="sub"><a href="#" >Sub-sub-Item 2 a</a></li>
</ul>
</li>
<li>Item 2
<ul>
<li>Sub-Item 2 a</li>
<li>Sub-Item 2 b</li>
</ul>
</li>
<li>Item 3
<ul>
<li>Sub-Item 3 a</li>
<li>Sub-Item 3 b</li>
<li>Sub-Item 3 c</li>
<li>Sub-Item 3 d</li>
</ul>
</li>
<li>Item 4
<ul>
<li>Sub-Item 4 a</li>
<li>Sub-Item 4 b</li>
<li>Sub-Item 4 c</li>
</ul>
</li>
</ul>

Make ordered list collapsible

I have an ordered list which i want to make collapsible by default and expandable when user click on the link.
https://jsfiddle.net/rkmv3rn3/17/
How can I make it work so that it works properly
With following script it collapses all Parent item then fails to open them properly.
$(window).load(function() {
prepareList();
});
function prepareList() {
$('#expList').find('li:has(ol)')
.click(function(event) {
if (this == event.target) {
$(this).toggleClass('expanded');
$(this).children('ol').toggle('medium');
}
return false;
})
.addClass('collapsed')
.children('ol').hide();
//Create the button funtionality
$('#expandList')
.unbind('click')
.click(function() {
$('.collapsed').addClass('expanded');
$('.collapsed').children().show('medium');
})
$('#collapseList')
.unbind('click')
.click(function() {
$('.collapsed').removeClass('expanded');
$('.collapsed').children().hide('medium');
});
};
.page-left-bar {
width: 200px;
background-color: #fff;
}
ol {
margin-left: 0px;
padding-left: 20px;
}
.handbook-page ol {
color: #687074;
counter-reset: item;
}
ol {
counter-reset: item;
color: #687074;
}
ol li {
display: block;
padding: 5px 0;
}
ol li a {
text-decoration: none;
color: #687074;
padding-left: 10px;
}
ol li:before {
content: counters(item, ".") " ";
counter-increment: item;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>LIST OL child list alignment</h1>
<div class="page-left-bar">
<ol id='#expList'>
<li>Home</li>
<li>News</li>
<li>Contact
<ol>
<li>Sub menu</li>
<li>Sub menu long name</li>
<li>Sub menu</li>
<li>Sub menu</li>
</ol>
</li>
<li>About
<ol>
<li>Mission</li>
<li>Vision</li>
<li>Sub menu</li>
<li>Sub menu</li>
</ol>
</li>
</ol>
</div>
If you want to toggle the visibility of your submenus. First remove the # from the id #expList in your HTML as #MoshFeu said.
<ol id='expList'>
Then you can simply do it like this.
$(document).ready(function(){
$("#expList").find("ol").hide();
$("#expList > li").click(function(){
$(this).find("ol").slideToggle();
});
});
See this fiddle

Show Bootstrap Multi level Dropdown Menu on Hover

I understand there are couple of posts on this title. What I want , to implement the same in my existing code and by using jQuery since I have already added ample of CSS lines for it's styling purpose.
The Piece of codes I have used in my web application for implementing Multi drop-down .
HTML :
<div class="dropdown" style="position:relative">
Click Here <span class="caret"></span>
<ul class="dropdown-menu">
<li>
<a class="trigger right-caret">Level 1</a>
<ul class="dropdown-menu sub-menu">
<li>Level 2</li>
<li>
<a class="trigger right-caret">Level 2</a>
<ul class="dropdown-menu sub-menu">
<li>Level 3</li>
<li>Level 3</li>
<li>
<a class="trigger right-caret">Level 3</a>
<ul class="dropdown-menu sub-menu">
<li>Level 4</li>
<li>Level 4</li>
<li>Level 4</li>
</ul>
</li>
</ul>
</li>
<li>Level 2</li>
</ul>
</li>
<li>Level 1</li>
<li>Level 1</li>
</ul>
css
.dropdown-menu>li
{ position:relative;
-webkit-user-select: none; /* Chrome/Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */
/* Rules below not implemented in browsers yet */
-o-user-select: none;
user-select: none;
cursor:pointer;
}
.dropdown-menu .sub-menu {
left: 100%;
position: absolute;
top: 0;
display:none;
margin-top: -1px;
border-top-left-radius:0;
border-bottom-left-radius:0;
border-left-color:#fff;
box-shadow:none;
}
.right-caret:after,.left-caret:after
{ content:"";
border-bottom: 5px solid transparent;
border-top: 5px solid transparent;
display: inline-block;
height: 0;
vertical-align: middle;
width: 0;
margin-left:5px;
}
.right-caret:after
{ border-left: 5px solid #ffaf46;
}
.left-caret:after
{ border-right: 5px solid #ffaf46;
}
JS
$(function(){
$(".dropdown-menu > li > a.trigger").on("click",function(e){
var current=$(this).next();
var grandparent=$(this).parent().parent();
if($(this).hasClass('left-caret')||$(this).hasClass('right-caret'))
$(this).toggleClass('right-caret left-caret');
grandparent.find('.left-caret').not(this).toggleClass('right-caret left-caret');
grandparent.find(".sub-menu:visible").not(current).hide();
current.toggle();
e.stopPropagation();
});
$(".dropdown-menu > li > a:not(.trigger)").on("click",function(){
var root=$(this).closest('.dropdown');
root.find('.left-caret').toggleClass('right-caret left-caret');
root.find('.sub-menu:visible').hide();
});
});
I have only go far a bit only. I am able to show the 1st dropdown menu on hover.
js
$(".dropdown > a").hover(function(){
$(this).parent().addClass('open');
});
When I will hover on any "li" element of 1st level navigation , if any 2nd level navigation present , It should be shown.

Different styles for childs before and after specifed element using jQuery and CSS?

I need to set special styles for li.done depending on whether they are before or after li.current. How can I do that using jQuery or CSS?
ul { list-style: none; padding: 0; margin: 0; }
ul li {
display:inline-table;
padding: 5px 12px;
color: #ddd;
background-color: #bbb;
margin: 0;
}
.done {
background-color: #ddd;
color: #aaa
}
.current {
background-color: #99f;
color: #dee
}
<ul>
<li class="done">step 1</li>
<li class="done">step 2</li>
<li class="current">step 3</li>
<li class="done">step 4</li>
<li>step 5</li>
</ul>
You should take a look at jQuerys .prevAll() and .nextAll().
var current = $(".current");
current.prevAll(".done").addClass("before");
current.nextAll(".done").addclass("after");
Please note that you will have to redo this every time you change the current element.
The documentation can be found here and here.
You can achieve this just with CSS by using the ~ selector. From the W3 documentation:
General sibling combinator
The general sibling combinator is made of the "tilde" (U+007E, ~) character that separates two sequences of simple selectors. The elements represented by the two sequences share the same parent in the document tree and the element represented by the first sequence precedes (not necessarily immediately) the element represented by the second one.
That means that you could set the styles for the .done that happen after .current by applying the selector: .current ~ .done.
One example:
ul { list-style: none; padding: 0; margin: 0; }
ul li {
display:inline-table;
padding: 5px 12px;
color: #ddd;
background-color: #bbb;
margin: 0;
}
.done {
background-color: #ddd;
color: #aaa
}
.current {
background-color: #99f;
color: #dee
}
.current ~ .done {
background-color:#f99;
color:white;
}
<ul>
<li class="done">step 1</li>
<li class="done">step 2</li>
<li class="current">step 3</li>
<li class="done">step 4</li>
<li class="done">step 5</li>
<li>step 6</li>
</ul>

what is the best approach to implement Tree View?

I'm working Tree View constructed by using nested ul li tag as below:
<ul>
<li>Level 1 a
<ul>
<li>Level 2 a</li>
<li>Level 2 b
<ul>
<li>Level 3 a</li>
<li>Level 3 b</li>
</ul>
</li>
</ul>
</li>
<li>Level 1 b</li>
</ul>
I wanted the list item is clickable on cell when navigate across the Tree View like below:
I know that we can added JavaScript function on list item as below:
<li onClick="redicrectPage(url)">
and add event.cancelBubble = true to avoid parent event is trigger when child item clicked.
My question is, any better cross-browser workaround on the implementation above?
Thank you in advanced.
You can make a nested menu structure in CSS alone which would remove the bubbling problem. The example at http://jsfiddle.net/steveukx/HfDBA/ uses the direct descendent selector to be able to repeat the same selectors without needing to know the depth of the menu, but if you are supporting browsers that don't have this functionality you should change the HTML to add classes to name the depth in the tree and specify those in the CSS.
HTML:
<ul class="menu">
<li>Level 1 a
<ul>
<li>Level 2 a</li>
<li>Level 2 b
<ul>
<li>Level 3 a</li>
<li>Level 3 b</li>
</ul>
</li>
</ul>
</li>
<li>Level 1 b</li>
</ul>​
CSS
* { font-family: tahoma, sans-serif; font-size: 10pt; }
a { text-decoration: none; color: #fff; display: block; }
ul { display: none; }
ul.menu, li:hover > ul { display: block; }
li > ul { position: absolute; top: 25%; left: 100%; margin-left: -1em;
box-shadow: -1px 1px 1px rgba(0,0,0,0.5); z-index: 1000; }
li { position: relative; padding: 0.1em 0.5em; width: 100px; background: silver;
box-shadow: -1px 1px 1px rgba(0,0,0,0.5); margin: 1px 1px 0; }
li:hover { background-color: #333; }
li:hover > a { color: #FAFAFE; }
​

Categories