I am new to hybrid mobile app creation. And my use case is very simple. I have a single ionic modal using template html.
What I want is populating the same ionic template with different values based on some records data. Basically it is a google map and on click on any of the markers, the same template should open with different values based on the marker.
My controller code -
.controller('MyLocationCtrl', function(
$scope,
$stateParams,
force,
$cordovaGeolocation,
$ionicModal,
GoogleMapService,
ForceService,
$q
) {
console.log('this is in my location page');
var currentPosition = GoogleMapService.getCurrentLocation();
var restaurantModal = $ionicModal.fromTemplateUrl('templates/bottom-sheet.html', {
scope: $scope,
viewType: 'bottom-sheet',
animation: 'slide-in-up'
});
var allContacts = ForceService.getAllContactsWithGeo();
var promises = [];
promises.push(currentPosition);
promises.push(allContacts);
promises.push(restaurantModal);
var allMarkers = [];
var allContactDetails = [];
currentPosition.then(
function(position) {
console.log('position data -->', position);
var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapOptions = {
center: latLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
$scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);
var bounds = new google.maps.LatLngBounds();
allContacts.then(
function(contacts) {
console.log('contacts final -->', contacts);
for (var i=0; i<contacts.records.length; i++) {
var contact = contacts.records[i];
console.log('single contact -->', contact.MailingLatitude, contact.MailingLongitude);
var contactlatLng = new google.maps.LatLng(contact.MailingLatitude, contact.MailingLongitude);
var contactInfo = {};
//contactInfo.marker = {};
var marker = new google.maps.Marker({
map: $scope.map,
animation: google.maps.Animation.DROP,
position: contactlatLng
});
contactInfo.marker = marker;
contactInfo.recordDetails = contact;
allMarkers.push(marker);
allContactDetails.push(contactInfo);
// Set boundary for markers in map
bounds.extend(contactlatLng);
}
// Fit map based on markers
$scope.map.fitBounds(bounds);
}
);
// google.maps.event.addListenerOnce($scope.map, 'idle', function(){
// });
},
function(error) {
console.log("Could not get location" + error);
}
);
// Add listener for marker pop up once all promises resolved
$q.all(promises).then(
function(values) {
console.log('first -->', values[0]);
console.log('second -->', values[1]);
console.log('third -->', values[2]);
var detailModal = values[2];
$scope.modal = detailModal;
for (var i=0; i<allContactDetails.length; i++) {
allContactDetails[i].marker.addListener('click', function() {
console.log('helllos from marker');
console.log('all contactInfo -->', allContactDetails[i].recordDetails.Name);
$scope.contactName = allContactDetails[i].recordDetails.Name;
detailModal.show();
});
}
}
);
})
Front end template code -
<script id="templates/bottom-sheet.html" type="text/ng-template">
<ion-bottom-sheet-view>
<ion-header-bar align-title="left">
<h1 class="title">New Particle</h1>
<button class="button button-icon icon ion-android-close" ng-click="modal.hide()"></button>
{{contactName}}
</ion-header-bar>
</ion-bottom-sheet-view>
</script>
Now the modal opens properly when i click on the google marker, but I am not sure how to pass dynamic data to the pop modal.
Since you are doing this :
var restaurantModal = $ionicModal.fromTemplateUrl('templates/bottom-sheet.html', {
scope: $scope,
viewType: 'bottom-sheet',
animation: 'slide-in-up'
});
Your modal can access to the scope of your controller.
So if you declare any variable in your controller it will be accessible through the modal.
Related
In my Ionic 2 application, I'm able to see my current location on the map, but how can I add the location (longtitude and latitude) to Firebase?
initMap(): Promise<any> {
this.mapInitialised = true;
return new Promise((resolve) => {
Geolocation.getCurrentPosition().then((position) => {
let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
//let latLng = new google.maps.LatLng(40.713744, -74.009056);
let mapOptions = {
center: latLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement, mapOptions);
resolve(true);
google.maps.event.addListener(this.map, 'click', (event) => {
this.clearMarkers();
let geocoder = new google.maps.Geocoder;
let infowindow = new google.maps.InfoWindow;
let distanceToYou = this.getDistanceBetweenPoints(
event.latLng,
position,
'miles'
).toFixed(2);
this.geocodeLatLng(event.latLng,geocoder,infowindow,distanceToYou);
});
});
});
}
I'm able to get the current position of me and if I double click the map I can see the distance between me and the marker.
Yes it's possible. But since double clicking a map zooms it, i'll use press. But it would be better if you set a button on a info window with a "save location" text or something like this to call the saving function.
YOUR HTML
<div #mapID (press)="saveLocation()">
YOUR .TS
import * as firebase from 'firebase';
public lat;
public long;
initMap(): Promise<any> {
this.mapInitialised = true;
return new Promise((resolve) => {
Geolocation.getCurrentPosition().then((position) => {
this.lat = position.coords.latitude;
this.long = position.coords.longitude;
// YOUR CODE CONTINUES HERE...
});
});
});
saveLocation(){
firebase.database().ref('PATH/YOU/WANT/TO/SAVE').update({
lat: this.lat,
long: this.long
}).then(res =>{
// THE LOCATION IS SAVED, DO YOUR STUFF
})
}
Like this you can save you location, use update() instead of set() so you don't subscribe other data.
If you want to retrieve that data just use firebase.database().ref('PATH/YOU'VE/SAVED').once('value', snapshot =>{ // CODE });
Hope it helps
I'm implementing google map into my ionic app, and I have a script in my index.html, which, will only allow the map works in the index.html.
But I need my map in my templates file route.html instead, so I believe I should move the script in the index.html to the specific controller.js file, but things here are written in $scope style, can anyone tell me how could I wrote the style into $scope style?
And why actually things won't works in the route.html as the same code is used?
<div id="map"></div>
Here's my script in my index.html:
<script>
function initMap() {
var uluru = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: uluru
});
var marker = new google.maps.Marker({
position: uluru,
map: map
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=APIKEY&callback=initMap">
</script>
And my controller in the controller.js
.controller('RouteCtrl', function($scope, $ionicLoading) {
$scope.mapCreated = function(map) {
$scope.map = map;
};
$scope.centerOnMe = function () {
console.log("Centering");
if (!$scope.map) {
return;
}
$scope.loading = $ionicLoading.show({
content: 'Getting current location...',
showBackdrop: false
});
navigator.geolocation.getCurrentPosition(function (pos) {
console.log('Got pos', pos);
$scope.map.setCenter(new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude));
$scope.loading.hide();
}, function (error) {
alert('Unable to get location: ' + error.message);
});
}
})
There 2 ways to solve your problem :
Change your script to angular method in controller or create a service , like:
var marker = new google.maps.Marker({
map: $scope.map,
animation: google.maps.Animation.DROP,
position: latLng
});
var infoWindow = new google.maps.InfoWindow({
content: "Here I am!"
});
google.maps.event.addListener(marker, 'click', function () {
infoWindow.open($scope.map, marker);
});
Change it to jquery in controller, but it not recommend because it will break to purpose of angular usage in ionic:
var map = new google.maps.Map($("#map"), {
zoom: 4,
center: uluru
});
im using vimeo drop uploader on my site. i got the uploder from
https://github.com/websemantics/vimeo-upload
its working well when i drop the image. but i dont know how to on click to open uploder window..
the uploder dont have the file input its only have the div
this is html
<div class="progress">
<div id="progress" class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="46" aria-valuemin="0" aria-valuemax="100" style="width: 0%">0%
</div>
</div>
<div id="drop_zone">Drop files here</div>
and they use this script
<script>
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files; // FileList object.
var accessToken = document.getElementById("accessToken").value;
var upgrade_to_1080 = document.getElementById("upgrade_to_1080").checked;
// Set Video Data
var videoName = document.getElementById("videoName").value;
var videoDescription = document.getElementById("videoDescription").value;
// Clear the results div
var node = document.getElementById('results');
while (node.hasChildNodes()) node.removeChild(node.firstChild);
// Rest the progress bar
updateProgress(0);
var uploader = new MediaUploader({
file: files[0],
token: accessToken,
upgrade_to_1080: upgrade_to_1080,
videoData: {
name: (videoName > '') ? videoName : 'Default name',
description: (videoDescription > '') ? videoDescription : 'Default description'
},
onError: function(data) {
var errorResponse = JSON.parse(data);
message = errorResponse.error;
var element = document.createElement("div");
element.setAttribute('class', "alert alert-danger");
element.appendChild(document.createTextNode(message));
document.getElementById('results1').appendChild(element);
},
onProgress: function(data) {
updateProgress(data.loaded / data.total);
},
onComplete: function(videoId) {
var url = "https://vimeo.com/"+videoId;
document.getElementById("video").value = url;
//var a = document.createElement('a');
// a.appendChild(document.createTextNode(url));
// a.setAttribute('href',url);
//
// var element = document.createElement("div");
// element.setAttribute('class', "alert alert-success");
// element.appendChild(a);
//
// document.getElementById('results').appendChild(element);
}
});
uploader.upload();
}
/**
* Dragover handler to set the drop effect.
*/
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy';
}
/**
* Wire up drag & drop listeners once page loads
*/
document.addEventListener('DOMContentLoaded', function () {
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
});
var elem = document.getElementById('drop_zone');
if(elem && document.createEvent) {
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, false);
elem.dispatchEvent(evt);
}
/**
* Updat progress bar.
*/
function updateProgress(progress) {
progress = Math.floor(progress * 100);
var element = document.getElementById('progress');
element.setAttribute('style', 'width:'+progress+'%');
element.innerHTML = progress+'%';
}
progress
</script>
Can you help me on this how to i upload an video on click..
Demo https://github.com/googledrive/cors-upload-sample
Thanks
I have list of markers that want to render in the map, but I want it one by one. In first click I want to make new marker. Then when I click to another location, I want my marker to just move to the new latLng not to create another marker. Here is my code:
function (licon, coord, data) {
var self = jQuery(this);
var map = self.data("map");
var latlng = new L.LatLng(coord[0], coord[1]);
//Create Marker
if (licon) {
var leafIcon = L.icon(licon);
console.log(typeof (marker));
if (typeof (marker) === 'undefined') {
var marker = L.marker(latlng, {
icon: leafIcon,
"markerData": data,
draggable: true
});
} else {
console.log('not undefined');
map.removeLayer(marker);
marker = L.marker(latlng, {
icon: leafIcon,
"markerData": data,
draggable: true
});
}
} else {
var marker = L.marker(latlng, {
"markerData": data,
draggable: true
});
}
marker.addTo(map);
return marker;
}
A quick example of the result: http://jsfiddle.net/ve2huzxw/43/
var currentMarker;
map.on("click", function (event) {
if (currentMarker) {
currentMarker.setLatLng(event.latlng);
return;
}
currentMarker = L.marker(event.latlng, {
draggable: true
}).addTo(map).on("click", function () {
event.originalEvent.stopPropagation();
});
});
document.getElementById("done").addEventListener("click", function () {
currentMarker = null;
});
You can also add a smooth transition to show the marker moving to the new position:
if (currentMarker) {
currentMarker._icon.style.transition = "transform 0.3s ease-out";
currentMarker._shadow.style.transition = "transform 0.3s ease-out";
currentMarker.setLatLng(event.latlng);
setTimeout(function () {
currentMarker._icon.style.transition = null;
currentMarker._shadow.style.transition = null;
}, 300);
return;
}
a slightly more consolidated solution some years later.
var currentMarker;
map2.on('click', function(e) {
if (currentMarker){
currentMarker.setLatLng(e.latlng)
} else {
currentMarker = new L.marker(e.latlng).addTo(map2);
};
//console.log('lat, lon: ', e.latlng.lat, e.latlng.lng);
});
leaflet now defaults to smoothly dragging the point over to the new coords.
I have error about for info window data. I can't get the Please help me to check my code.
function initialize() {
map = new google.maps.Map(document.getElementById(map), {
center: new google.maps.LatLng(1.352083, 103.819836),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
//var infowindow;
if (markers) {
for (var level in markers) {
for (var i = 0; i < markers[level].length; i++) {
var details = markers[level][i];
//var infowindow;
markers[level][i] = new google.maps.Marker({
title: details.name,
position: new google.maps.LatLng(
details.location[0], details.location[1]),
clickable: true,
draggable: false,
icon: details.icon
});
var infowindow = new google.maps.InfoWindow({
content: details.description,
//content : markers[level][i].description,
position: new google.maps.LatLng(details.location[0], details.location[1])
//position: markers[level][i].position
});
google.maps.event.addListener(markers[level][i], 'click', function() {
infowindow.setPosition(this.position);
alert(this.position);
//infowindow.setContent(markers[level][i].description);
infowindow.open(map,markers[level][i]);
});
}
}
}
I can't get the description data. Please help me to check my code.