How to use same html but different model values in angular js? - angularjs

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

Related

I am using ng-hide in angular but it's not working

<nav class="menu-nav">
<ul>
<li class="menu-li" ng-model="myVar"><a>Search<i class="fa fa-chevron-down pull-right"></i></a>
<div class="sub-menu" ng-hide="myVar">
<ul>
<li><a>Search-sub</a></li>
<li><a>Search-sub</a></li>
<li><a>Search-sub</a></li>
<li><a>Search-sub</a></li>
</ul>
</div>
</li>
<li class="menu-li"><a>Home<i class="fa fa-chevron-down pull-right"></i></a></li>
<li class="menu-li"><a>Dashboard<i class="fa fa-chevron-down pull-right"></i></a></li>
<li class="menu-li"><a>Register<i class="fa fa-chevron-down pull-right"></i></a></li>
<li class="menu-li"><a>Login<i class="fa fa-chevron-down pull-right"></i></a></li>
</ul>
</nav>
In Angular 2+ ng-hide won't work you can use *ngIf directive for hide and show element.
Example
TS -
isLoading = true // change value as per your requirement
HTML -
<div *ngIf="isLoading">Loading... </div>
Hope this will help!
If we presume that you are using Angular2+ and not AngularJS:
ng-hide is Angularjs directive, you can't use it in Angular2+. You can use *ngIf if you want your DOM elements to be actually rendered or not, and [hidden] which is equivalent of ng-show in angularjs, when you want your DOM element to be rendered but not displayed.
In your case, you can have a property in your .ts file:
public loading: boolean = false; // update this property when you have to...
And in your .html template:
<div class="sub-menu" *ngIf="loading">
<ul>
<li><a>Search-sub</a></li>
<li><a>Search-sub</a></li>
<li><a>Search-sub</a></li>
<li><a>Search-sub</a></li>
</ul>
</div>

How to use custom directives in html

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?

directive parameter issue with angular templateURL

i have following directive
App.directive('minuteListDirective', function () {
return {
restrict: "A,E",
required: 'ng-model',
templateUrl: "/app/profile/company-minutes/templates/minute-list.html",
controller: "CompanyMinutesController",
replace: true,
scope: {
mode: '#mode',
},
link: function (scope, el, attrs) {
},
}
});
when i remove scope: {
mode: '#mode',
},
from directive , the template render correctly as below (minute-list.html )
<div dropdown="dropdown" class="btn-group btn-group-sm">
<button dropdown-toggle="" ng-class="'btn btn-default'" class="ng-binding btn btn-default" aria-haspopup="true" aria-expanded="false">
<b class="caret"></b>
</button>
<ul role="menu" ng-class="'dropdown-menu animated flipInX'" class="dropdown-menu animated flipInX">
<li>
edit
</li>
<li class="hide-edit-mode">
delete
</li>
</ul>
</div>
but when i add scope: { mode: '#mode'} to directive the template render but it removes ng-class from rendered template
<div dropdown="dropdown" class="btn-group btn-group-sm">
<button dropdown-toggle="" ng-class="''" class="ng-binding" aria-haspopup="true" aria-expanded="false">
<b class="caret"></b>operation
</button>
<ul role="menu" ng-class="''">
<li>
edit
</li>
<li class="hide-edit-mode">
delete
</li>
</ul>
</div>
and here is original template without rendering
<div dropdown="dropdown" class="btn-group btn-group-sm">
<button dropdown-toggle="" ng-class="'btn btn-default'" class="ng-binding btn btn-default">
<b class="caret"></b> {{resources.grid.ACTION_BUTTOM_TEXT}}
</button>
<ul role="menu" ng-class="'dropdown-menu animated flipInX'" class="dropdown-menu animated flipInX">
<li>
edit
</li>
<li class="hide-edit-mode">
delete
</li>
</ul>
</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>

ng-click fires twice in directive controlled navigation

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>

Resources