ng-click in a loop is always clicked - ionic 2 - angularjs

I have a google map in my view and in this map I have many marker and each marker should have a content which contains an a href for more details
This is my code for adding one marker which is used in a loop on all the events saved in the database :
setMarker(event){
let coords = event.location.split(",");
let location = new google.maps.LatLng(coords[0],coords[1]);
let marker = new google.maps.Marker({
map: this.map,
position: location
});
let content = "<h1>" + event.name + "</h1></br><a ng-click="+this.viewEventDetails(event)+"> More Details</a>";
let infoWindow = new google.maps.InfoWindow({
content: content
});
google.maps.event.addListener(marker, 'click', () => {
infoWindow.open(this.map, marker);
});
return marker;
}
and this is my viewEventDetails function :
viewEventDetails(event){
this.navCtrl.push(EventDetailsPage, event);
}
When I load the map view it loads the viewEventDetails on all events , what should I do please ?

Could you change "</h1></br><a ng-click="+this.viewEventDetails(event)+"> More Details</a>" to "</h1></br><a ng-click=\"viewEventDetails(event)\"> More Details</a>". I think this should work.
Btw I think ng-click should also be substitude with (click) since ionic 2 does the angular2 way and therefore does not accept ng-click.

Related

How to show AngularJS ((value)) inside the Cordova.InAppBrower

i have value '$scope.value = "test"'
now i want to display this value inside the Cordova.InAppBrowser
i want to insert '{{value}}' inside the Cordova.InAppBrowser
is it possible ?
My JS Pushing code :
'var ref = cordova.InAppBrowser.open('https://wp-developer.online/', '_blank', 'location=yes');
ref.addEventListener('loadstop', function() {
ref.executeScript({ code:
'let ion = document.createElement("ion-content"); document.body.appendChild(ion); let inside = document.createElement("div"); inside.setAttribute("sb-tabbar", ""); inside.innerHTML = "{{value}}"; ion.appendChild(inside); ' });
});'
i am trying to append the ion {{value}} by js pushing
Ca you help me to clear the issue ?

Appcelerator Titanium: Using eventListener & fireEvent on Database Array on View

I'm new to titanium. I've been having some problems on this for a while now. Help would be greatly appreciated.
I have a array loop that cycles through a database to retrieve images and labels. These are all stored in a view. I am adding an event listener to the the view and then adding fire event to the listener to open the selected image in a new window with the id of that video acting as a reference point to play the selected video in the new window. Hope my code makes more sense.
The problem is that the even listener will only return the value of the last row in the database, not the info of the video image that the user clicks on
function getChannelVideos(){
// create an empty data array
var video = [];
// create the httpRequest
var xhr = Titanium.Network.createHTTPClient();
xhr.open('GET','getVideoFeed.php?chid='+channelView.channelId);
// this method will be called when the request is complete
xhr.onload = function()
{
// parse json coming from the server
var json = JSON.parse(this.responseText);
// if Channel Videos are returned
if(json.channelVideos)
{
for (var i = 0; i < json.channelVideos.length; i++){
var video = Ti.UI.createView({ // creates video view
width:'60%', // sets height
backgroundColor: 'transparent',
});
var videoThumb = Ti.UI.createImageView({ // creates thumb
image:json.channelVideos[i].vThumb,
width:'100%', // sets height
top:150 + i*200, // positions from top
backgroundColor: '#000'
});
video.add(videoThumb); // adds thumb to video view
var videoTitle = Ti.UI.createLabel({ // creates label
text:json.channelVideos[i].vTitle,
font:{
fontSize:12
},
color:'#fff',
backgroundColor:'#000',
textAlign:'center',
width:'100%',
height:20,
top:140 + i*200, // positions from top
});
video.add(videoTitle); // adds video title to video view
var videoSpeaker = Ti.UI.createLabel({ // creates Label
text:json.channelVideos[i].vSpeaker,
font:{
fontSize:12
},
color:'#fff',
backgroundColor:'#000',
textAlign:'center',
width:'100%',
height:20,
top:295 + i*200, // positions from top
});
video.add(videoSpeaker); // adds speaker name to video view
var videoPlay = Ti.UI.createImageView({
image:'/images/light_play.png',
top:215 + i*200, // positions from top
});
video.add(videoPlay); // adds playbutton to videoview
chContentAreaView.add(video); // adds video view to scrollview
var vId=json.channelVideos[i].vId;
video.vId = vId; // Here vId is custom property of video
video.addEventListener('click', function(e){
alert(e.source.vId);
Ti.App.fireEvent('videoPlay',{
videoId:e.source.vId
});
});
}
}
};
// this method will be called if there is an error
xhr.onerror = function(){
alert(this.error + ': ' + this.statusText);
return false;
};
// open the httpRequest
xhr.setRequestHeader("contentType","application/json; charset=utf-8");
xhr.send();
}
try some things:
give video.vId = json.channelVideos[i].vId directly in the property of video like :
var video = Ti.UI.createView({ // creates video view
width:'60%', // sets height
backgroundColor: 'transparent',
vId : json.channelVideos[i].vId
});
use property touchEnabled : false in other views and labels for videoThumb, videoTitle, videoSpeaker, videoPlay etc.
I think by doing this all things will work fine.

angular leaflet marker change property with function

I would like to change some leaflet marker properties by clicking a link outside the map, but it doesn't work.
Check out this fiddle:
http://jsfiddle.net/Ls59qLLa/2/
js:
var app = angular.module('demoapp',['leaflet-directive']);
app.controller('DemoController', [ '$scope', 'leafletData', function($scope, leafletData) {
var local_icons = {
defaultIcon: {},
gmapicon: {
iconUrl: 'http://maps.google.com/mapfiles/kml/shapes/capital_big.png',
iconSize: [25, 25],
iconAnchor: [12, 12],
popupAnchor: [0, 0]
}
}
angular.extend($scope, {
markers: {
m1: {
lat: 41.85,
lng: -87.65,
clickable: false,
message: "I'm a static marker",
icon: local_icons.gmapicon
}
}
});
$scope.makeIconClickable = function(){
alert('function called');
var whichmarker = 'm1';
$scope.markers[whichmarker].clickable = true;
}
}]);
HTML:
<body ng-controller="DemoController">
<leaflet markers="markers"></leaflet>
<a href="#" ng-click=makeIconClickable()>Make Icon Clickable</a>
</body>
Leaflet directive has separate $watch for every marker (and path) on the map. When you change one of the marker property, this $watch is fired and it checks if some of properties has changed. Apparently it does not look for the clickable property, but it looks for message property. So in your function you could set message of the marker and everything binds properly:
$scope.makeIconClickable = function(){
var whichmarker = 'm1';
$scope.markers[whichmarker].clickable = true;
$scope.markers[whichmarker].message = "I'm a static marker";
}
If you need to set message on marker initialization phase, you can use some temporary property:
angular.extend($scope, {
markers: {
m1: {
lat: 41.85,
lng: -87.65,
icon: local_icons.gmapicon,
tmpmessage: 'I am a static marker'
}
}
});
And then:
$scope.makeIconClickable = function(){
var whichmarker = 'm1';
$scope.markers[whichmarker].clickable = true;
$scope.markers[whichmarker].message = $scope.markers[whichmarker].tmpmessage;
}
Working example: http://jsfiddle.net/3zgL8m4u/
I had the same problem. I sometimes need the map to fire an onClick Event even if the user clicked the Marker. The answer provided by "Agnieszka ƚwiecznik" is a quick and easy workaround if all you need is no Popup to be shown. It does not solve my problem, since it only removes the Popup, but no onClick Event on the map is fired.
To solve this i found this official Thread which seems to have been opened by the OP: https://github.com/tombatossals/angular-leaflet-directive/issues/676
Here a link to a modified JSFiddle is Provided: http://jsfiddle.net/nmccready/gbd1aydL/
The user who provided this fix included the following codeblock in the "angular-leaflet-directive.js" which can be found in the jsfiddle under "external resources":
var _destroy = function(markerModels, oldMarkerModels, lMarkers, map, layers){
// Delete markers from the array
var hasLogged = false,
modelIsDiff = false;
var doCheckOldModel = isDefined(oldMarkerModels);
for (var name in lMarkers) {
if(!hasLogged) {
$log.debug(errorHeader + "[markers] destroy: ");
hasLogged = true;
}
if(doCheckOldModel){
//might want to make the option (in watch options) to disable deep checking
//ie the options to only check !== (reference check) instead of angular.equals (slow)
modelIsDiff = !angular.equals(markerModels[name],oldMarkerModels[name]);
}
if (!isDefined(markerModels) ||
!Object.keys(markerModels).length ||
!isDefined(markerModels[name]) ||
!Object.keys(markerModels[name]).length ||
modelIsDiff) {
deleteMarker(lMarkers[name], map, layers);
delete lMarkers[name];
}
}
};
Note that this seems to be an older Version, as noted in the file itself: "angular-leaflet-directive 0.7.11 2015-04-08". When included in my AngularJS Project this allowed me to change the clickable property of the marker by just modifiyng the corresponding boolean in my "$scope.markers"-equivalent.

Angular-ui ui-map click event not receiving $params

I'm trying to implement Google maps in Angularjs using ui.Map (http://angular-ui.github.io/ui-map/)
I've followed the example pretty closely and the map loads, I can create a marker in the map center and the 'map-tilesloaded' event works fine.
My problem is adding a marker where the user clicks. The click function is receiving an empty $params parameter. In my controller:
$scope.newMapOptions = {
center : new google.maps.LatLng($scope.position.lat, $scope.position.lng),
zoom : 18,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
$scope.getLocation = function() {
if (navigator.geolocation) {
return navigator.geolocation.getCurrentPosition(setPosition);
}
};
$scope.addMarker = function($event, $params) {
$scope.newTingMarker = new google.maps.Marker({
map : $scope.myNewTingMap,
position : $params[0].latLng
});
};
$scope.initMap = function() {
if (!$scope.mapLoaded)
$scope.getLocation();
$scope.mapLoaded = true;
};
function setPosition(pos) {
$scope.position = {
lat : pos.coords.latitude,
lng : pos.coords.longitude
};
$scope.meMarker = new google.maps.Marker({
map : $scope.myNewTingMap,
position : new google.maps.LatLng($scope.position.lat, $scope.position.lng)
});
$scope.myNewTingMap.setCenter(new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude));
$scope.$apply();
}
The html:
<div ui-map-info-window="myInfoWindow">
<b>Current location</b>
</div>
<div ui-map-marker="meMarker" ></div>
<div ui-map-marker="newTingMarker" ui-event="{'map-click': 'openMarkerInfo(newTingMarker)'}"></div>
<section id="newTingMap" >
<div ui-map="myNewTingMap" ui-options="newMapOptions" class="map-canvas"
ui-event="{'map-tilesloaded': 'initMap()', 'map-click': 'addMarker($event, $params)' }"></div>
</section>
$scope.addMarker should receive $event and $params where $params[0] has the latlng object. At the moment is it an empty array: []
I'm using angular 1.1.5, but I've tried using the same as the ui.Map example with no effect.
I should also note that this is in a view but putting it outside the view in the main controller makes no difference.
If I try to follow the code running from the ui-map directive I can see that the latlng object does start off in the event:
ui-map.js:
angular.forEach(eventsStr.split(' '), function (eventName) {
//Prefix all googlemap events with 'map-', so eg 'click'
//for the googlemap doesn't interfere with a normal 'click' event
google.maps.event.addListener(googleObject, eventName, function (event) {
element.triggerHandler('map-' + eventName, event);
//We create an $apply if it isn't happening. we need better support for this
//We don't want to use timeout because tons of these events fire at once,
//and we only need one $apply
if (!scope.$$phase){ scope.$apply();}
});
});
element.triggerHandler('map-' + eventName, event); ... has the latlng object in 'event' but is seems to get lost after that
Not sure what your issue is, I took your code and created a fiddle that works fine(something you should have done).
I did a console log when you click that logs the $params.
The most important thing to note is your code crashes at first because you reference $scope.position.lat before setting it. I updated it to default to RVA.
,
You do need to handle the case a little more gracefully.
function MapCtrl($scope, watchArray) {
var center;
if ($scope.position) {
center = new google.maps.LatLng($scope.position.lat, $scope.position.lng);
}
else {
center = new google.maps.LatLng(37.5410, 77.4329); //if null use rva
}
$scope.newMapOptions = {
center: center,
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
...
}
Console.log:
[Ps]
v 0: Ps
> la: Q
> latLng: O
> pixel: Q
> __proto__: Ps
length: 1
> __proto__: Array[0]

Leaflet markers from Backbone.js collection?

I am trying to build an application based on backbone.js and leaflet.
Users could drag the map and see markers on the map.
Markers can be selected by clicking on them. When selected they have to change their icon and the marker detailed information shown on a (not popup).
my backbone model consists of several entities:
Marker model contains
latitude, longitude
type,
title,
isSelected
Map model contains:
center of the map,
markers collection,
selected marker
anyone has any idea how i could make this kind of functionality?
how can i make leaflet markers as backbone views?
Backbone views and the leaflet object model are not a perfect fit, because the markers aren't contained within a DOM element, which is what Backbone.View.el is supposed to represent. Markers do of course have an element (accessible via marker._icon), but it doesn't exist until the marker is rendered to the map.
That said, you can represent the markers with Backbone views, you just can't use the events or any el related functionality. I've implemented similar views successfully using OpenLayers, which has the same "problem", and it works fine.
I think this is easiest to explain with code:
//MarkerView has no element
App.Views.MarkerView = Backbone.View.extend({
initialize: function(options) {
//pass map instance to the marker
this.map = options.map;
//create the marker object
this.marker = L.marker([this.model.get('longitude'), this.model.get('latitude')]);
},
render: function() {
//append marker to the map
this.marker.addTo(this.map);
//can't use events hash, because the events are bound
//to the marker, not the element. It would be possible
//to set the view's element to this.marker._icon after
//adding it to the map, but it's a bit hacky.
this.marker.on('click', this.onClick);
},
onClick: function() {
alert("click");
}
});
//MapView renders a map to the #map element
App.Views.MapView = Backbone.View.extend({
id:"#map",
render: function() {
//render map element
var map = this.map = L.map(this.$el.attr('id'))
.setView([this.model.get('centerLon'), this.model.get('centerLat') ], 13)
.addLayer(L.tileLayer(this.model.get('layerUrl'), { maxZoom: 18 }));
//render each marker
this.markerViews = this.model.get('markers').map(function(marker) {
return new App.Views.MarkerView({model:marker, map:map}).render();
});
}
});
Here's a demo on JSFiddle.

Resources