How to set bootstrap active tab on refresh in Angular JS - angularjs

I am creating tabs as:
<tabset class="content-tabset no-margin">
<tab ng-repeat="t in t.values" heading="{{t.name}}" active="t.active">
//other stuff
</tab>
</tabset>
Now within this other stuff I also have button which when clicks updates the row and refreshes that part. When the refresh happens it also resets the tab I am currently on.
So if I am tab two and click on the button, the panel refreshes and I come back on tab 1. How can I prevent this?

Use localStorage. Set it on selecting tab. To get boolean value of active state for current tab use ng-init.
<tabset class="content-tabset no-margin">
<tab
ng-repeat="t in t.values"
heading="{{t.name}}"
ng-init="isActive = isActiveTab(t.name, $index)"
active="isActive"
select="setActiveTab(t.name)">
//other stuff
</tab>
</tabset>
And in your controller
$scope.setActiveTab = function( activeTab ){
localStorage.setItem("activeTab", activeTab);
};
$scope.getActiveTab = function(){
return localStorage.getItem("activeTab");
};
$scope.isActiveTab = function( tabName, index ){
var activeTab = $scope.getActiveTab();
return ( activeTab === tabName || ( activeTab === null && $index === 0 ) );
};
NOTE: Since your t has no unique ID for tabs, names should be unique to detect active tab correctly.
See example JSFiddle.

Whenever you do a refresh the local/scope variables runs out of scope. So the way out to solve this is using JavaScript's Session Storage/ Local Storage.
Session storage will run out of scope once you close the browser while local storage will persist value till window and browser lifetimes.
Inside controller:
$scope.selTab = sessionStorage.tabName; //On refresh it will fetch value from session storage
$scope.onClickTab = function(tabName){ //On click it will set the sessionStorage
$scope.selTab = tabName;
sessionStorage.tabName = tabName;
}
Inside HTML must refer your controller
<ul class="nav nav-pills col-md-12 col-sm-12 col-xs-12{{active}}">
<li ng-class ="{active:selTab=='tab1'}">Tab3</li>
<li ng-class ="{active:selTab=='tab3'}">Tab3</li>
</ul>

You can use this package ui-router-tabs. Follow the link https://github.com/rpocklin/ui-router-tabs. Easy to use and gets the job done.

I have solved it by using Local Storage
Inside HTML:
<ul class="nav">
<li>
<a ng-click="goToManageUsers('manageUser')" ng-class="{'active': selectedTab == 'manageUser'}">
<i class="lnr lnr-home"></i>
<span>Manage User</span>
</a>
</li>
<li>
<a ng-click="goToManageRequest('manageImage')" ng-class="{'active': selectedTab == 'manageImage'}">
<i class="lnr lnr-home"></i>
<span>Manage Image</span>
</a>
</li>
</ul>
Inside Controller:
$scope.selectedTab = localStorage.getItem('getActive');
$scope.goToManageUsers = function (user) {
$scope.selectedTab = user;
localStorage.setItem('getActive', user);
}
$scope.goToManageRequest = function (image) {
$scope.selectedTab = image;
localStorage.setItem('getActive', image);
}

To do this same thing in Angular 2+, you also use LocalStorage. Something like this (I used ng-bootstrap to enable Bootstrap tabs):
HTML:
<ngb-tabset class="nav-fill" (tabChange)="tabChange($event)" [activeId]="activeTabId">
<ngb-tab title="Tab 1" id="tab1">
...
</ngb-tab>
<ngb-tab title="Tab 2" id="tab2">
...
</ngb-tab>
</ngb-tabset>
.ts:
import {NgbTabChangeEvent} from "#ng-bootstrap/ng-bootstrap";
... other imports
export class MyComponent {
activeTabId: string;
constructor() {
this.activeTabId = localStorage.getItem("activeTab");
}
tabChange($event: NgbTabChangeEvent) {
localStorage.setItem("activeTab", $event.nextId);
}
}

Related

Angularjs: initiating first tab as active on page load

We are creating a tabs widget in ServiceNow and want to initiate the first tab as the active tab when the page loads. Right now when the page loads, this is what we see:
We actually want to see this on load:
Our code looks like this:
<ul class="nav nav-tabs">
<li ng-click="c.activateClass(tabs)" ng-repeat="tabs in c.data.tab_labels track by $index" ng-class="{'active':tabs.active}">
<a data-toggle="tab" href="#{{tabs}}">{{tabs}}</a>
</li>
</ul>
<div class="tab-content" >
<div ng-repeat="content in c.data.tab_labels" id="{{content}}" class="tab-pane fade in active">
<h3>{{content}}</h3>
<p>Some content.</p>
</div>
</div>
function($scope) {
/* widget controller */
var c = this;
c.data.tab_labels = c.options.tab_labels.split(',');
c.activateClass = function(subModule){
subModule.active = !subModule.active;
}
console.log('tabs');
console.log($scope);
}
We tried to use ng-init, but it was returning a console error. Any idea how to initiate the first tab on page load? Thanks!
You can set the active tab as active like this:
if(c.data.tab_labels.length > 0) {
c.data.tab_labels[0].active = true;
}
and show the active content:
<div ng-repeat="content in c.data.tab_labels | filter:{active:true}">

AngularJs - Opening a Bootstrap dropdown menu on page load by programmatically triggering the "click" event (NO jQuery)

May I ask if it's possible to trigger the click event of a dropdown menu programmatically on page load using AngularJS?
What I want to happen is that after loading the page, my navigation menu gets displayed automatically.
This is what I have so far:
<li class="menu-item" style="margin-top:15px">
<!-- Single button -->
<div class="btn-group open" uib-dropdown is-open="status.isopen">
<!-- Hamburger menu -->
<img ng-init="displayMainMenu()" id="nav-burger" uib-dropdown-toggle ng-disabled="disabled" ng-click="sMainMenu=true; isSubMenu=resetMenu(); getLinks(); bStopPropagation=true;" src="img/burger.png">
<!-- Main menu -->
<ul uib-dropdown-menu role="menu" aria-labelledby="single-button" ng-click="bStopPropagation && $event.stopPropagation()">
<!-- Main Menu -->
<li role="menuitem" class="main-menu-item" ng-repeat="link in links" ng-click="whatMenu(link.name); isSubMenu=false;" ng-show="isMainMenu">
<img id="{{link.icon}}">{{link.name}}<img class="navi-expand-icon">
</li>
<!-- End Main Menu -->
</ul>
</div>
</li>
And this is my Angular JS code:
$scope.displayMainMenu = function () {
var domElement = document.getElementById('nav-burger');
alert('before timeout'); // <-- This gets triggered
$timeout(function () {
angular.element(domElement).triggerHandler('click');
}, 0);
alert('after timeout'); // <-- This doesn't get triggered...
}
I have a feeling that I'm really close, however I couldn't figure out why it's not working.
Thank you in advance for your replies.
The ng-click on your image triggers this: ng-click="sMainMenu=true;"
However, to show your list items you have used isMainMenu ng-show="isMainMenu"
So I guess you made a typo.
Thank you for the clue Matheno! I did some more research about $timeout and finally got it to work by declaring $timeout in the controller:
app.controller('ctrlDropdown', function ($scope, $timeout) {
$scope.isMainMenu = true;
$scope.isSubMenu = false;
$scope.links = "";
$scope.subLinks = "";
$scope.selectedLink = "";
$scope.bStopPropagation = true;
...
}

ng-click toggle only works on first click

I want to toggle a boolean by click event using Angular.
This is my the code
<div class="nav_mobile" ng-click="mobilestatus.navActive = (mobilestatus.navActive == false) ? true : false">
</div>
<nav>
<ul class="nav_mobile_list" ng-class="{active: mobilestatus.navActive}">
<li><a ui-sref="about" ng-click="mobilestatus.navActive = false">About</a></li>
<li><a ui-sref="contact" ng-click="mobilestatus.navActive = false">Contact</a></li>
</ul>
</nav>
The controller looks like this
angular.module('app').controller('NavCtrl', function ($scope){
$scope.mobilestatus = {navActive: false};
});
I also tried other shorthand notations. The initial value of navActive is false. The ng-click on nav_mobile makes the navActive attribute true the first time, but when clicking again, it doesn't return back to false. When clicking on the li items, the navActive does return back to false. Any suggestion is appreciated.
Try this statement
ng-click="mobilestatus.navActive = !mobilestatus.navActive"
EDIT
If you have no idea of whats going on inside your code try to debug it. Use function call instead of angular's DOM expression and log output into console. Also you can use breakpoints.
HTML
ng-click="toggle()"
Controller
$scope.toggle = function toggle() {
$scope.mobilestatus.navActive = !$scope.mobilestatus.navActive;
console.log('Status is ' + $scope.mobilestatus.navActive);
};
You will see if this code is executable and $scope.mobilestatus is available to html part.
EDIT
Here is plunker
Check this solution:
<div class="nav_mobile" ng-click="mobilestatus.navActive = !mobilestatus.navActive">
Test- {{mobilestatus.navActive}}
</div>
<nav>
<ul ng-class="{'active': mobilestatus.navActive, 'inactive': mobilestatus.navActive}">
<li><a ui-sref="about" ng-click="mobilestatus.navActive = !mobilestatus.navActive">About</a></li>
<li><a ui-sref="contact" ng-click="mobilestatus.navActive = !mobilestatus.navActive">Contact</a></li>
</ul>
</nav>

$scope is only visible in function and thats why is not working

My layout page looks like this:
<li class="dropdown">
<ul class="submenu">
<li>#Translate("MY_ACCOUNT")</li>
</ul>
</li>
In layout page i have : #RenderBody()where i have Index page.In index page im using <div ng-view></div>. What im trying to do is when user click on a href to redirect him on that page and set class to this menu that is render in ng-view:
<div class="account-item">
<div class="account-heading" ng-class="{active : activeMenu === 'Settings'}">
<h4 class=" account-title has-sub">
<a data-toggle="collapse" data-parent="#accordion" href="#settings" ng-click="activeMenu='Settings'">5. #Translate("SETTINGS")</a></h4>
</div>
<div id="settings" class="account-collapse collapse in">
<div class="account-body">
#Translate("PERSONAL_INFORMATION")
#Translate("NOTIFICATIONS")
#Translate("CHANGE_PASSWORD")
#Translate("GAME_SETTINGS")
</div>
</div>
</div>
When i try this nothing happens:
$scope.SetActiveMenuForPersonalInfo = function () {
$scope.activeMenu = 'Settings';
$scope.activeLink = "PersonalInfo";
}
$scope.activeMenu and $scope.activeLink are visible only in function and thats why i cant set class on menu. When i put it out of function it works
Try changing the tripple equality sign in ng-class="{'active-link' : activeLink==='PersonalInfo'}" to double ==
PS: I do not understand the last paragraph

How to show tab with carousel avoiding sliding from the current image to the selected image?

In my Angular app I have a simple twitter-bootstrap carousel, in a tab:
<div class="tabbable">
<ul class="nav nav-pills">
<li ng-class="{active: tabSelected === 'main'}">
Main
</li>
<li ng-class="{active: tabSelected === 'photos'}">
Photos
</li>
</ul>
</div>
...
<div class="tab-content" ng-show="tabSelected === 'photos'>
<div class="slides-control">
<carousel disable-animation="false">
<slide ng-repeat="photo in person.photos" active="photo.active">
<img class="slide" ng-src="{{photo.path}}" />
</slide>
</carousel>
</div>
</div>
In the controller I have defined a method, tabSelect(tabName, photoNumber), which allows the tab to be selected in code, and - if the tab is the one named 'photos' - a specific image number can be selected:
<script>
$scope.tabSelect = function (tabName, photoNumber) {
if (tabName === 'photos') {
$scope.person.photos[0].active = false;
$scope.person.photos[photoNumber].active = true;
}
$scope.tabSelected = tabName;
};
</script>
The problem is this:
When calling, for example, $scope.tabSelect('photos', 7);, the photos tab is shown, but initially the previously active image is shown, and then immediately it slides to the selected image (the 7th, in the example). I don't want to avoid using animations, which are quite cool... Though, I want to display immediately the selected image...
I did already try to surround the $scope.tabSelected = tabName; instruction in a $timeout() block, and the selected slide is immediately shown, but not fully rendered (for example, the arrows are not present...).

Resources