I have created one custom directive to add active class for clicked li in menu list based on url.
.directive('addActive', [function() {
return{
...
link : function(scope, element, attrs){
pageUrl = location.pathname;
$('#sidebar-left .nav li.active').removeClass("active");
if (pageUrl) {
debugger
console.log($('.nav li:has(a[href="' + pageUrl + '"])'))
$('.nav li:has(a[href="' + pageUrl + '"])').addClass("active");
}
}
}
}]);
directive code defines that when a menu is clicked, active class should be added for current url.
how can I use this directive in html code?
Html:
<div id="sidebar-left" class="col-xs-2 col-sm-2">
<ul class="nav main-menu">
<li class="dropdown ng-scope" ng-repeat="parent in menu">
<a href="/employee/Home" class="dropdown-toggle" ng-click="tabName(parent.name)">
<i class="fa fa-home"></i>
<span class="hidden-xs ng-binding">Home</span>
</a>
</li>
<li class="dropdown ng-scope" ng-repeat="parent in menu">
<a href="/documents/doc_details" class="dropdown-toggle" ng-click="tabName(parent.name)">
<i class="fa fa-file-text"></i>
<span class="hidden-xs ng-binding">Documents</span>
</a>
</li>
<li class="dropdown ng-scope" ng-repeat="parent in menu">
<a href="#" class="dropdown-toggle" ng-click="tabName(parent.name)">
<i class="fa fa-money"></i>
<span class="hidden-xs ng-binding">Pay & Benifits</span>
</a>
<ul class="dropdown-menu">
<li ng-repeat="child in parent.children" class="ng-scope">
slips
</li>
</ul>
</li>
</ul>
</div>
Please guys any help?
you are missing the most important information about your directive: the 'restrict' attribute indicates how should the directive can be used in your html. For instance: using retrict: 'E', means that your directive can be used as an html element
<add-active></add-active>
But i guess that in you situation, your restrict value is 'A', and you should use it as an attribute:
<div add-active></div>
for more info you can see the angularJS directive's documentation here:
https://docs.angularjs.org/guide/directive
but i agree with the folks above me that in this case, you probably just need to use ng-class (that is also a directive).
I think Yaniv's answer is what you need.
But I suggest you try ng-class.
In your code, you are trying to use the url so I think this might help you:
How to highlight a current menu item?
Related
I need to open the dropdown when clicking on link with angularjs. my idea is to add the class open to the dropdown with ng-class directive but this is not working .
I have two dropdown menu, what i need is to open the second one when clicking on the link within the first one
<ul class="nav navbar-nav navbar-right " >
<li class="dropdown" ng-class="myDropdown ? : 'open'">
<a class="dropdown-toggle" data-toggle="dropdown" >Menu</a>
<ul class="dropdown-menu " role="menu" ng-if="!myDropdown">
<li>
Open second dropdown
</li>
</ul>
<ul class="dropdown-menu " role="menu" ng-if="myDropdown">
<li >
Go back
</li>
</ul>
</li>
</ul>
Typescript
toogleDropDown() {
this.scope.myDropdown = true;
}
This won't work since you toggleDropDown is a function and it does not return anything !undefined should be true I think so your line:
Go back
is same as writing:
Go back
overall there's no need for that function at all what you need is something like this:
<a href="" ng-click="myDropdown=!myDropdown">
<span ng-if="!myDropdown">Open second dropdown</span>
<span ng-if="myDropdown">Go back</span>
</a>
and remove that function from your controller there's no need for it.
also I believe you wanted to set up ng-class like this:
<li class="dropdown" ng-class="{'open': myDropdown}">
Here's fiddle: https://jsfiddle.net/pegla/nq11093m/1/
I have a scenario in which html of the two partials is same but the model is different. For instance see the below code
<ul class="feeds">
<li ng-if="scleanerData.contact_no">
<div><i class="fa fa-phone color-grey" aria-hidden="true"></i></div>{{scleanerData.contact_no}}</li>
<li ng-if="scleanerData.email">
<div><i class="fa fa-envelope color-grey" aria-hidden="true"></i></div>{{scleanerData.email}}</li>
<li ng-if="scleanerData.address">
<div><i class="fa fa-globe color-grey" aria-hidden="true"></i></div>{{scleanerData.address}}</li>
</ul>
I need this same html in second partial but this time the bindings are like this
<ul class="feeds">
<li ng-if="profile.house">
<div><i class="fa fa-phone color-grey" aria-hidden="true"></i></div>{{profile.house}}</li>
<li ng-if="profile.email">
<div><i class="fa fa-envelope color-grey" aria-hidden="true"></i></div>{{profile.email}}</li>
<li ng-if="profile.home}">
<div><i class="fa fa-globe color-grey" aria-hidden="true"></i></div>{{profile.home}}</li>
</ul>
Is there any way so i can write the html once but the data binding works for both of them.
Create a custom directive with this html as template and having isolated scope. Use the directive where ever required and passing the model as input to that directive from different locations.
Below is the short example, that might help you.
define directive:
app.directive('myDirective', function(){
return {
restrict: 'E',
scope: {
contactInfo: '='
},
templateUrl: 'my-template.html',
link: function (scope,element,attrs,ctrl){
// you can manipulate your data / DOM here, if required.
}
}
})
associate a directive HTML:
<ul class="feeds">
<li ng-if="contactInfo.contact_no">
{{contactInfo.contact_no}}</li>
<li ng-if="contactInfo.email">
{{contactInfo.email}}</li>
<li ng-if="contactInfo.address">
{{contactInfo.address}}</li>
</ul>
use that directive in your main HTML:
<button ng-click="showInfo1 = true;showInfo2=false;">Show Info 1</button>
<button ng-click="showInfo2 = true;showInfo1=fasle;">Show Info 2</button>
<my-directive contact-info="contactInfo1" ng-show="showInfo1"></my-directive>
<my-directive contact-info="contactInfo2" ng-show="showInfo2"></my-directive>
Plunk here: https://plnkr.co/edit/EknrkUBBRl4rr7kma1Yw?p=preview
(please do not update the english grammer in this question/ I wont be able to approve it and this question wont get resolved.)
This is my UI
It contains various li elements whose values are populated using this angular html
<div class="row">
<li class="no-bullet-li li-12 monaco-font"> {{selectedChangeEligibilityPlan}}</li>
<ul class="ul-plan-1">
<li class="no-bullet-li" ng-repeat="plan in fewThings">
<div ng-class="{ 'selected-class-name': $index == selectedIndex }" ng-click="itemClicked($index)" class="li-alt monaco-font"> p2|{{plan.planName}} | {{plan.planId}}
<a class="iconing-sub" ng-click="addClick(item)" href=""><i class="glyphicon glyphicon-plus"></i></a>
<a ng-click="deleteClick(item)" ng-class="{ active : active.one }" href=""><i class="glyphicon glyphicon-remove iconing_1-sub"></i></a>
</div>
<ul class="ul-plan">
<li class="no-bullet-li li-8 monaco" ng-repeat="item in plan.planIds">
p1| {{ plan.planNames[$index]}} | {{item}}
<a <a ng-click="editClick(item)" href=""><i class="glyphicon glyphicon-pencil iconing"></i></a>
<a ng-click="deleteClick(item)" href=""><i class="glyphicon glyphicon-remove iconing_1"></i></a>
</li>
</ul>
</li>
</ul>
</div>
It uses the nested ng-repeat.
The whole UI is contained within a one controller ( no directives used)
the following code gets triggered when someone clicks the blue lis.
$scope.itemClicked = function ($index) {
console.log($index);
// console.log($(item).closest('li') );
$scope.selectedIndex = $index;
};
here's how to ui looks and its great.
problem arises when I try to do the same logic for the pink ones (nested ng-repeat li). It selects other pink lis in all the other stack too.
here's the screenshot.
second part of question:
I have I have the above UI plus I also have this second UI that is loaded along with this on the same page. It contains a bunch of horizontal rows.
Once the user click the blue pink colored lis it goes into the active state. Then the user can click the row which he likes. upon clicking it the plan name of currently selected li will get replaced.
Here is the html for it.
<div class="row">
<li class="no-bullet-li li-12 monaco-font"> {{selectedChangeEligibilityPlan}}</li>
<ul class="ul-plan-1">
<li class="no-bullet-li" ng-repeat="plan in fewThings">
<div class="li-alt monaco-font"> p2|{{plan.planName}} | {{plan.planId}}
<a class="iconing-sub" ng-click="addClick(item)" href=""><i class="glyphicon glyphicon-plus"></i></a>
<a ng-click="deleteClick(item)" ng-class="{ active : active.one }" href=""><i class="glyphicon glyphicon-remove iconing_1-sub"></i></a>
</div>
<ul class="ul-plan">
<li ng-class="{ 'selected-class-name': $index == selectedIndex }" ng-click="itemClicked($index)" class="no-bullet-li li-8 monaco" ng-repeat="item in plan.planIds">
p1| {{ plan.planNames[$index]}} | {{item}}
<a ng-click="editClick(item)" href=""><i class="glyphicon glyphicon-pencil iconing"></i></a>
<a ng-click="deleteClick(item)" href=""><i class="glyphicon glyphicon-remove iconing_1"></i></a>
</li>
</ul>
</li>
</ul>
</div>
The problem lies in the fact that you are trying to save the state of the data (which one is selected) inside your controller using $index. The $index property isn't unique among different ng-repeats, so when you set your $scope.selectedIndex to $index, each of your sub lists will see that their $index matches, and so will each trigger the ng-class and add the selected-class-name class.
What you could do instead is have each item in the data have a unique index and use that id to store which item is selected in $scope.selectedIndex.
<ul class="ul-plan">
<li ng-class="{ 'selected-class-name': item.id == selectedIndex }" ng-click="itemClicked(item.id)" class="no-bullet-li li-8 monaco" ng-repeat="item in plan.planIds">
p1| {{ plan.planNames[$index]}} | {{item}}
<a ng-click="editClick(item)" href=""><i class="glyphicon glyphicon-pencil iconing"></i></a>
<a ng-click="deleteClick(item)" href=""><i class="glyphicon glyphicon-remove iconing_1"></i></a>
</li>
</ul>
This line looks strange.
<a ng-click="select('one')" href="">
Did you really mean to pass a hardcoded 'one' to the function? Or was it supposed to be the index, like the deleteClick() call.
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>
I have a directive that I am using to render my navigation but there are two ng-clicks in it and both of them fire twice when clicked. I have read similar questions on here but still can't work it out. Any input would be much appreciated.
The html element
<nav ng-cloak ig-nav class="navbar navbar-default" role="navigation"></nav>
The js
.controller('navCtrl',
['$scope', function($scope){
console.log('navCtrl');
$scope.usermenu = false;
$scope.toggleMenu = function() {
var nv = !$scope.usermenu;
console.log(nv);
$scope.usermenu = nv;
};
}])
.directive('igNav', function() {
return {
restrict: 'A',
templateUrl: 'partials/nav.html',
controller: 'navCtrl'
};
})
And the nav template
<ul class="nav navbar-nav navbar-right">
<li ng-if="auth.user"><!--i class="icon-plus"></i--><span class="glyphicon glyphicon-plus"></span> Add</li>
<li ng-if="auth.user"><!--i class="icon-share"></i--><span class="glyphicon glyphicon-share"></span> Share</li>
<li ng-if="auth.user" class="dropdown" ng-class="{open: usermenu}">
{{user.name}} <strong class="caret"></strong>
<ul class="dropdown-menu">
<li><!--i class="icon-align-left"></i--><span class="glyphicon glyphicon-align-left"></span> Activity</li>
<li><!--i class="icon-truck"></i--><span class="glyphicon glyphicon-paperclip"></span> Shares</li>
<li class="divider"> </li>
<li><!--i class="icon-cog"></i--><span class="glyphicon glyphicon-cog"></span> My Profile</li>
<li><!--i class="icon-signout"></i--><span class="glyphicon glyphicon-minus-sign"></span> Logout</li>
</ul>
</li>
<li ng-if="!auth.user"><!--i class="icon-signin"></i--><span class="glyphicon glyphicon-user"></span> Login</li>
</ul>
As it has worked in charliefl's plnkr there must be some other reason it is firing twice. Here is some more info I thought was irrelevant but perhaps it is after all.
The app is running firebase and angularfire 0.5.
$route has been included.
Angular is manually inialized.
ignav is included inside a base level controller (applied to the HTML tag)
Despite working in the fiddle in my app it was still firing twice.
After a bit of reorganising the simple fix was moving the ng-click from the <a> to its parent <li>
<li ng-if="auth.user" ng-click="toggleMenu()" class="dropdown" ng-class="{open: usermenu}">
{{user.name}} <strong class="caret"></strong>
<ul class="dropdown-menu">
<li><!--i class="icon-align-left"></i--><span class="glyphicon glyphicon-align-left"></span> Activity</li>
<li><!--i class="icon-truck"></i--><span class="glyphicon glyphicon-paperclip"></span> Shares</li>
<li class="divider"> </li>
<li><!--i class="icon-cog"></i--><span class="glyphicon glyphicon-cog"></span> My Profile</li>
<li><!--i class="icon-signout"></i--><span class="glyphicon glyphicon-minus-sign"></span> Logout</li>
</ul>
</li>