accessing values from a controller to directive which is having local scope - angularjs

i have a directive(with local scope) and a controller. If i want to access the students data from the controller to the directive, how do i need to do it ? below is the code.
My purpose is to build a chart which shows the details of students who were absent and present and when the user clicks on the absent/present i should be able to show a table with the details of it.
JS
app.directive('hcPieChart', function () {
return {
restrict: 'E',
template: '<div></div>',
scope: {
title: '#',
data: '='
},
link: function (scope, element,attrs) {
Highcharts.chart(element[0], {
chart: {
type: 'pie',
spacingTop: 30,
width: 300,
height: 250,
},
title: {
text: ''
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
showInLegend: true,
dataLabels: {
enabled: false,
format: '<b>{point.name}</b>: {point.percentage:.1f} %'
},
events: {
click: function(event)
{
how can i access the student details from the controller to this function ? i want to use the click to call a rest service (inside the controller ).
},
series: [{
data: scope.data
}]
});
}
};
})
app.controller('myCtrl', ['$scope','$http','DTOptionsBuilder', 'DTColumnBuilder',function($scope,$http,DTOptionsBuilder, DTColumnBuilder)
{
$scope.showTableDetails=function(x,typeOfData){
$scope.showTableDetailsData="";
$scope.showTableName="";
$scope.checkAnomaly= false;
if(typeOfData==1){
dataCatagory="total";
$scope.checkAnomaly==false;
}else if(typeOfData==2){
dataCatagory="present";
$scope.checkAnomaly==false;
}else if(typeOfData==3){
dataCatagory="absent";
$scope.checkAnomaly==false;
}
$http.get('http://localhost/rest/tripsStatus/studentdetails/'+x.tripDetails.tripId+'/'+dataCatagory+'/am').
then(function(result) {
$scope.showTableDetailsData = result.data.messages[0].data.studentDetails;
$scope.showTableName=x.tripDetails.tripName;
});
HTML
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="x in data track by $index" style="float:left";>
<div class="wrapper">
<trip-details></trip-details>
<div class="chartdiv">
<hc-pie-chart data="showPieChart(x)"></hc-pie-chart>
</div>
</div>
</div>
</div>

If you use the directive at "first level", i.e not a directive within a directive you can use $parent:
link: function (scope, element, attrs) {
...
scope.$parent.showTableDetails(...)
}
If you use a directive within another directive it would be $scope.$parent.$parent and so on.

Related

function nested in directive not alerting

two questions: is it possible to access my showData() function that is located in the controller even though its not within the directive? I also have placed one in the directive but it is still not alerting? please advice on what i am doing wrong.
var myApp = angular.module('myApp', []);
myApp.controller('productController', ['$scope',
function($scope) {
$scope.product1 = {
name: 'Phone',
price: '100',
stock: true
};
$scope.product2 = {
name: 'Ipad',
price: '1000',
stock: true
};
$scope.product3 = {
name: 'Laptop',
price: '800',
stock: false
};
$scope.showData = function() {
alert("Display Data");
}
}
]);
myApp.directive('myInventory', function() {
return {
restrict: 'E',
scope: {
name: '#',
price: '#'
},
template: '{{name}} costs {{price}} <button ng-click="showData()">change cost</button>'
};
directive.link = function($scope, element) {
$scope.showData = function() {
alert("Display Data");
};
}
return directive;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<body ng-App="myApp">
<div ng-controller="productController">
<h1>{{product1.name}}</h1>
<my-inventory name="{{product1.name}}" price="{{product1.price}}"></my-inventory>
<h1>{{product2.name}}</h1>
<my-inventory name="{{product2.name}}" price="{{product2.price}}"></my-inventory>
<h1>{{product3.name}}</h1>
<my-inventory name="{{product3.name}}" price="{{product3.price}}"></my-inventory>
</div>
</body>
In your directive, you're returning too early so half of your code isn't executing.
myApp.directive('myInventory', function() {
return {
restrict: 'E',
scope: {
name: '#',
price: '#'
},
template: '{{name}} costs {{price}} <button ng-click="showData()">change cost</button>',
link: function($scope, element) {
$scope.showData = function() {
alert("Display Data");
};
}
});
It's possible for you to pass showData from the controller to the directive.
myApp.directive('myInventory', function() {
return {
restrict: 'E',
scope: {
name: '#',
price: '#',
showData: '&' // Add it to your scope like so
},
template: '{{name}} costs {{price}} <button ng-click="showData()">change cost</button>',
link: function($scope, element) {
// Don't need showData() here anymore
}
});
Call your directive with your function like so
<my-inventory show-data="showData()" name="{{ something }}" price="{{ something }}"></my-inventory>

Bind array to highcharts data part using Angular Directives

I need to bind an array of data to "data" part of highcharts which is embedded in
Angular directives but I don't know how exactly to do that.
This is my controller part which fetches data from repository:
vm.data = [];
function getVmAll(forceRefresh) {
return datacontext.esxservers.getAllWithoutPaging(forceRefresh, vm.vmAllSearchTemp)
.then(function (data) {
vm.data= data;
});
return data;
}
);
}
and here is the template which I use the controller in it:
<section class="mainbar" data-ng-controller="mbVirtualizationOverviewCtrl as vm">
<mb-virtualization-overview-donut-chart value="vm.data"></mb-virtualization-overview-donut-chart>
</section>
and the last but not least one is my directive which I use highcharts settings:
'use strict';
angular.module('app').directive('mbVirtualizationOverviewDonutChart', [
function () {
return {
restrict: "E",
templateUrl: '/app/directives/virtualizationOverview/mbVirtualizationOverviewDonutChartTemplate.html',
scope: {
value : "="
},
link: function (scope, el, attrs) {
scope.chart = Highcharts.chart(el[0], {
chart: {
type: 'pie',
},
title: {
text: scope.innerTitle
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
},
series: [{
data: undefined
}]
});
var init = true;
scope.$watch(
function () {
var chart = scope.chart;
if (init && scope.value.length > 0) {
init = false;
scope.value.forEach(function (item, index) {
chart.series[0].data.push(item);
});
}
});
}
};
}
]);

Link function of Directive is not being called

I have a scenario where I need to show a pie-chart in a popup modal (used ui-bootstrap modal). I used c3.js for my pie-chart requirement (inside a directive).
The pie-chart is not loading inside the pop up. But to my surprise when I tried to debug the issue when I opened the console it is loading. When I re-size the window it is loading.
How can i fix this issue?
'use strict';
angular.module('App')
.directive('pieChartDirective', function() {
return {
restrict: 'A',
scope: {
chartdata: '=',
},
link: function(scope, elem, attrs) {
var chart = c3.generate({
bindto: '#chart',
data: {
columns: [
['Javascript', scope.chartdata.Javascript],
['HTML', scope.chartdata.HTML],
['Css', scope.chartdata.Css],
['Angular', scope.chartdata.Angular],
['Bootstrap', scope.chartdata.Bootstrap],
['Jquery', scope.chartdata.Jquery],
['Communication', scope.chartdata.Communication]
],
type: 'pie',
},
legend: {
show: false
},
tooltip: {
format: {
value: function(value, ratio, id, index) {
return value;
}
}
}
});
}
};
});
Html:
<div pie-chart-directive chartdata="oChartData">
<div id="chart"></div>
</div>
Are you shure, that you include your directive properly in your html code as
<div pie-chart-directive></div>
Maybe you have to change your restriction to 'E' to use your directive as a tag elment
<pie-chart-directive chartdata="myData"></pie-chart-directive>
The reason could be, that at the moment you try to generate the chart, your '#chart' div isn't yet present in the dom tree. Therefore you have to resize to trigger a new draw. Try to wait until the dom is loaded
$('#chart').ready(function() {
var chart = c3.generate({
bindto: '#chart',
data: {
columns: [
['Javascript', scope.chartdata.Javascript],
['HTML', scope.chartdata.HTML],
['Css', scope.chartdata.Css],
['Angular', scope.chartdata.Angular],
['Bootstrap', scope.chartdata.Bootstrap],
['Jquery', scope.chartdata.Jquery],
['Communication', scope.chartdata.Communication]
],
type: 'pie',
},
legend: {
show: false
},
tooltip: {
format: {
value: function(value, ratio, id, index) {
return value;
}
}
}
});
});
I got it by giving size property:
link: function(scope, elem, attrs) {
var chart = c3.generate({
bindto: '#chart',
size: {
width:400,
height:350
},
data: {
columns: [
['Javascript', scope.chartdata.Javascript],
['HTML', scope.chartdata.HTML],
['Css', scope.chartdata.Css],
['Angular', scope.chartdata.Angular],
['Bootstrap', scope.chartdata.Bootstrap],
['Jquery', scope.chartdata.Jquery],
['Communication', scope.chartdata.Communication]
],
type: 'pie',
},
legend: {
show: false
},
tooltip: {
format: {
value: function(value, ratio, id, index) {
return value;
}
}
}
});
}

how to make custom directive or pass variable in directive in angular js

I am trying to make bar chart in angular .I am able to make in jquery (using highchart.js file).This is link which I am able to make in jquery code
http://plnkr.co/edit/SD1iSTBk8o1xi3unxKeE?p=preview .I am getting the correct output.But the same thing I need to show using angularjs using directive .So I try to make directive .My issue is how I will pass my parameter in directive
here is my angular code.
http://plnkr.co/edit/LwonlkbCy3asHXyToVMz?p=catalogue
// Code goes here
angular.module('contactsApp', ['ionic'])
.controller('MainCtrl', function($scope) {
}).directive('chartTest',function(){
return {
restrict: 'E',
scope:{
},
link :function(scope, element, attrs){
element.highcharts({
chart: {
type: 'bar'
},
title: {
text: chart_title
},
xAxis: {
categories: xAxisarry
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
name: names[0],
data: janeData
}, {
name: names[1],
data: joneData
}]
});
}
}
});
I want it look like same as in jquery ? can we pass variable in directive using scope?
You need to pass the parameters from the isolated scope of your directive, and then inside your directive you need to use $ on directive element to make highcharts method available.
Markup
<chart-test chart-title="chartTitle" x-axisarry="xAxisarry"
y-axis="yAxis" json-data="janeData" names="names"></chart-test>
Controller
.controller('MainCtrl', function($scope) {
$scope.chartTitle = "";
$scope.xAxisarry = ['Apples', 'Bananas', 'Oranges'];
$scope.yAxis = 'Fruit eaten';
$scope.data = {
jane: [1, 0, 4],
jone: [5, 7, 3]
};
$scope.names = ["jane", "jone"];
})
Directive
.directive('chartTest', function() {
return {
restrict: 'E',
scope: {
chartTitle: '=',
xAxisarry: '=',
yAxis: '=',
jsonData: '=',
names: '='
},
link: function(scope, element, attrs) {
$(element).highcharts({
chart: {
type: 'bar'
},
title: {
text: scope.chartTitle
},
xAxis: {
categories: scope.xAxisarry
},
yAxis: {
title: {text: 'Fruit eaten'}
},
series: [{
name: scope.names[0],
data: scope.jsonData['jane']
}, {
name: scope.names[1],
data: scope.jsonData['jone']
}]
});
}
}
});
Working Plunkr

Angular UI Bootstrap's Radio Button inside a directive with ng-repeat does not show default value properly

Essentially, I have a directive that is used as a 3 way filter using a radio button. Unfortunately, it needs to have a default state and that default state has to actually be shown in the UI, the problem is that although the model is updated properly, the UI is not. Here is a plunkr that demonstrates the issue:
http://plnkr.co/edit/8pljDFyRfInI4Q0qSTmL?p=preview
The directive is used the following way:
<filter model="model"/>
Where the model is defined as this.model = { value: {} } in the controller
Here is an updated code.
At first I want to say what ng-model directive works only with input elements,
and also I changed the isActive: 'Yes/No' to true/false
// Code goes here
var filters = angular.module('filters', ['ui.bootstrap']);
filters.controller('FilterCtrl', function() {
this.model = { value: {} };
});
filters.directive('filter', function () {
return {
restrict: 'E',
scope: {
model: '='
},
template: '<div class="btn-group">' +
'<label ng-repeat="choice in choices" class="btn btn-{{ choice.buttonClass }}" ng-class="{active: choice.value.isActive}"' +
'btn-radio="{{ choice.value }}"><i class="fa {{ choice.icon }}"></i> {{ choice.name }}</label>' +
'</div>',
link: function (scope, element, attrs) {
scope.choices = [
{ value: { isActive: true }, name: 'Active', buttonClass: 'default', icon: 'fa-circle' },
{ value: null, name: 'Both', buttonClass: 'primary', icon: 'fa-arrows-h' },
{ value: { isActive: false}, name: 'Inactive', buttonClass: 'danger', icon: 'fa-circle-o' },
];
scope.model.value = _.first(_.filter(scope.choices, { value: { isActive: 'Yes' } })).value;
}
}
});

Resources