Reputation: 1024
We are brand new to AngularJS but are trying to display some html tooltips from a custom directive in Angular and since new new to this technology are struggling to come up with a proper solution to this issue.
We had a version of a solution running using Angular+Web API, but discovered the mouseover events and CRUD functionality belonged in directives instead of the controller, so we're pulling that out and re-building.
Currently in a Plunker POC, we have:
SVG Sample:
<g id="f3s362c16">
<rect x="577.5" y="533.2" fill="none" width="22.2" height="25.7"/>
<polyline fill="none" stroke="#CEDEED" stroke-width="0.6468" stroke-miterlimit="10" points="590.4,559 577.5,559 577.5,533.2
599.5,533.2 599.5,550 "/>
<text transform="matrix(1 0 0 1 590.9561 557.4941)" font-family="arial, sans-serif" font-size="5.1408">362.16</text>
Json sample:
{"Id":1,"empNum":null,"fName":" Bun E.","lName":"Carlos","refacName":null,"deptId":"Drums","divisionId":null,"jobDesc":"Drummer","seatTypeId":1,"officeCode":null,"phone":null,"seatId":"f3s362c12 ","oldSeatId":null,"floor":3,"section":"313 ","seat":"12 "}
we have a scope variable for the json defined in the html file:
{{ **empData** }}
Controller file data load:
var onLoadComplete = function (response) {
$scope.**empData** = response.data;
}
//error
var onError = function(reason) {
$scope.error = "Could not get the data";
}
//get data
$http.get('data.json')
.then(onLoadComplete, onError);
Directive to load SVG and add directive to cube element
//directive loads SVG into DOM
angular.module('FFPA').directive('svgFloorplan', ['$compile', function ($compile) {
return {
restrict: 'A',
templateUrl: 'test.svg',
link: function (scope, element, attrs) {
var groups = element[0].querySelectorAll("g[id^='f3']")
angular.forEach(groups, function (g,key) {
var cubeElement = angular.element(g);
//Wrap the cube DOM element as an Angular jqLite element.
cubeElement.attr("cubehvr", "");
$compile(cubeElement)(scope);
})
}
}
}]);
Cube Hover Directive:
angular.module("FFPA").directive('cubehvr', ['$compile', function ($compile) {
return {
restrict: 'A',
scope: true,
empData: "=",
link: function (scope, element, attrs) {
//id of group
scope.elementId = element.attr("id");
//function call from line 63
scope.cubeHover = function () {
//groupId is the id of the element hovered over.
var groupId = scope.elementId;
alert(scope.elementId);
//Here need to get access to scope empdata json to filter and
//match to the cube #.
//IE: If I hover over 362.12, return json data for
//{"Id":1,"empNum":null,"fName":" Bun E.","lName":"Carlos","refacName":null,"deptId":"Drums","divisionId":null,"jobDesc":"Drummer","seatTypeId":1,"officeCode":null,"phone":null,"seatId":"f3s362c12 ","oldSeatId":null,"floor":3,"section":"313 ","seat":"12 "}
//since we don't have access to the empData scope variable, cannot run filter.
var thisData = empData.filter(function (d) {
return d.seatId.trim() === groupId
});
//after we get a match, we need to display a tooltip with save/cancel buttons.
};
element.attr("ng-mouseover", "cubeHover()");
element.removeAttr("cubehvr");
$compile(element)(scope);
}
}
}]);
We are getting the alert for the specific cube hover, but I think we need to get access to the page scope variable to do the filter:
var thisData = empData.filter(function (d) {
return d.seatId.trim() === groupId
});
Once we get a match, I think we should be able to append html to our div tag and display it:
<div class="tooltip"></div>
Angular:
tooltip.html("Name: " + thisData[0].fName + " " +
thisData[0].lName + "<br>Role: " +
thisData[0].jobDesc + "<br>Extension: " +
thisData[0].phone)//+ "<br>Avatar: <img src=" + thisData[0].Avatar + ">")
.style("top", (d3.event.pageY + 15) + "px").style("left", (d3.event.pageX + 0) + "px")
.style("visibility", "visible");
At this point, we're not sure how to get the view/page scope variable {{empData}} in the hover (2nd) directive since we're already passing cubeHvr the directive:
angular.module("FFPA").directive('cubehvr', ['$compile', function ($compile) {...}
Thanks in advance for any direction you might give us here.
Upvotes: 2
Views: 603
Reputation: 9330
Define a service as the following code
angular.module('FFPA')
.service('dataService', function () {
this.getData = function(){
return $http.get('data.json').then(function(){
return response.data;
}, function(){
return {err:"Could not get the data"};
}
);
}
});
and then inject it to any directive, controller, component or service.
angular.module("FFPA").directive('cubehvr', ['$compile','dataService', function ($compile,dataService) {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attrs) {
dataService.getData().then(function(data){
scope.emData=data;
})
Upvotes: 1