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>
Related
I have to pages. first page I have bootstrap tab. please check below sample
1.first page is user page. its url http://localhost:8081/#!/app/user
in this page there is a tab controller.
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active">One </li>
<li>Two
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab_1">
content 01
</div>
<div class="tab-pane" id="tab_2">
content 02
</div>
</div>
</div>
this is second page. its url http://localhost:8081/#!/app/user-list
this page has back button. When user click this button, page should redirect to the first page (user page) SECOND TAB. How i active SECOND TAB after redirect. Currently i am using below function
$scope.goBack = function () {
$state.go('app.user/#tab_2');
}
Above back function is not working. how i do this work. thanks
Have you tried $ionicHistory?
// include $ionicHistory in your injected dependencies...
$scope.goBack = function() {
$ionicHistory.goBack();
};
I do not possess much knowledge on MVC, JavaScript or Bootstrap. But here I am stuck at something working on all the three. I have a Layout page consisting of a navigation bar styled using Bootstrap. Idea taken from here. Markup given below.
<div id="innerTab">
<ul class="nav nav-pills">
<li class="active">
Index
</li>
<li>
About
</li>
</ul>
<div class="tab-content clearfix">
<div class="tab-pane active">
#RenderBody()
</div>
</div>
</div>
Since this is a Layout View, I want to be able to load the content from the other Views in the tab content area. Due to which, I have to make use of #RenderBody() which cannot be called more than once. I am not really sure what data-toggle does exactly but clicking on About had no impact whatsoever. Then I realised that I had to manually set the active class on the clicked tab via JS. So this is what I did.
$(".nav li").on("click", function() {
$(".nav li").removeClass("active");
$(this).tab('show');
})
Now, the selected tab did become active. However, for some unknown reason, when clicked on About, it does not navigate to the About page but stays at Index. Because of which I had to change it to #Html.ActionLink as given below.
#Html.ActionLink("About", "About", "Home")
This successfully navigated to the About page. However, the About tab becomes active for a second and quickly switches to the Index tab but displays the content from the About page. like below.
Thought adding data-toggle would fix this. So I followed the answer given here.
#Html.ActionLink("About", "About", "Home", new { data_toggle="tab"})
And then it's back to square one. Except for the fact that it highlights the tab I select, it does nothing.I am lost!! Where am I going wrong?
First, #Url.Action(" Index ", "Home ") isn't working because you have extra spaces around your Action and Controller arguments.
It should be #Url.Action("Index", "Home")
"The About tab becomes active for a second and quickly switches to the Index"
That's because, on click, jQuery click event adds a class. But MVC redirects to a new page and the _Layout is rendered again with the default active tab Home.
So to the top of your About.cshtml,
#{
ViewBag.Title = "About";
ViewBag.ActiveNav = "About"; // you'll need to add this to Home as well
}
Then change the Layout to:
<ul class="nav nav-pills">
//Based on the "ActiveNav" value, "active" class will be added
<li class="#(ViewBag.ActiveNav == "Home" ? "active" : "")">
#Html.ActionLink("Index", "Index", "Home")
</li>
<li class="#(ViewBag.ActiveNav == "About" ? "active" : "")">
#Html.ActionLink("About", "About", "Home")
</li>
</ul>
Now the active class is added to particular li, based on the page.
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
Using Bootstrap modal that contains tabs. The modal is called from a php generated table of gallery names.
Table Data
<td>
<a href="#" class="galName" data-target="#myModal" data-toggle="modal" id="update_<?php echo $gal['id']; ?>" >
<?php echo $gal['name']; ?>
</a>
</td>
The modal opens and the first tab is selected on initial fire. If I navigate to another tab close the modal and select a different gallery the modal opens to the last tab that was open.
How do I make sure that when the modal is opened, it always opens to the first tab?
Modal Tabs
<ul id="myTab" class="nav nav-tabs">
<li class="active">
Home
</li>
<li class="">
<a id="uploadRevision" href="#upload" data-toggle="tab">Upload Revision</a>
</li>
<li class="">
Edit Revision
</li>
</ul>
.galName fires an initUpdate function in effort to set first tab as default. It sets the tab but tab content is not show.
function initUpdate()
{
$('#myModal a:first').tab('show');
}
Thanks for the help.
Found the solution. Must remove the class="active" from both tab and tabContent. Thanks to #merv - https://stackoverflow.com/a/11762931/1214858
Simple; use class "active" to show particular tab on load.
Like below:
<!-- Nav tabs -->
<!-- content tabs -->
Remove class="tab-pane active" in li of above on nav of tab and content which you want to make it in active.
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');
});