getting Cannot read property '0' of undefined when i click google map marker? - angularjs

I am getting error when i click google map marker how to solve this problem i have enclosed fiddle http://jsfiddle.net/cLADs/135/ .when i click button it should pass id value based on marker click some one help me out to move forward.
var gmarkers1 = [];
var markers1 = [];
var infowindow = new google.maps.InfoWindow({
content: ''
});
// Our markers
markers1 = [
['0', 'Madivala', 12.914494, 77.560381, 'car','as12'],
['1', 'Majestic', 12.961229, 77.559281, 'third','as13'],
['2', 'Ecity', 12.92489905, 77.56070772, 'car','as14'],
['3', 'Jp nagar', 12.91660662, 77.52047465, 'second','as15']
];
/**
* Function to init map
*/
function initialize() {
var center = new google.maps.LatLng(12.9667,77.5667);
var mapOptions = {
zoom: 12,
center: center,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
for (i = 0; i < markers1.length; i++) {
addMarker(markers1[i]);
}
}
/**
* Function to add marker to map
*/
function addMarker(marker) {
var category = marker[4];
var title = marker[1];
var pos = new google.maps.LatLng(marker[2], marker[3]);
var content = marker[1];
var fullContent = marker.slice(1,6).join();
var marker1 = new google.maps.Marker({
title: title,
position: pos,
category: category,
map: map
});
gmarkers1.push(marker1);
// Marker click listener
google.maps.event.addListener(marker1, 'click', (function (marker1, fullContent) {
return function () {
console.log('Gmarker 1 gets pushed');
infowindow.setContent(fullContent);
infowindow.open(map, marker1);
map.panTo(this.getPosition());
map.setZoom(15);
///////
// Set CSS for the control border.
var controlDiv = document.createElement("div");
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = '#fff';
controlUI.style.border = '2px solid #fff';
controlUI.style.borderRadius = '3px';
controlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
controlUI.style.cursor = 'pointer';
controlUI.style.marginBottom = '22px';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click to recenter the map';
controlDiv.appendChild(controlUI);
// Set CSS for the control interior.
var controlText = document.createElement('div');
controlText.style.color = 'rgb(25,25,25)';
controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
controlText.style.fontSize = '16px';
controlText.style.lineHeight = '38px';
controlText.style.paddingLeft = '5px';
controlText.style.paddingRight = '5px';
controlText.innerHTML = 'Center Map';
controlUI.appendChild(controlText);
// Setup the click event listeners: simply set the map to Chicago.
controlUI.addEventListener('click', function() {
//Do Whatever you want here
});
controlDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_CENTER].push(controlDiv);
///////
}
})(marker1, fullContent));
}
/**
* Function to filter markers by category
*/
filterMarkers = function (category) {
for (i = 0; i < markers1.length; i++) {
marker = gmarkers1[i];
// If is same category or category not picked
if (marker.category == category || category.length === 0) {
marker.setVisible(true);
}
// Categories don't match
else {
marker.setVisible(false);
}
}
}
// Init map
initialize();
#map-canvas {
width: 500px;
height: 500px;
}
<div id="map-canvas"></div>
<select id="type" onchange="filterMarkers(this.value);">
<option value="">Please select category</option>
<option value="second">second</option>
<option value="car">car</option>
<option value="third">third</option>
</select>

if you print our your i in your listener, you will realized it always to be 4. Basically, the listener does not remember the number i, since it is a globe variable.
Look at the Google Example, they called a function and setup the info window inside.(so that it is i independent) You might do the same too.
Another solution is to store the value i as a tag to the marker, so that you can retrieve it from the marker object.

Related

Raycaster display a Render

I use Threejs and I would like to create a function to display a descriptive card (Render() of Satllite.js) when I click on a Sphere. (Satellite.js)
/********** Imports **********/
import React, { PureComponent } from 'react';
import * as THREE from 'three';
import satData from '../data/sat.json';
export class Satellites extends PureComponent {
constructor(props) {
super(props)
this.state = { open: true }
this.x = {};
this.mouse = {};
this.raycaster = new THREE.Raycaster();
this.mouse = new THREE.Vector2();
}
onDocumentMouseDown = event => {
event.preventDefault()
this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1
this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
// find intersections
this.raycaster.setFromCamera(this.mouse, this.props.camera)
this.intersects = this.raycaster.intersectObjects(
this.scene.className("card"),
false
)
if (this.intersects.length > 0) {
if (this.intersects[0].object.callback)
this.intersects[0].object.callback()
this.intersects[0].className(".card")
this.particle = new THREE.Sprite(this.particleMaterial)
this.particle.position.copy(this.intersects[0].point)
this.particle.scale.x = this.particle.scale.y = 16
this.props.scene.add(this.particle)
}
}
componentDidMount() {
// Satellite Sphere
// this.geometry = new THREE.SphereGeometry( this.props.data.r, 32, 32 );
this.geometry = new THREE.SphereGeometry(10, 32, 32)
this.material = new THREE.MeshBasicMaterial({ color: 0xffff00 })
this.sphere = new THREE.Mesh(this.geometry, this.material)
this.sphere.callback = function() {
console.log('Toto!')
}
this.sphere.position.set(50, 50, 50)
this.props.scene.add(this.sphere)
document.addEventListener('mousedown', this.onDocumentMouseDown, true)
}
// componentDidUpdate() {
// // update satelite pos.
// const radius = 10;
// const scale = radius * 1;
// this.sphere.scale.x = scale;
// this.sphere.scale.y = scale;
// this.sphere.scale.z = scale;
// }
componentWillUnmount() {
document.removeEventListener('mousedown', this.onDocumentMouseDown);
}
render() {
return (
<div>
{satData.map((satDetail, index) => {
return <div key={index} className="card">
<h2>{satDetail.satName.toUpperCase()}</h2>
<div className="cardImg" >
<img src={satDetail.satImg} alt={satDetail.satAlt} />
</div>
<div>
<p>Altitude : <span>{satDetail.alt}</span> km</p>
<p>Longitude : <span>{satDetail.long}</span> °</p>
<p>Latitude : <span>{satDetail.lat}</span> °</p>
</div>
<button onClick={this.closeModal}>Fermer</button>
</div>
})}
</div>
)
}
}
More details here
I got the code of a tutorial that show white squares but I would like to display my div ".card" which is in the "Render"
What is the method ?
Thanks for help !
This answer involves many topics combined, basically you need:
Raycast the mouse click and find the object intersection,
Get info by picked object,
Display it if object was selected, or hide if nothing was picked by mouse.
Test it here: http://jsfiddle.net/mmalex/9k4qbL8s/
let cardShown = false;
function showCard(userText) {
var divElement = $("#card");
if (divElement) {
if (!cardShown) {
divElement.css({
display: "block",
opacity: 0,
height: "0px"
});
}
divElement.text("Object color: " + userText);
if (!cardShown) {
setTimeout(function() {
divElement.css({
opacity: 1,
height: "16px"
});
}, 25);
}
cardShown = true;
}
}
function hideCard() {
var divElement = $("#card");
if (divElement) {
divElement.css({
height: "0px",
opacity: 0
});
cardShown = false;
}
}
var scene = new THREE.Scene();
var raycaster = new THREE.Raycaster();
//create some camera
camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 5;
camera.position.y = 5;
camera.position.z = 5;
camera.lookAt(0, 0, 0);
var controls = new THREE.OrbitControls(camera);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color(0x595959));
document.body.appendChild(renderer.domElement);
// white spotlight shining from the side, casting a shadow
var spotLight = new THREE.SpotLight(0xffffff, 2.5, 25, Math.PI / 6);
spotLight.position.set(4, 10, 7);
scene.add(spotLight);
// collect objects for raycasting,
// for better performance don't raytrace all scene
var clickableObjects = [];
var colors = new RayysWebColors();
for (let k = 0; k < 12; k++) {
var size = 0.5;
var geometry = new THREE.BoxGeometry(size, 0.2, size);
var randomColor = colors.pickRandom();
var material = new THREE.MeshPhongMaterial({
color: randomColor.hex,
transparent: true,
opacity: 0.75
});
var cube = new THREE.Mesh(geometry, material);
cube.userData.userText = randomColor.name;
cube.applyMatrix(new THREE.Matrix4().makeTranslation(k % 3, 0, Math.floor(k / 3) - 1));
scene.add(cube);
clickableObjects.push(cube);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
// this will be 2D coordinates of the current mouse position, [0,0] is middle of the screen.
var mouse = new THREE.Vector2();
var clickedObj; // this objects is hovered at the moment
// Following two functions will convert mouse coordinates
// from screen to three.js system (where [0,0] is in the middle of the screen)
function updateMouseCoords(event, coordsObj) {
coordsObj.x = ((event.clientX - renderer.domElement.offsetLeft + 0.5) / window.innerWidth) * 2 - 1;
coordsObj.y = -((event.clientY - renderer.domElement.offsetTop + 0.5) / window.innerHeight) * 2 + 1;
}
function onMouseUp(event) {
updateMouseCoords(event, mouse);
latestMouseProjection = undefined;
clickedObj = undefined;
raycaster.setFromCamera(mouse, camera); {
var intersects = raycaster.intersectObjects(clickableObjects);
if (intersects.length > 0) {
latestMouseProjection = intersects[0].point;
clickedObj = intersects[0].object;
showCard(clickedObj.userData.userText);
} else {
clickedObj = undefined;
hideCard();
}
}
}
window.addEventListener('mouseup', onMouseUp, false);
animate();

Load from JSON with dynamic patterns, patternSourceCanvas is not defined error return by the serialize JSON data

I am trying to save Fabric.js canvas and reload it using loadFromJson. But I am getting error patternSourceCanvas is not defined. I thought I should make it global so I removed var.
How to set the global variable in Fabric JS and use var patternSourceCanvas?
When I use the code below, then everything is working fine and the JSON is loaded easily.
var t = https://image.freepik.com/free-photo/roof-texture_21206171.jpg
fabric.util.loadImage(t, function(t) {
var svg_width = i.width;
console.log('svg widh' + i.width + 'svg height' + i.height);
console.log('img width t'+ t.width + ' img height' + t.height);
if(svg_width >= 300){
if (i.isSameColor && i.isSameColor() || !i.paths) {
i.setPatternFill({
source: t, repeat: 'repeat', offsetX:200 , offsetY : -110 // working
}), e.fabric.renderAll();
console.log('in if image 300 up ', t);
} else if (i.paths){
for (var r = 0; r < i.paths.length; r++)
i.paths[r].setPatternFill({
source: t, repeat: 'repeat' , offsetX: -100 , offsetY:-110
}), e.fabric.renderAll();
console.log('in image elseeee 300 up ', t);
}
}
})
But when I fill some other new shape with the new patternSourceCanvas variable then it's not working. Kindly help me with dynamic patterns.
var t = https://image.freepik.com/free-photo/roof-texture_21206171.jpg
fabric.Image.fromURL(t, function (img) {
img.scaleToHeight(200);
var patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(img);
patternSourceCanvas.renderAll();
var pattern = new fabric.Pattern({
source: function() {
patternSourceCanvas.setDimensions({
width: img.getScaledWidth() ,
height: img.getScaledHeight()
});
patternSourceCanvas.renderAll();
return patternSourceCanvas.getElement();
},
repeat: r
});
console.log('pattern', pattern);
//p.set('fill', pattern);
canvas.renderAll();
if (i.isSameColor && i.isSameColor() || !i.paths) {
i.setPatternFill(pattern);
} else if(i.paths) {
for (var r = 0; r < i.paths.length; r++) {
i.paths[r].setPatternFill(pattern);
}
}
e.fabric.renderAll();
});
You need to put patternSourceCanvas to global scope/ scope where loadFromJSON can access patternSourceCanvas. Else you can use cors enabled image directly.
DEMO
var imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/2/22/Wikimapia_logotype.svg';
var canvas = new fabric.Canvas('canvas');
var rect = new fabric.Rect({
width: 200,
height: 200,
strokeWidth: 2,
stroke: '#000'
})
canvas.add(rect);
fabric.Image.fromURL(imageUrl, function(img) {
img.scaleToHeight(200);
var patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(img);
patternSourceCanvas.setDimensions({
width: img.getScaledWidth(),
height: img.getScaledHeight()
});
patternSourceCanvas.renderAll();
var pattern = new fabric.Pattern({
source: patternSourceCanvas.getElement()
},
function(patternObj) {
rect.fill = patternObj;
rect.dirty = true;
canvas.renderAll();
});
}, {
crossOrigin: 'annonymous'
});
function loadfromjson() {
var json = canvas.toJSON();
canvas.clear();
setTimeout(function() {
canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));
}, 1000)
}
canvas{
border:2px solid #000;
}
<canvas id="canvas" width="300" height="300"></canvas><br>
<button onclick="loadfromjson()">loadfromjson </button>
<script src='https://rawgit.com/kangax/fabric.js/master/dist/fabric.js'></script>

Marker Clusterer in DevExtreme Mobile

I'm developing an application in DevExtreme Mobile. In application, I use DXMap in this application. How can I use the marker clusterer structure in DevExtreme Mobile App?
You can use Google Maps Marker Clusterer API to create and manage per-zoom-level clusters for a large number of DevExtreme dxMap markers. Here is an example:
 dxMap Marker Clusterer
This example is based on the approach described in the Google Too Many Markers! article
Here is sample code:
$("#dxMap").dxMap({
zoom: 3,
width: "100%",
height: 800,
onReady: function (s) {
var map = s.originalMap;
var markers = [];
for (var i = 0; i < 100; i++) {
var dataPhoto = data.photos[i];
var latLng = new google.maps.LatLng(dataPhoto.latitude, dataPhoto.longitude);
var marker = new google.maps.Marker({
position: latLng
});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers);
}
});
The kry is to use the google maps api. I did it for my app, here how.
This the html, very simple:
<div data-options="dxView : { name: 'map', title: 'Punti vendita', pane: 'master', secure:true } ">
<div data-bind="dxCommand: { id: 'back', behavior: 'back', type: 'back', visible: false }"></div>
<div data-options="dxContent : { targetPlaceholder: 'content' } ">
<div style="width: 100%; height: 100%;">
<div data-bind="dxMap:options"></div> <!--this for the map-->
<div id="large-indicator" data-bind="dxLoadIndicator: {height: 60,width: 60}" style="display:inline;z-index:99;" />
<div data-bind="dxPopover: {
width: 200,
height: 'auto',
visible: visible,
}">
</div>
</div>
</div>
</div>
When the page loads, the app read the gps coordinates:
function handleViewShown() {
navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
jQuery("#large-indicator").css("display", "none"); //this is just a gif to indicate the user to wait the end of the operation
}
If the gps location is correctly read, I save the coordinates (the center of the map):
function onSuccess(position) {
var lat1 = position.coords.latitude;
var lon1 = position.coords.longitude;
center([lat1, lon1]);
}
And these are the options I set to my dxMap:
options: {
showControls: true,
key: { google: "myGoogleApiKey" },
center: center,
width: "100%",
height: "100%",
zoom: zoom,
provider: "google",
mapType: "satellite",
autoAdjust: false,
onReady: function (s) {
LoadPoints();
var map = s.originalMap;
var markers = [];
for (var i = 0; i < MyPoints().length; i++) {
var data = MyPoints()[i];
var latLng = new google.maps.LatLng(data.location[0], data.location[1]);
var marker = createMarker(latLng, data.title, map, data.idimp);
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers, { imagePath: 'images/m' });
}
},
Where MyPoints is populated calling LoadPoints:
function LoadPoints() {
$.ajax({
type: "POST",
async:false,
contentType: "application/json",
dataType: "json",
url: myApiUrl,
success: function (Response) {
var tempArray = [];
for (var point in Response) {
var location = [Response[p]["latitudine"], Response[p]["longitudine"]];
var title = Response[p]["name"] + " - " + Response[p]["city"];
var temp = { title: title, location: location, tooltip: title, onClick: GoToNavigator, idpoint: Response[p]["id"] };
tempArray.push(temp);
}
MyPoints(tempArray);
},
error: function (Response) {
jQuery("#large-indicator").css("display", "none");
var mex = Response["responseText"];
DevExpress.ui.notify(mex, "error");
}
});
}
Note that in the folder Myproject.Mobile/images I included the images m1.png, m2.png, m3.png, m4.png and m5.png.
You can found them here.

angular-google-maps not showing infowindow on mouseover event

I am using angularjs-google-map http://angular-ui.github.io/angular-google-maps/#!/api
I can add multiple markers with showing infoWindow by cliking on a marker, but now I need to show the marker infoWindow when the mouse enters the area of the marker icon and hide it when the mouse leaves the area of the marker icon instead of using the click event.
You can look on this example on Jsfiddle https://jsfiddle.net/meher12/bgb36q7b/ to get idea about my purpose !
My HTML code:
<ui-gmap-google-map center="map.center" zoom="map.zoom" dragging="map.dragging" bounds="map.bounds"
events="map.events" options="map.options" pan="true" control="map.control">
<ui-gmap-markers models="map.randomMarkers" coords="'self'" icon="'icon'"
doCluster="map.doClusterRandomMarkers" clusterOptions="map.clusterOptions" modelsbyref="true"
events="map.markersEvents" options="'options'"
>
<ui-gmap-windows show="'showWindow'" ng-cloak>
<div>
<p>This is an info window</p>
</div>
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
</div>
My JS code:
myApp.controller('MainController', function ($scope,uiGmapGoogleMapApi) {
$scope.numOfMarkers = 25;
uiGmapGoogleMapApi.then(function(maps) { $scope.googleVersion = maps.version; });
$scope.map = {
center: {
latitude: 45,
longitude: -73
},
zoom: 10,
options: {
streetViewControl: false,
panControl: false,
maxZoom: 20,
minZoom: 3
},
dragging: false,
bounds: {},
randomMarkers: [],
doClusterRandomMarkers: true,
currentClusterType: 'standard',
clusterOptions: {
title: 'Hi I am a Cluster!', gridSize: 60, ignoreHidden: true, minimumClusterSize: 2
}
};
$scope.map.markersEvents = {
mouseover: function (marker, eventName, model, args) {
model.options.labelContent = "Position - lat: " + model.latitude + " lon: " + model.longitude;
marker.showWindow = true;
$scope.$apply();
},
mouseout: function (marker, eventName, model, args) {
model.options.labelContent = " ";
marker.showWindow = false;
$scope.$apply();
}
};
var genRandomMarkers = function (numberOfMarkers, scope) {
var markers = [];
for (var i = 0; i < numberOfMarkers; i++) {
markers.push(createRandomMarker(i, scope.map.bounds))
}
scope.map.randomMarkers = markers;
};
var createRandomMarker = function (i, bounds, idKey) {
var lat_min = bounds.southwest.latitude,
lat_range = bounds.northeast.latitude - lat_min,
lng_min = bounds.southwest.longitude,
lng_range = bounds.northeast.longitude - lng_min;
if (idKey == null)
idKey = "id";
var latitude = lat_min + (Math.random() * lat_range);
var longitude = lng_min + (Math.random() * lng_range);
var ret = {
latitude: latitude,
longitude: longitude,
title: 'm' + i,
showWindow: false,
options: {
labelContent: ' ',
labelAnchor: "22 0",
labelClass: "marker-labels",
draggable: true
}
};
ret[idKey] = i;
return ret;
};
$scope.genRandomMarkers = function (numberOfMarkers) {
genRandomMarkers(numberOfMarkers, $scope);
};
$scope.removeMarkers = function () {
$scope.map.randomMarkers = [];
};
});
Like you see on my JS code I have created markerEvents and I can get the marker label changed on mouse events but still not showing the infoWindow attached to each marker on the map when the mouse Event is fired, despite its value is changing and take the correct value.
Someone Have an idea to resolve this issue ?
Feel free to put your changes to my Jsfiddle code :)
You must set model.showWindow instead of marker.showWindow
You can set model.show = true instead of model.showWindow, in html remove show =showWindow.

AngularJS - ng-click not working in custom directive

I have created a custom directive. The controls defined in templates seem to be working fine. But, I need to append another control - image button, to a control defined in templates according to some condition. To do this I included an IF condition, created an image button and added a 'ng-click' attribute to it. However, using javascript 'append' of image button to my template control's ('html') does not seem to work as it says no 'append' is an undefined function. Hence I used 'concat()', this renders the image button but 'ng-click' does not work. The function in the controller does get hit. Please help!
<div ng-controller="pdfFormsEditController">
<split-pane id="splitPane" height="800">
<split-pane-component id="leftPane" width="50%"> <div class="form-editor boxed-section dashed" id="form">
<form-control ng-repeat="control in formDefinition.Definition.controls" control="control" />
</div></split-pane-component>
</split-pane>
</div>
This is my directive file -
"use strict";
angular.module('configurePDF.directives.noteForms', [])
.directive('formControl', ['$compile', function ($compile) {
var templates = {
"NoteLabel":'<label ng-click="onSelectNoteField(control.Name)" ng-style="control.style" style="font-style:Bold; font-size: 8.25pt; font-family:Arial">{{control.Properties.DisplayName}}</label>',
"NoteMedcinFinding":'<p ng-click="onSelectNoteField(control.Name)" ng-style="control.style"><input type="image" src="../Images/YesNo.gif" style="Width:35px; Height:17px;"><label style="font-style:Bold; font-size: 8.25pt; font-family:Arial">{{control.Properties.OriginalText}}</label></input></p>'
}
var linker = function(scope, element, attrs) {
var location = scope.control.Properties.Location.split(',');
var size=scope.control.Properties.Size.split(',');
// var font=scope.control.Properties.Font.split(',');
scope.control.style = {position: "absolute", left: (parseInt(location[0])*1.5) + "px", top: location[1] + "px" ,minWidth:425+"px",height:size[1]+"px"};
var html = templates[scope.control.Type];
debugger;
if(scope.control.Properties.DetailFormID != "00000000-0000-0000-0000-000000000000"){
var img = document.createElement('input');
img.type = "image"
img.src = "../../Images/plus.png";
img.height = 10;
img.width = 10;
img.style.position = 'absolute'
img.style.left = ((parseInt(location[0])*1.5) - 13) + "px"
img.style.top = (parseInt(location[1]) + 3)+ "px"
//img.className ="ng-scope ng-binding"
//img.onclick = "onSelectNoteField(scope.control.Properties.DetailFormID)"
var attr = document.createAttribute("data-ng-click");
attr.value = "onSelectNoteField(control.Properties.DetailFormID)";
img.attributes.setNamedItem(attr);
debugger;
html = html.concat(img.outerHTML);
//console.log(element);
}
var elem = $compile(html)(scope);
element.replaceWith(elem);
}
return {
restrict: "E",
replace: true,
link: linker,
scope: {
control:'='
}
};
}]);
UPDATE: I read that class="ng-scope ng-binding" should be created automatically in the element's html. But in my image button the class is is just "ng-scope". So, may be there is some binding issue to the scope, because I was not able to append the image button but concatenate it??
<input type="image" src="../../Images/plus.png" height="10" width="10" style="position: absolute; left: 32px; top: 83px;" data-ng-click="onSelectNoteField(control.Properties.DetailFormID)" class="ng-scope">
Controller:
/
.controller('pdfFormsEditController', ['$scope', '$routeParams', 'pdfFormsService','mastersService','$rootScope',
function pdfFormsEditController($scope, $routeParams, pdfFormsService,mastersService,$rootScope) {
var allNoteFields = [];
$scope.editMode = true;
$scope.onSelectNoteField = function(noteField) {
debugger;
$scope.formDefinition = {};
var result = pdfFormsService.getFormDefinition('3151ff0d-6c93-4c80-9182-fd05f7d6cf90');
result.success(function (formDefinition) {
console.log(formDefinition);
$scope.formDefinition = formDefinition;
var size = $scope.formDefinition.Definition.Properties.Size.split(',');
$scope.formDefinition.style = { position: 'relative', width: size[0] + "px", height: size[1] + "px" }
}
Well, I found the answer and its pretty simple! My directive had no access/link to the scope when I was calling onSelectNoteField! Hence a different approach worked.
if ((scope.control.Properties.DetailFormID != "00000000-0000-0000-0000-000000000000") && (scope.control.Properties.DetailFormID != "0") && (scope.control.Properties.DetailFormID !== undefined)) {
var img = document.createElement('input');
img.type = "image";
img.src = "../../Images/plus.png";
img.height = 10;
img.width = 10;
img.style.position = 'absolute'
img.style.left = ((parseInt(location[0]) * 1.5) - 13) + "px"
img.style.top = (parseInt(location[1]) + 3) + "px"
//img.className ="ng-scope ng-binding"
//img.onclick = "onSelectNoteField(scope.control.Properties.DetailFormID)"
var attr = document.createAttribute("data-ng-click");
attr.value = "onImageClick('" + scope.control.Properties.DetailFormID + "')";
img.attributes.setNamedItem(attr);
html = html.concat(img.outerHTML);
}
var elem1 = $compile(html)(scope);
element.replaceWith(elem1);
scope.onImageClick = function (subformID) {
var id = subformID;
scope.onImageClick = function (control) {
var scope = angular.element($("#form")).scope();
scope.onSelectNoteField(id);
}
}
I am creating a scope property- the function onImageClick and calling this in ng-click of my image. onImageClick gets the scope of my parent element, which has access to the function I want to call - onSelectNoteField!

Resources