Create nav-tabs with directives? - angularjs

I have a nav-tabs in my view
<ul class="nav nav-tabs" ng-controller="myController">
<li ng-class="{ active: isActive('/Page1')}">myPage1</li>
<li ng-class="{ active: isActive('/Page2')}">myPage2 </li>
</ul>
How can I write it into a directive? The problem is the braces..

I'm sorry that I first now corresponds to the question. I have found a solution to the problem.
My directives:
myApp.directive('userNavbar', function(){
return {
restrict : 'AE',
templateUrl : '../js/partials/userNavbarTemplates.html',
controller : function($scope, $element, $location) {
$scope.isActive = function(viewLocation) {
var active = false;
if (viewLocation === $location.path()) {
active = true;
}
return active;
};
}
};
});
And my userNavbarTemplates:
<title>userNavbar</title>
<div class="row">
<div class="span6">
<ul class="nav nav-tabs">
<li ng-class="{ active: isActive('/page1')}">
nav. to page1
</li>
<li ng-class="{ active: isActive('/page2')}">
nav. to page2
</li>
</ul>
</div>
And in my View can I add
<div data-user-Navbar></div>

Related

All Bookmarks are redirecting to same element

I have three bookmarks, two are on same page and one in different page, when ever I click on the link, it moving to same element and it was't smooth.
The frame works I am using are materializecss, angularjs 1 and ui router
I don't know how to write the code for it.
myapp.controller('ctrl',ctrl);
ctrl.$inject=['$scope', '$location', '$anchorScroll'];
function ctrl($scope, $location, $anchorScroll) {
$scope.scrollTo = function(team) {
$location.hash('team');
$anchorScroll();
};
$scope.scrollTo = function(contact) {
$location.hash('contact');
$anchorScroll();
};
};
<body ng-controller="ctrl">
<div class="container">
<div class="fixed-action-btn toolbar">
<a class="btn-floating btn-large light-blue accent-2 pulse">
<i class="large material-icons">menu</i>
</a>
<ul>
<li class="waves-effect waves-light"><a ui-sref="home">HOME</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo(home/project)">PROJECTS</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo(team)">TEAM</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo(contact)">CONTACT</a></li>
</ul>
</div>
</div>
Any help is appreciate.
Thank you.
You dont need to add multiple scrollTo function in controller, you can use only one function for all like this
myapp.controller('ctrl', ctrl);
ctrl.$inject = ['$scope', '$location', '$anchorScroll'];
function ctrl($scope, $location, $anchorScroll) {
$scope.scrollTo = function(state) {
$location.hash(state);
$anchorScroll();
}
};
And html is
<body ng-controller="ctrl">
<div class="container">
<div class="fixed-action-btn toolbar">
<a class="btn-floating btn-large light-blue accent-2 pulse"> <i class="large material-icons">menu</i> </a>
<ul>
<li class="waves-effect waves-light"><a ui-sref="home">HOME</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo('home/project')">PROJECTS</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo('team')">TEAM</a></li>
<li class="waves-effect waves-light"><a ng-click="scrollTo('contact')">CONTACT</a></li>
</ul>
</div>
</div>
</body>

Recursive template using ng-include inside a directive template

Directive template :
<script type="text/ng-template" id="child-map.html">
<b ng-click="selectNode(child.id)">{{child.title}}</b>
<ul ng-if="child.children.length">
<li ng-repeat="child in child.children" ng-include="clild-map.html"></li>
</ul>
</script>
<b ng-click="selectNode(mapData.id)">{{mapData.title}}</b>
<ul ng-if="mapData.children.length">
<li ng-repeat="child in mapData.children" ng-include="child-map.html" ></li>
</ul>
Directive definition :
function widgetNodeMap () {
var nodeMap = {};
nodeMap.restrict = 'E'
nodeMap.scope = {
'mapData' : '=mapData'
}
nodeMap.controller = ['$scope',function($scope){
// $scope.currentNode = $scope.mapData.id;
$scope.selectNode = function(node_id){
$scope.currentNode = node_id;
}
$scope.getCurrentNode = function(){
return $scope.currentNode;
}
}];
nodeMap.templateUrl = '/static/app/components/widget/widget.view.node-map.html';
return nodeMap
}
Main template :
<widget-node-map map-data="navCtrl.mapData">
</widget-node-map>
But still i cannot get the data listed properly. Can you help me, where Im wrong?
I figured the solution
<script type="text/ng-template" id="child-map.html">
<ul ng-if="child.children.length">
<li ng-repeat="child in child.children">
<a ng-click="selectNode(child)">{{child.title}}</a>
<div ng-include src="'child-map.html'"></div>
</li>
</ul>
</script>
<div class="row">
<div class="col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2 col-sm-12 col-xs-12">
<a ng-click="selectNode(mapData)">{{mapData.title}}</a>
<ul ng-if="mapData.children.length">
<li ng-repeat="child in mapData.children">
<a ng-click="selectNode(child)">{{child.title}}</a>
<div ng-include src="'child-map.html'"></div>
</li>
</ul>
</div>
</div>

Angular JS - Identifying type of isolated category in child directive

I have a custom directive with isolated scope for category :
'use strict';
angular.module('myModule').directive('myContent', function() {
return {
restrict: 'E',
templateUrl: 'myContent.html',
scope: {
category: '='
},
controller: function($scope){
// private methods
},
controllerAs: 'myContentCtrl'
};
});
In my main directive am calling the same directive as :
<div>
<my-content category = "category1"></my-content>
</div>
<div>
<my-content category = "category2"></my-content>
</div>
<div>
<my-content category = "category3"></my-content>
</div>
And myContent.html is having :
<div class="form-group">
<div class="col-lg-10 navbar">
<ul class="nav nav-tabs" role="tablist">
<li class="active itemFirst"><a href="#link1" role="tab"
data-toggle="tab">Link 1 </a>
</li>
<li>Link 2 </li>
<li>Link 3 </li>
</ul>
</div>
</div>
<div class="form-group">
<div class="tab-content col-lg-10">
<div class="tab-pane active" id="link1">
// contents here for link 1
</div>
<div class="tab-pane" id="link2">
// contents here for link 2
</div>
<div class="tab-pane" id="link3">
// contents here for link 3
</div>
</div>
</div>
Here my issue is, the id is getting replicating as the same direct is populating each links.
So the UI is not populating the different directives and tabs properly.
How can I separate the Id of each one by identifying the category value I had send to each directive.
My requirement is making id dynamic as :
id = "link1_{{category}}"
But it is not reflecting. How can I achieve this?
Updating the category object.
My category objects are having some data like :
$scope.category1 = [
{obj1},
{obj2},
{obj3},
{obj4}
];
$scope.category2 = [
{obj1},
{obj2},
{obj3},
{obj4}
];
So I can't use category1 object as an ID. instead how can i use the string "category1" that I'm separating each categories. I hope now the code is clear.
I just resolved it in a complicated approach, but am not sure about the perfection.
I had added one more data in category object as "type"
Now my category object is:
$scope.category1 = {
type : "category1",
data : [
{obj1},
{obj2},
{obj3},
{obj4}
]
};
$scope.category2 = {
type : "category2",
data : [
{obj1},
{obj2},
{obj3},
{obj4}
]
};
So in HTML the id is :
<div class="form-group">
<div class="col-lg-10 navbar">
<ul class="nav nav-tabs" role="tablist">
<li class="active itemFirst"><a href="#{{category.type}}" role="tab"
data-toggle="tab">Link 1 </a>
</li>
<li>Link 2 </li>
<li>Link 3 </li>
</ul>
</div>
</div>
<div class="form-group">
<div class="tab-content col-lg-10">
<div class="tab-pane active" id="{{category.type}}">
// contents here for link 1
</div>
<div class="tab-pane" id="{{category.type}}">
// contents here for link 2
</div>
<div class="tab-pane" id="{{category.type}}">
// contents here for link 3
</div>
</div>
</div>
</div>
I think you need different ID for each <div> for all instances of directive.
<div class="tab-pane active" id={{'link1_'+category}}></div>
and use # in isolated scope to get values of attributes
app.directive('myContent', function() {
return {
restrict: 'E',
templateUrl: 'myContent.html',
scope: {
category : '#'
},
controller: function($scope){
// private methods
console.log($scope.category)
},
controllerAs: 'myContentCtrl'
};
});
Here's the working plunkr
If I understood you correctly, You can set the Id in a function inside your controller...
<div class="tab-pane active" id="{{setId}}">
And in your custom directive with isolated scope for category :
controller: function($scope){
// private methods
$scope.setId = function(){...}
},

Angular how to redirect to a tab

I have a page which has got 5 tabs. There is another page which contains the links pointing to these tabs. Whenever a user clicks a link on this page, corresponding tab should be opened on angular application page.
The tab are working fine when user manunally clicks on a tab but I am unable to find how can I select a tab by default.
Add in app.js:
$routeProvider.when('/trend', {
templateUrl:'partials/trend.html'
}).when('/deepdive', {
templateUrl:'partials/deepdive.html'
}).when('/driversNdrainers', {
templateUrl:'partials/DriversNDrainers.html'
}).when('/timeline', {
templateUrl:'partials/timeline.html'
}).otherwise("/trend");
index page:
<div header></div>
<div class="row">
<div class = "col-md-12" ng-include="'partials/home.html'"></div>
</div>
<div footer></div>
The home controller creates the tabs dynamically.
Home.html
<div class="" fade-in ng-controller="HomeCtrl">
<ul class="nav nav-pills">
<li ng-class="tabClass(tab)" ng-repeat="tab in tabs" tab="tab"><a href="{{tab.link}}" id="{{tab.id}}"
ng-click="setSelectedTab(tab)">{{tab.label}}</a></li>
</ul>
<div ng-view></div>`enter code here`
Controller:
var homectrl = myApp.controller('HomeCtrl', ['$scope', '$routeParams', '$location','$state', function ($scope, $routeParams,$location,$state) {
$scope.tabs = [
{ link : '#/trend', label : 'Trend', id: "trendLink"},
{ link : '#/deepdive', label : 'Deep Dive' , id:"deepdriveLink"},
{ link : '#/driversNdrainers', label : 'Drivers & Drainers', id:"ddLink" },
{ link : '#/timeline', label : 'Timeline' , id: "timelineLink"},
{ link : '#/zoomin', label : 'Zoom In', id: "zoominLink" }
];
$scope.selectedTab = $scope.tabs[0];
$scope.setSelectedTab = function(tab) {
$scope.selectedTab = tab;
};
$scope.tabClass = function(tab) {
return $scope.selectedTab == tab? "active": "";
};
angular.element(document).ready(function () {
$.each($scope.tabs,function(i){
if(this.link==location.hash){
$scope.setSelectedTab(this);
//$state.go("/trend");
return;
}
});
});
}]);
What I see here is that the tab is selected but the content inside tab is not loaded.
Your code inside jQuery is not executed in Angular's digest cycle. Try adding $scope.$apply(); right after $scope.setSelectedTab(this);
To understand why you should do this read: "Scope Life Cycle" at https://docs.angularjs.org/guide/scope
Here is the solution you can refer to stackblitz
I had to do some modification in its function to achieve the result as per my requirement.
modified solution:
moveToSelectedTab(tabName: string) {
for (let i = 0; i < document.querySelectorAll('[aria-selected]').length; i++) {
let element = document.querySelectorAll('[aria-selected="false"]')[i];
if (element != undefined) {
if ((<HTMLElement>document.querySelectorAll('[aria-selected="false"]')[i]).innerHTML == tabName) {
(<HTMLElement>document.querySelectorAll('[aria-selected="false"]')[i]).click();
}
}
}}
HTML
<ul class="nav nav-tabs" id="editorTab" role="tablist">
<li class="nav-item active" role="presentation">
<a class="nav-link active" id="bannerArea-tab" data-toggle="tab" href="#bannerArea" role="tab"
aria-controls="bannerArea" aria-selected="true">General Information</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" id="cardArea-tab" data-toggle="tab" href="#cardArea" role="tab"
aria-controls="cardArea" aria-selected="false">Banner Content</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link" id="mainArea-tab" data-toggle="tab" href="#mainArea" role="tab"
aria-controls="mainArea" aria-selected="false">Main Content</a>
</li>
</ul>
<div class="tab-content" id="editorTabContent">
<div class="tab-pane fade show active col-sm-12" id="bannerArea" role="tabpanel" aria-labelledby="bannerArea-tab">
<div class="form-group">
</div>
<div class="text-right margin-top-xl">
<button class="btn-icon-confirm" (click)="moveToSelectedTab('Banner Content')">Next<i class="material-icons">arrow_forward</i></button>
</div>
</div>
<div class="tab-pane fade show active col-sm-12" id="cardArea" role="tabpanel" aria-labelledby="cardArea-tab">
<div class="form-group">
</div>
<div class="text-right margin-top-xl">
<button class="btn-icon-confirm" (click)="moveToSelectedTab('Main Content')">Next<i class="material-icons">arrow_forward</i></button>
</div>
</div>
<div class="tab-pane fade col-sm-12" id="mainArea" role="tabpanel" aria-labelledby="mainArea-tab">
<div class="text-right margin-top-xl">
<button class="btn-icon-confirm" (click)="moveToSelectedTab('General Information')"><i class="material-icons">check</i></button>
</div>
</div>
</div>

AngularJs :Expand and collapse in directive

I have this code :
<div >
<ul class="nav nav-pills nav-stacked" data-ng-repeat="filter in filters">
<li class="" >
<a class="" data-toggle="collapse" href="#collapse{{filter.year}}">
{{filter.year}}
</a>
<ul class="nav nav-pills nav-stacked panel-collapse collapse" id="collapse{{filter.year}}">
<li>January</li>
</ul>
</li>
</ul>
</div>
I would like that when I click the years the second show the data...
But it doesn't work
Try ng-href instead:
Quoted from the doc:
Using Angular markup like {{hash}} in an href attribute will make the
link go to the wrong URL if the user clicks it before Angular has a
chance to replace the {{hash}} markup with its value. Until Angular
replaces the markup the link will be broken and will most likely
return a 404 error.
Use angularui toggle collapse (http://angular-ui.github.io/bootstrap/). In the outer ul set ng-click="isCollapsed = !isCollapsed" and in the inner ul set collapse="isCollapsed".
module.directive('collapseDirective', function(){
return {
restrict: 'EA',
transclude: 'true',
link: function(scope, element, attrs){
scope.isCollapsed = true;
};
}
});
<div collapse-directive>
<ul class="nav nav-pills nav-stacked" data-ng-repeat="filter in filters">
<li>
<a ng-click={isCollapsed=!isCollapsed} class="" data-toggle="collapse" href="#collapse{{filter.year}}">
{{filter.year}}
</a>
<ul collapse=isCollapsed class="nav nav-pills nav-stacked panel-collapse collapse" id="collapse{{filter.year}}">
<li>January</li>
</ul>
</li>
</ul>
</div>

Resources