I have 3 tabs, created by js. Active tab has class named "active" and it changes on every click on the tabs
<div class='tab'>
<ul class='tabs'>
<li class="active"><a href='http://link1.com#t1'>First</a></li>
<li><a href='http://link2.com#t2'>Second</a></li>
<li><a href='http://link3.com#t3'>Third</a></li>
</ul>
<div>
<h2>First tab!</h2>
</div>
<div>
<h2>Second tab!</h2>
</div>
<div>
<h2>Thrid tab1</h2>
</div>
</div>
Links returns 'false' by default. I need to create some js function, that enables link (onclick="return true";) on the active tab, and disables it, when I switch to the other tab (li). Appreciate any help.
I can suggest you to check dynamically whether the parent element (in this case li element) has class active and return the negative value
$('#tabs a').on('click', function(){
// if parent has class active returns false
return !$(this).parent().hasClass('active');
});
Related
It is two level menu:
<ul>
<li>
<a href="#/time'>Time</a>
<ul>
<li><a href="#/time/timetable'>timetable</a></li>
</ul>
</li>
</ul>
How can I add "active" class to both the item "timetable" and its parent "time" based on url? ( so I can highlight them both ) and removing other previously opened element.
Any help would be appreciated.Thanks in advance.
Check out ng-class. I think that is what you are describing. You can use it to set the element active class based on the current URL or any other data you have available.
I have a popup window with several tabs in my angular application.
The tabs have bootstrap-like styles and I should switch them via angular.
I have the following markup for my tabs (the code is simplified):
<div class="settingsPopupWindow">
<div>
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li class="{{getStyle(0)}}" ng-click="showTab(0)">
<a href="">
First tab nav
</a>
</li>
<li class="{{getStyle(1)}}" ng-click="showTab(1)">
<a href="">
Second tab nav
</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane {{getStyle(0)}}">
First tab content
</div>
<div class="tab-pane {{getStyle(1)}}">
Second tab content
</div>
</div>
</div>
And I have the following code in my controller for switching tabs:
.......
$scope.active = 0;
$scope.showTab = function (tabNumber) {
$scope.active = tabNumber;
};
$scope.getStyle = function(n) {
if (n === $scope.active) {
return 'active';
}
else {
return '';
}
}
.......
Navigation elements and tab blocks both should have active class if they are switched on.
In the initial state all is correct:
the first tab is switched on so First tab nav has active class
(and highlighted) and First tab content is displayed.
But if I click on the Second tab nav to switch the tabs -
only navigation element (Second tab nav) has the active class
(and Second tab content doesn't).
The second tab navigation element is highlighted as active
but I still see First tab content in the panel,
so I need to click twice on the Second tab nav to really switch to the second tab.
If in the initial state I click on the Second tab nav and after that click on the First tab nav,
First tab nav is active and highlighted but I see Second tab content in the pane.
So switching of the tab panels is lagging behind by one step from switching of navigation elements!
It is very surprising because the class of both navigation element and tab is got by the same function.
Help me please to switch those tabs correctly. Thank you.
Update
I tried to use ng-class instead of the class but it didn't help. I still have a one-click gap among switching of navigation elements and tab panels. I checked showTab() function, it works correctly, the number of active tab/nav switches properly. It seems that styles of the tabs are not renewing immediately after changing of active tab number, but styles of the 'navs' are still renewing immediately, and it happens regardless of using class or ng-class.
You should use the ngClass attribute.
from the ngClass docs -
The ngClass directive allows you to dynamically set CSS classes on an HTML element by databinding an expression that represents all classes to be added.
In my opinion however its best not to use a function to get the class name,
but rather use the ng-class with the tag's scope property:
<div class="tab-pane" ng-class="{'desiredClassName': tagObject.isTagActive}">
First tab content
</div>
<div class="tab-pane" ng-class="{'desiredClassName': tagObject.isTagActive}">
Second tab content
</div>
This way tagObject can be an object containing the tag's info.
and if its an item in a collection you can use the ng-repeat attr.
The isTagActive would be updated from any method (scope, service etc.)
and angular would immediately update the tag's <div> with the classes you wish.
Use the ngClass directive.
For your tab nav:
<li ng-class="{'active': active == 0}" ng-click="ShowTab(0)">First tab nav</li>
<li ng-class="{'active': active == 1}" ng-click="ShowTab(1)">Second tab nav</li>
And for your tab content:
<div class="tab-pane" ng-class="{'active': active == 0}">
First tab content
</div>
<div class="tab-pane" ng-class="{'active': active == 1}">
Second tab content
</div>
EDIT: Working Example
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.active = 0;
$scope.showTab = function(tabNumber) {
$scope.active = tabNumber;
};
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li ng-class="{'active': active == 0}" ng-click="showTab(0)">
First tab nav
</li>
<li ng-class="{'active': active == 1}" ng-click="showTab(1)">
Second tab nav
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane" ng-class="{'active': active == 0}">
First tab content
</div>
<div class="tab-pane" ng-class="{'active': active == 1}">
Second tab content
</div>
</div>
</div>
Is there a way to do the following
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li class="active">Home</li>
<li>Profile</li>
<li>Messages</li>
<li>Settings</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="home">...</div>
<div class="tab-pane" id="profile">...</div>
<div class="tab-pane" id="messages">...</div>
<div class="tab-pane" id="settings">...</div>
<div class="tab-pane" id='extra'> .... </div>
</div>
so there is another tab pane called #extra, but I don't want it to have a link as a tab, but I do want it to be toggleable by some other event
as bootstrap tabs.js works from trigger a tab('show') on a link and not on the pane itself, how do I trigger a tab pane without working on a tab?
note: I aware that the basic operation it does it doing a show() and hide() on the tab pane, but I feel that doing all this manually inhibits me from using callbacks, etc
You could add the tab for extras and then just hide it
Add this to your nav-tabs:
<li class="hidden"><a href="#extra" role="tab" data-toggle="tab" >Extra</a></li>
Then activate from somewhere else with JavaScript:
$("#launchExtra").click(function() {
$('#myTab a[href="#extra"]').tab('show')
});
Working demo in jsFiddle
Alternatively, you could just handle the whole thing yourself. The only thing .tab('show') does is remove the active class from all the other nav-tabs and tab-content elements. And then add back the .active class on the appropriate elements.
So first remove all the active elements and then add back the active class:
$("#launchExtra").click(function() {
$(".nav-tabs .active, .tab-content .active").removeClass("active");
$("#extra").addClass("active");
});
Working demo in jsFiddle
Create a link in memory and call the tab function on it.
$('<a data-toggle="tab" data-target="#some-id"></a>').tab("show")
an anchor link is used when you want to navigate. If you dont want to navigate, use a button. But style it like a link.
<ul class="nav nav-tabs">
<li role="presentation" class="active">
<button class="btn btn-sm btn-link">Tab1</button>
</li>
</ul>
nows its a button and will not navigate. Just add any javascript you want to it.
But I recommend to use the anchor. Javascript tabs dont support history back in the browser. And its often tricky to start with ex. tab number 4 selected. I often let every tabpage be an own page. With its own route
I have a few tabs on a page that have this markup
<div id="holiday-details-nav">
<ul>
<li><a class="holidaydetails-description" title="Overview" href="#tab-holidaydetails-overview">Overview</a></li>
<li><a class="holidaydetails-included" title="Rooms" href="#tab-holidaydetails-rooms">Rooms</a></li>
<li><a class="holidaydetails-itinerary" title="Rates" href="#tab-holidaydetails-rates">Rates</a></li>
<li><a class="holidaydetails-accommodation" title="Information" href="#tab-holidaydetails-information">Information</a></li>
<li><a class="holidaydetails-reviews" title="Reviews" href="#tab-holidaydetails-reviews">Reviews</a></li>
</ul>
</div>
The hiding and showing of the content in these tabs are controlled by some JQuery code that begins thus
$(document).ready(function () {
// Hide all tabs apart from the overview
$('#holiday-details-tabs div:#tab-holidaydetails-rooms').hide();
$('#holiday-details-tabs div:#tab-holidaydetails-rates').hide();
$('#holiday-details-tabs div:#tab-holidaydetails-information').hide();
$('#holiday-details-tabs div:#tab-holidaydetails-reviews').hide();
...
The problem is that if I add, remove or rename tabs (like I have just done), then I have to change all this code. What I would like is to add, rename or remove as many tabs as I like but to not have to modify this JQuery code.
I'm not really looking for someone to code a solution for me but rather wanted to start a discussion on tools, techniques etc that can be used to avoid this sort of naming dependency.
EDIT
I also have this bit of ugliness for when a tab is clicked.
$('#holiday-details-nav ul li a').click(function () {
// Remove active class from all links
$('#holiday-details-nav ul li').removeClass('active');
//Set clicked link class to active
$(this).parent().addClass('active');
// Set variable currentTab to value of href attribute of clicked link
var currentTab = $(this).attr('href');
// Hide all tabs
$('#holidaydetails-description-imagecontainer').hide();
$('#holiday-details-tabs div:#tab-holidaydetails-overview').hide();
$('#holiday-details-tabs div:#tab-holidaydetails-rooms').hide();
$('#holiday-details-tabs div:#tab-holidaydetails-rates').hide();
$('#holiday-details-tabs div:#tab-holidaydetails-information').hide();
$('#holiday-details-tabs div:#tab-holidaydetails-reviews').hide();
$('#holiday-details-bottom').show();
$('#holiday-details-left-booknow').show();
// Show div with id equal to variable currentTab
$(currentTab).show();
$('#holidaydetails-description-imagecontainer').show();
return false;
});
Thanks,
Sachin
You could assign a common CSS class, say tab, to every li except overview, and then use a jQuery class selector to hide them all. For example:
<div id="holiday-details-nav">
<ul>
<li><a class="holidaydetails-description" title="Overview" href="#tab-holidaydetails-overview">Overview</a></li>
<li><a class="tab holidaydetails-included" title="Rooms" href="#tab-holidaydetails-rooms">Rooms</a></li>
<li><a class="tab holidaydetails-itinerary" title="Rates" href="#tab-holidaydetails-rates">Rates</a></li>
<li><a class="tab holidaydetails-accommodation" title="Information" href="#tab-holidaydetails-information">Information</a></li>
<li><a class="tab holidaydetails-reviews" title="Reviews" href="#tab-holidaydetails-reviews">Reviews</a></li>
</ul>
</div>
And then, to hide every tab except overview:
$("holiday-details-nav .tab").hide();
Or the other way around, that is, add a specific class to overview, and hide every other tab:
<div id="holiday-details-nav">
<ul>
<li><a class="overview holidaydetails-description" title="Overview" href="#tab-holidaydetails-overview">Overview</a></li>
<li><a class="holidaydetails-included" title="Rooms" href="#tab-holidaydetails-rooms">Rooms</a></li>
<li><a class="holidaydetails-itinerary" title="Rates" href="#tab-holidaydetails-rates">Rates</a></li>
<li><a class="holidaydetails-accommodation" title="Information" href="#tab-holidaydetails-information">Information</a></li>
<li><a class="holidaydetails-reviews" title="Reviews" href="#tab-holidaydetails-reviews">Reviews</a></li>
</ul>
</div>
Then, to hide, select all tabs, and exclude overview using .not():
$("#holiday-details-nav a").not(".overview").hide();
When dealing with tabs, especially in the setup you have (where the href attribute has the id of the div related to it), you don't need to hardcode anything, use the title attribute, or use any extra classes. Look at this:
http://jsfiddle.net/FAM2s/2/
All it does it find all of the tabs' detail divs and hide them all, then only show the one related to what was just clicked.
As long as you set the correct href attributes for the links, and set the corresponding divs with those id's, it will work, no matter how many tabs you add/remove whenever you want.
I am trying to change the class of a tab on the dashboard depending upon the page selected.
I have 3 tabs in the dashboard like
<div>
<ul class="menu">
<li class="MenuDashboard"><a href="#" >Dashboard</a></li>
<li class="MenuSearch">Search</li>
<li class="MenuAccountSetup">Account Set up</li>
</ul>
</div>
Now I want to highlight the tab when I select that particular tab. By default the 'Dashboard' tab should be highlighted. I have a style class called "current" which highlights the tab.
Please advise.
This should work:
$('.menu li').click(function() {
$(this).addClass('current').siblings().removeClass('current');
});
// Clicks on the first menu item to style it
$('.menu li').eq(0).click();