Using same directive with different value in the same view - angularjs

I have two tabs, each tab contains a set of thumbnails which I have set as a directive. Tab is also coming via a directive, and thumbnails too. The data to be pushed into the thumbnail is stored in an constant file. But each tabs thumbnails data is different. How do I implement that?
For setting tabs and thumbnail:
<tabset> <tab heading="{{heading.title}}" id="heading1" set-thumb="setThumbnail(arg)">
<thumbnail></thumbnail>
</tab> <tab heading="{{heading1.title}}" id="heading2" set-thumb="setThumbnail(arg)">
<thumbnail></thumbnail>
</tab> </tabset>
Thumbnail HTML:
<div class="row" style="padding: 20px;">
<div class="col-md-3" ng-repeat="data in thumbnailDetails">
<div class="thumbnail-sim">
<img src="resources/images/Sim-thumbnail.png" alt="sim"
class="thumbnail-img">
<div class="thumbnail-caption">
<div class="thumbnail-name">{{ data.name }}</div>
<div class="thumbnail-date">{{ data.time }}</div>
<div class="thumbnail-details">
{{ data.details }}
</div>
</div>
</div>
<br>
</div>
Thumbnail directive:
angular.module('thumbnailDirectiveModule', [])
.directive('thumbnail', function() {
return {
restrict: 'E',
templateUrl: 'UI/templates/thumbnail.html'
};
});
service part method:
s.getThumbnail = function(thisId){
if(thisId === 'heading1'){
return thumbnailDetails1;
}else if (thisId === 'heading2'){
return thumbnailDetails2;
}
};
Tab directive:
angular.module('tabsDirectiveModule', [])
.directive('tab', function() {
return {
restrict: 'E',
transclude: true,
template: '<div role="tabpanel" ng-show="active" ng-transclude></div>',
require: '^tabset',
scope: {
heading: '#',
id: '#',
setThumb: '&'
},
link: function(scope, elem, attr, tabsetCtrl) {
scope.active = false;
tabsetCtrl.addTab(scope, attr.id);
}
};
})
.directive('tabset', function() {
return {
restrict: 'E',
transclude: true,
scope: { },
templateUrl: 'UI/templates/tabset.html',
bindToController: true,
controllerAs: 'tabset',
controller: function() {
var self = this;
self.tabs = [];
self.addTab = function addTab(tab, id) {
tab.setThumb({arg: id});
self.tabs.push(tab);
if(self.tabs.length === 1) {
tab.active = true;
}
};
self.select = function(selectedTab) {
angular.forEach(self.tabs, function(tab) {
if(tab.active && tab !== selectedTab) {
tab.active = false;
}
});
selectedTab.active = true;
};
}
};
});

Related

Angular1 Send Variable to directive

How can I send variable to directive? My code actually doesn't work, but I did everything from your comments :(
As you can see in my .html file, {{ ctrl.emptyParent.name }} is working.
.html
<div cms-dropdown emptyParent="emptyParent.name" classes="btn-default">
<i style="opacity: 0.8">{{ emptyParent.name }}</i>
</div>
directive
.directive('cmsDropdown', [function(){
return {
restrict: 'A',
scope: {
emptyParent: '=',
},
transclude: true,
template:
`
{{emptyParent}} Hi
`
link: function($scope, $element, $attrs){
}
};
}]);
and variable
this.emptyParent = {
_id: 'empty',
name: '~~#(brak)#~~',
parentAlbumId: null,
position: -1,
createdDate: undefined,
modifiedDate: undefined
};
change emptyParent="emptyParent.name" to empty-parent="emptyParent.name"
angular.module("app",[])
.controller("ctrl",function($scope){
$scope.emptyParent = {"name":"jhon"}
})
.directive('cmsDropdown', [function(){
return {
restrict: 'A',
scope: {
emptyParent: '=',
},
transclude: true,
template:
`
{{emptyParent}} Hi
`,
link: function($scope, $element, $attrs){
}
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div cms-dropdown empty-parent="emptyParent.name" classes="btn-default">
<i style="opacity: 0.8">{{ emptyParent.name }}</i>
</div>
</div>

Variable value not passing in a controller using directive with ng-class

I am referencing the value of the variable in a controller in an ng-class template but its not working.
here is the html directive template URl :
<div class="tooltip-anchor">
<div class=" tooltip-content ehub-body" ng-class="{ 'tooltip__content--disabled': tooltipContentValue}" ng-transclude>Tooltip content</div>
</div>
Here is where i am using the directive in the index page
<div style="text-align:center;">
<ehub-tooltip>Hello i am here, and i am her to stay</ehub-tooltip>over here
<ehub-tooltip>Be nice to people on your way up and they will be nice to you on your way down</ehub-tooltip>click me
</div>
And here is the directive:
in this directive i am creating a variable and setting it to false and also trying to use it in an ng-class attribute
(function (window) {
'use strict';
angular
.module('ehub.component.tooltip', [])
.controller('ehubTooltipCtrl', ['$scope', function ($scope) {
$scope.tooltipContentValue = false;
}])
.directive('ehubTooltip', ehubTooltip);
function ehubTooltip() {
var directive = {
controller: "ehubTooltipCtrl",
link: link,
transclude: true,
templateUrl: 'ehub-tooltip.html',
restrict: 'E'
};
return directive;
function link(scope, element, attrs) {
scope.keyupevt = function () {
if (event.keyCode === 27) {
$scope.tooltipContentValue = true;
}
}
}
}
})();
Try this working jsfiddle.
angular.module('ExampleApp', ['ngMessages'])
.controller('ExampleController', function($scope) {
})
.directive('ehubTooltip', function() {
var directive = {
link: link,
transclude: true,
template: '<div class="tooltip-anchor"><div class=" tooltip-content ehub-body" ng-class="{ \'tooltip__content--disabled\': tooltipContentValue}" ng-transclude>Tooltip content</div></div>',
restrict: 'E'
};
function link(scope, element, attrs) {
scope.tooltipContentValue = false;
scope.keyupevt = function() {
if (event.keyCode === 27) {
scope.tooltipContentValue = true;
}
}
}
return directive;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController">
<div style="text-align:center;">
<a href="" ng-keyup="keyupevt()">
<ehub-tooltip>Hello i am here, and i am her to stay</ehub-tooltip>over here</a>
<a href="" ng-keyup="keyupevt()">
<ehub-tooltip>Be nice to people on your way up and they will be nice to you on your way down</ehub-tooltip>click me</a>
</div>
</div>
</div>

Modify DOM content after Scope Variables have been translated

I want to truncate my table cells but fit as much as possible content into them. There is an excellent solution (fiddle) which I want to implement in a directive. I need to transform a table cell from
<td>veryverylongunbreakablecontent</td>
to
<td>
<div class="container">
<div class="content">veryverylongunbreakablecontent</div>
<div class="spacer">veryv­erylon­gunbr­eakab­lecon­tent</div>
<span> </span>
</div>
</td>
This is a simplified example. My table cells consist of angular scope variables:
<td>{{ item.attribute.verylong }}</td>
What I have come up with so far is a directive
.directive('mwTableTruncate', function ($compile) {
return {
restrict: 'A',
templateUrl: 'modules/ui/templates/mwComponents/mwTableTruncate.html',
transclude: true,
compile: function( tElem, tAttrs ){
}
};
});
with a template
<div class="containerTest">
<div class="content">
<div ng-transclude></div>
</div>
<div class="spacer">
<div ng-transclude></div>
</div>
<span> </span>
</div>
Now I need to add soft hyphens (­) every 5 characters to the text in the spacer div. How can I do this?
The problem is I need to access the spacer div text after all the scope variables have been translated to add the soft hyphens.
edit#1 #sirrocco
I have examined the output from the compile, pre-link, link, post-link phase. None of these phases do translate the scope variables.
link phase
.directive('mwTableTruncate', function ($compile) {
return {
restrict: 'A',
link: function (scope, iElem, attrs) {
console.log('link => ' + iElem.html());
console.log('link text => ' + iElem.text());
}
};
});
gives me in the console:
link =>
{{ item.attributes.surname }}
link text =>
{{ item.attributes.surname }}
compile, pre-link, post-link
.directive('mwTableTruncate', function ($compile) {
return {
restrict: 'A',
templateUrl: 'modules/ui/templates/mwComponents/mwTableTruncate.html',
transclude: true,
compile: function( tElem, tAttrs ){
console.log('Compile => ' + tElem.html());
return {
pre: function(scope, iElem, iAttrs){
console.log('pre link => ' + iElem.html());
console.log('pre link text => ' + iElem.text());
},
post: function(scope, iElem, iAttrs){
console.log('post link => ' + iElem.html());
console.log('post link text => ' + iElem.text());
//debugger;
}
};
}
};
});
output in the console:
pre link => <div class="containerTest">
<div class="content">
<div ng-transclude=""></div>
</div>
<div class="spacer">
<div ng-transclude=""></div>
</div>
<span> </span>
</div>
pre link text =>
 
post link => <div class="containerTest">
<div class="content">
<div ng-transclude=""><span class="ng-binding ng-scope">
{{ item.attributes.surname }}
</span></div>
</div>
<div class="spacer">
<div ng-transclude=""><span class="ng-binding ng-scope">
{{ item.attributes.surname }}
</span></div>
</div>
<span> </span>
</div>
post link text =>
{{ item.attributes.surname }}
{{ item.attributes.surname }}
As you can see, none of the {{ item.attributes.surname }} variables got translated.
edit#2
Based on the hint with the timeout function in the post link phase I have come up with this solution:
directive
.directive('mwTableTruncate', function($timeout) {
return {
restrict: 'A',
templateUrl: 'modules/ui/templates/mwComponents/mwTableTruncate.html',
transclude: true,
compile: function() {
var softHyphenate = function (input) {
var newInput = '';
for (var i = 0, len = input.length; i < len; i++) {
newInput += input[i];
if (i % 5 === 0) {
newInput += '­';
}
}
return newInput;
};
return {
post: function (scope, iElem) {
$timeout(function () {
var text = iElem.find('div.spacer').text().trim();
// add tooltips
iElem.find('div.content').prop('title', text);
// add soft hyphens
var textHyphenated = softHyphenate(text);
iElem.find('div.spacer').html(textHyphenated);
});
}
};
}
};
});
template
<div class="containerTest">
<div ng-transclude class="content"></div>
<div ng-transclude class="spacer"></div>
<span> </span>
</div>
How would it look like with an isolated scope sirrocco rbaghbanli?
Do not transclude. Simply set your item.attribute.verylong as ng-model for your directive. Then get the object to manipulate as you wish. In the controller add all spacers you need. Then just display the result in {{ ... }} in your template for directive.
Code:
.directive('truncateString', function ($compile) {
return {
restrict: 'E',
templateUrl: '{{ strWithBreaks }}',
scope: {
str: '=ngModel'
},
controller: ['$scope', function ($scope) {
$scope.strWithBreaks = (function (input) {
var newInput = '';
for (var i = 0, len = input.length; i < len; i++) {
newInput += input[i];
if (i % 5 === 0) {
newInput += '­';
}
}
return newInput;
})(str);
}]
};
});
Usage:
<truncate-string ng-model="myVeryLongString"></truncate-string>
The directive without transclude would probably look something like:
.directive('mwTdTruncate', function() {
return {
restrict: 'A',
templateUrl: 'modules/ui/templates/mwComponents/mwTableTruncate.html',
scope:{
longText: '#mwLongText'
},
replace:true,
link: function(scope) {
var softHyphenate = function (input) {
var newInput = '';
for (var i = 0, len = input.length; i < len; i++) {
newInput += input[i];
if (i % 5 === 0) {
newInput += '­';
}
}
return newInput;
};
scope.softText = softHyphenate(scope.longText);
}
};
});
and the template:
<td>
<div class="container">
<div class="content">{{longText}}</div>
<div class="spacer">{{softText}}</div>
<span> </span>
</div>
</td>
used like:
<td mw-td-truncate mw-long-text='{{yourTextVariable}}'>veryverylongunbreakablecontent</td>

Pass object to custom angular bootstrap ui tooltip

Im trying to pass and object to a custom angular-ui bootstrap tooltip component.
My code so far is a new directive:
angular.module('ui.bootstrap.korv', [ 'ui.bootstrap.tooltip' ])
.directive('korvPopup', function () {
return {
restrict: 'EA',
replace: true,
scope: { title: '#', content: '#', placement: '#', animation: '&', isOpen: '&', species: '='},
templateUrl: 'korv.html'
};
})
.directive('korv', [ '$tooltip', function ($tooltip) {
return $tooltip('korv', 'korv', 'click');
}]);
and the the template:
<script type="text/ng-template" id="korv.html">
<div class="tooltip {{ placement }}" ng-class="{ in: isOpen(), fade: animation() }">
<div class="tooltip-arrow"></div>
<div class="tooltip-inner">obj is {{content}} obj.a is {{content.a}}</div>
</div>
and in the view:
<li korv="{a:1234}">
outputs:
obj is {a:1234} obj.a is
So the object I pass converts to a json string and I can not access its fields. Using tooltipHtmlUnsafe is not an option here.
I tried changing content: '#' to content: '=' but that doesn't work.
So how can I pass an object to tooltip?
This is not possible due to the implementation of angular bootstrap ui tooltip. My solution was to create a new directive:
angular.module('app').directive('speciesInfo', function ($log, $timeout) {
return {
restrict: 'A', // only activate on element attribute
scope: {
species: "=speciesInfo"
},
link: function (scope, elem, attrs) {
var showPromise;
elem.on('mouseenter', function () {
showPromise = $timeout(function () {
elem.children('.popover').show();
}, 500);
});
elem.on('mouseleave', function () {
$timeout.cancel(showPromise);
elem.children('.popover').hide();
});
},
templateUrl: 'species-info.html'
}
});
now it is easy to style the tooltip:
<div class="popover right in fade">
<div class="arrow"></div>
<div class="popover-inner">
<div class="popover-title text-center">
{{species.vernacularName}} <img class="small-species" ng-src="{{species.iconFileName}}"/>
</div>
<div class="popover-content">
<em> {{species.scientificName}}</em>
</div>
</div>

how to pass an object to a directive template in angularjs?

I am trying to make a re-usable directive with ui-bootstrap modal.
It's almost working except the options
here is the directive :
directive('update', function() {
return {
restrict: "E",
templateUrl: "tplModal.html",
scope: {
selected:"="
},
link: function(scope, elm, attr){
scope.open = function (obj) {
scope.shouldBeOpen = true;
};
scope.close = function () {
scope.shouldBeOpen = false;
};
scope.opts = {
backdropFade: true,
dialogFade:true
};
}
}
})
and tplModal.html
<button class='btn' ng-click='open(selected)'>Update</button>
<div modal="shouldBeOpen" close="close()" options="opts">
<div class="modal-header">
<h3><i class="lead" icon="{{selected.type}}"></i> {{selected.name}}</h3>
</div>
<div class="modal-body">
<!-- stuffs here -->
</div>
<div class="modal-footer">
<button class="btn btn-warning cancel" ng-click="close()">Cancel</button>
</div>
</div>
despite the scope.opts, there is no fade effect.
here is the whole code :
http://plnkr.co/edit/Ab4BOH?p=preview
what am i doing wrong ?
The problem is that you add opts property to scope in the post-linking function, which will be called after modal directive's linking function, so the modal directive will never get those options.
The solution is to move scope.opts = ... to pre-linking function:
directive('update', function() {
return {
...
compile: function() {
return {
pre: function(scope, elm, attr){
...
scope.opts = {
backdropFade: true,
dialogFade: true
};
}
};
}
}
}
http://plnkr.co/edit/iZaEiM?p=preview

Resources