Slide Toggle automatically open the first item? - javascript

I have aJQuery accordian using the following JS.
function initMenu() {
$('#accordion ul').hide();
$('#accordion li a').click(
function() {
$(this).next().slideToggle('normal');
}
);
}
$(document).ready(function() {initMenu();});
And the following HTML
<ul id="accordion">
<li><a class="firstheading" href="#">Making words work</a>
<ul class="panelContent">
<li>
<p>IPSUM</p>
</li>
</ul>
</li>
<li><a class="heading" href="#">Full business-writing services</a>
<ul class="panelContent">
<li>
<p>IPSUM<p>
</li>
</ul>
</li>
</ul>
Can anyone tell me how to ensure the first item is opened when the page loads?

You can use the gt selector to specify the ul's with an index greater than zero, so every ul except the first.
Demo here
function initMenu() {
$('#accordion ul:gt(0)').hide();
$('#accordion li a').click(
function() {
$(this).next().slideToggle('normal');
}
);
}
$(document).ready(function() {initMenu();});

It should be opening automatically, but you can open up accordion pieces programmatically like so:
.accordion( 'activate' , index )
so to open up the first section, you would do
$('#accordion').accordion('activate',0);
You could put that in your document ready function. Note that a selector can also be used in place of the number, which represents each section from 0 onwards.
Source

Related

jQuery click() and on() function

I'm trying to add "active" class to menu when user clicks on the button but for some reason it's not working correctly. They have to click really fast and two times. I've tried both click and on click function but still not working.
$('#menu li').click(function() {
$('#menu li.active').removeClass('active');
$(this).addClass('active');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right" id="menu">
<li class="nav active">Home
</li>
<li class="nav">About
</li>
<li class="nav">Services
</li>
<li class="nav">Gallery
</li>
<li class="nav">Contact
</li>
</ul>
</div>
you must handle active li after page loaded.Add this at the end of your code:
var curruntLocation = window.location.href;
$('#menu li a').each(function ()
{
var thisHref = $(this).attr('href');
if (curruntLocation.indexOf(thisHref) > 0)
{
$(this).parent().addClass('active');
}
});
The links included in the menu items are reloading the page while clicking and when the page is reloaded, the initial setting comes first. You can use preventDefault() if you'd like to run the function but then, your links won't work.
I suggest you use anchors instead of query string.

Jquery - How to add active class to entire navigation menu path?

I have a menu with 3 levels, and I would like to use a class for the first active li and a second class for all other subsequent li. When I click on a selection the level 3 to remain active the whole path (level 1, level 2, level 3). If I click on a selection on level 2 to remain active up to level 2.
I have the following:
$(document).ready(function(){
$('.sf-menu li a').each(function(index) {
if((this.pathname.trim() == window.location.pathname))
$(this).parent().addClass("selected");
var next_li = $(this).parent().next();
$('a', next_li).addClass("selected2");
});
});
I think I got it this time, It's a bit dirty but It works.
First add classes so you can identify first, second and third level <li> elements. Do it in the foreach, or whatever bucle that makes the menu (or by hand if there's no such bucle):
<ul id="navlist" >
<li id="home" class="firstLevel">
<a class="nav" href="home">Home</a>
<ul class="secondLevel">
<li class="secondLevel">
<a class="nav2" href="home">sub-Home1</a>
<ul>
<li class="thirdLevel"><a class="nav3" href="home">sub-sub-Home1></a></li>
<li class="thirdLevel"><a class="nav3" href="home">sub-sub-Home1></a></li>
</ul>
</li>
<li><a class="nav2" href="home">sub-Home2</a></li>
</ul>
</li>
<li id="about" class="firstLevel">
<a class="nav" href="about-us">About Us</a>
</li>
</ul>
Then use jQuery closest. It traverses up the DOM tree and matches the closest item, you can pass a selector (the firstLevel or secondLevel classes we just created):
$('#navlist a').on('click', function (e) {
e.preventDefault(); //prevent the link from being followed
$('#navlist a').removeClass('selected');
$('#navlist a').removeClass('selected2');
$(this).closest('.secondLevel').children('a').addClass('selected2');
$(this).closest('.firstLevel').children('a').addClass('selected2');
$(this).addClass('selected');
});
Then you add !important to the selected class (so when there's a colision like in the About Us link selected is the class that is applied). This is the dirtiest part.
Check a working fiddle: https://jsfiddle.net/4r5vg/661/

Prevent default only on some levels

I am making a menu that has submenu. When I click on a menu item I am using prevent default because it is a tags, but on the submenu level I don't want to prevent default. I haven't been able to figure out how to make it work so it doesn't affect the top level.
<div id="block-menu-block-2">
<ul class="menu">
<li>
1
</li>
<li>
2
<ul class="menu">
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
<li>2.4</li>
</ul>
</li>
<li>
3
<ul class="menu">
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
<li>3.4</li>
</ul>
</li>
<li>
4
</li>
<li>
5
</li>
<li>
6
<ul class="menu">
<li>6.1</li>
</ul>
</li>
</ul>
</div>
Here is the jQuery
$('#block-menu-block-2 ul li').on("click", function() {
if ($(this).children().is('ul')) {
if ($(this).find('ul').is(':visible')) {
$(this).find('ul').hide("blind");
$(this).removeClass('menuItemSelected');
$(this).find('ul').removeClass('menuItemSelected');
} else {
$(this).parent().find('li ul').hide("blind");
$(this).parent().find('.menuItemSelected').removeClass('menuItemSelected');
$(this).find('ul').show("blind");
$(this).addClass('menuItemSelected');
$(this).find('ul').addClass('menuItemSelected');
};
event.preventDefault()
}
});
Here is a codepen for reference: http://codepen.io/mathiasha/pen/bVpMyo
Added some stuff. Changed some stuff. Couldn't paste into codepen from my phone so this might not work. Code first, then word wall.
$('#block-menu-block-2 ul li').each (function () {
var $this = $(this);
if ($this.find ('ul:first').length > 0) {
$this.click (function () {
if ($this.find ('ul:visible').length > 0) {
$this.removeClass ('menuItemSelected').find ('ul').removeClass('menuItemSelected').hide ('blind');
} else {
$this.parent ().find ('ul li').hide ('blind');
$this.parent ().find('.menuItemSelected').removeClass ('menuItemSelected');
$this.addClass ('menuItemSelected').find ('ul').show ('blind').addClass ('menuItemSelected');
}
});
}
});
$('#block-menu-block-2 > ul > li > a').click (function (e) {
if ($(this).find ('ul:first').length > 0)
e.preventDefault ();
});
The real answer lies in only putting the preventDefault only on the a tag and only when it is the immediate child of a li tag tjat is the immediate child of a ul tag that is the immediate child of the block-menu. See the last 3 lines.
The rest of the code below should only add the click listener to li tags with ul tags inside. Tried to use chaining to limit the number of jQuery objects created. Might have messed up what it was doing. You only really need to remove preventDefault from where it is and than use the last 3 lines.
Can you not add a class to your submenu triggers, e.g. .submenu-trigger, and then use the following jQuery:
$(document).on('click', function(e) {
if ($(e.target).hasClass('submenu-trigger')) e.preventDefault();
});
Ignoring all the other menu manipulation and putting the event on <a> tags you can simply check if the <a> has a sibling <ul> and if it does prevent default
$('#block-menu-block-2 a').click(function(e){
if( $(this).siblings('ul').length ){
e.preventDefault();
}
// menu manipulation code
});

Display active tab's name in an span

I would like to show the active tab's name (text) in a span .active-class.
Example:
<ul class="tabs">
<li class="feinleinen active">feinleinen</li>
<li class="glatt">glatt</li>
</ul >
<span class="active-class">*Active_Tab_Name_Here (i.e. feinleinen) *</span>
What you want is either to have a click event each time a link is clicked and put the text in there?
Javascript:
function changeSpan(var newText){
document.getElementByClassName('active-class').innterHTML(newText);
}
When the above you need to initialise the function. this can be done in the anchor within the list item.
<li><a href='#' onclick='changeSpan("new item name!");'>
Don't forget the hash (#) within the href! This stops the default action, in layman's terms.
With jQuery this can be a bit simpler
$('a','ul.tabs>li').click(function(){//a classname would be a better selector
$('.active-class').appendTo($(this).innerHTML());//can also use $(this).text();
return false;//also stops default action
});
FIDDLE:
HTML
<ul class="tabs">
<li class="feinleinen active">feinleinen
</li>
<li class="glatt">glatt
</li>
</ul>
<span class="active-class">active tab name here</span>
SCRIPT
$('.active-class').text($('.tabs .active').find('a').text());
I guess you want this on click , therefore bit updation to my above code here :-
$('.tabs a').click(function () {
$('.tabs li').removeClass('active');
$(this).parent('li').addClass('active');
$('.active-class').text($(this).text());
});
fiddle: http://jsfiddle.net/x97g8sc7/
$(".active-class").text($(".tabs .active").text());

Why does my accordion list keep closing?

I've created a side menu that contains accordion list. When I load the page, the accordion list has one section open because it's coded to be active on page load. However if I attempt to open another section... it opens the section but then closes straight away. Can someone tell me where I'm going wrong?
List code:
<ion-content class="has-header" id="accordian"scroll="false" ng-controller="MainCtrl">
<ul>
<li class="active">
<h3><span class="icon-dashboard"></span>Group 1</h3>
<ul>
<li ng-repeat="card in cards">{{ card.title }}</li>
</ul>
</li>
<!-- we will keep this LI open by default -->
<li>
<h3><span class="icon-tasks"></span>Group 2</h3>
<ul>
<li ng-repeat="card in cards">{{ card.title }}</li>
</ul>
</li>
<li>
<h3><span class="icon-calendar"></span>Group 3</h3>
<ul>
<li ng-repeat="card in cards">{{ card.title }}</li>
</ul>
</li>
</ul>
JS:
$(document).ready(function(){
$("#accordian h3").click(function(){
//slide up all the link lists
$("#accordian ul ul").slideUp();
//slide down the link list below the h3 clicked - only if its closed
if(!$(this).next().is(":visible"))
{
$(this).next().slideDown();
}
})
})
You must wait until the execution of the slideUp function is completed (by default the duration is 400ms) before you test if the next element is visible or not.
$(document).ready(function(){
$("#accordian h3").click(function(){
//slide up all the link lists
$("#accordian ul ul").slideUp();
//slide down the link list below the h3 clicked - only if its closed
var $elemH3 = $(this);
setTimeout(function() {
if(!$elemH3.next().is(":visible"))
{
$elemH3.next().slideDown();
}
}, 401);
})
})
You can use some CSS to do this easily see this example : http://jsfiddle.net/nx2LkoLd/
You hide all sections but not the active one :
css code
li.active ul {
display:block;
}
li ul {
display: none;
}
The js and html code still the same.
Hope it's clear and will help you resolve your problem.
Default position of accordion is collapsed... put this on the begining of your $(document).ready to expand it.
$('#accordian').collapse({toggle: true});
EDIT:
In your case:
$(document).ready(function(){
$('#accordian').collapse({toggle: true});
});
Or... if you want your accordion expands independent of the ready event you can put this line anywhere in your js file (except inside another function):
$(function () { $('#accordian').collapse({toggle: true}); });
Both will work, but I'm not sure if your own functions are working, so be careful. I'm sorry, no time to test. ;)

Categories

Resources