I have written following code.. which fires Add Listener event on Place_change but i want to fire that event on page load.. which is copied from google and i have made some changes.
function _initMap(latlng){
// google map
$map = $(".lwizard-step1-map");
_latlng = latlng || new google.maps.LatLng(41.3833333,2.1833333);
if (!_STEP1_LOCATION_MAP) {
_STEP1_LOCATION_MAP = new google.maps.Map($map[0],{
center: _latlng,
zoom:11,
mapTypeId:google.maps.MapTypeId.ROADMAP,
streetViewControl:false,
scrollwheel:false
});
} else {
_STEP1_LOCATION_MAP.setCenter(_latlng);
}
if (!_STEP1_LOCATION_MARKER) {
_STEP1_LOCATION_MARKER = new google.maps.Marker({
position: _latlng,
map: _STEP1_LOCATION_MAP,
draggable: true
});
google.maps.event.addListener(_STEP1_LOCATION_MARKER, "dragend", function(event) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
$("#lwizard-step1-location-autocomplete").val('');
STEP1_PLACE.latLng = [lat,lng];
STEP1_PLACE.address = null;
$.ajax({
url: 'http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+lng+'&sensor=false',
success: function(response){
if ((response) && (response.results) && (response.results.length)){
$(".lwizard-step1-chosen-address").parent().show();
var $address = $(".lwizard-step1-chosen-address");
$address.text(response.results[0].formatted_address);
$("#lwizard-step1-adjust-onmap").data("location", response.results[0].geometry.location);
STEP1_PLACE.address = nc.utils.convertGoogleAddressComponents(response.results[0].address_components);
}
}
})
});
} else {
_STEP1_LOCATION_MARKER.setPosition(_latlng);
}
}
// autocomplete
$input = $("#lwizard-step1-location-autocomplete");
_STEP1_LOCATION_GA = new google.maps.places.Autocomplete($input[0],{ types: [] });
google.maps.event.addListener(_STEP1_LOCATION_GA, 'place_changed', function () {
var place = _STEP1_LOCATION_GA.getPlace();
console.log(place)
var $where = $(".lwizard-step1-chosen-address");
var found = ((place) && (place.formatted_address) && (place.geometry) && (place.id));
if (place && found) {
$("#lwizard-step1-adjust-onmap").data("location", place.geometry.location);
STEP1_PLACE.address = nc.utils.convertGoogleAddressComponents(place.address_components);
STEP1_PLACE.latLng = [place.geometry.location.lat(),place.geometry.location.lng()];
STEP1_PLACE.location = place.geometry.location;
$where.parent().show();
$where.text(place.formatted_address);
$("#lwizard-step1-right-1").show();
$("#lwizard-step1-right-2").hide();
_initMap(place.geometry.location);
} else {
$where.parent().hide();
$("#lwizard-step1-right-1").show();
$("#lwizard-step1-right-2").hide();
_initMap();
}
});
I have one textbox named lwizard-step1-location-autocomplete which shows value from session named SessionLocation on page load.
but i also want to show the map on page load of the location specified in textbox.
But the problem is the addlistener fires only on textbox change means Place_changed event.
pls. Give some suggestions or new method for it.
You can just call change event on load and than it will fired.
$('#lwizard-step1-location-autocomplete').trigger("change");
Or with js;
document.getElementById('lwizard-step1-location-autocomplete').fireEvent("onchange");
Related
I'm currently working on a map that's meant to load multiple layers from different sources based on a config.json file.
Each layer should also display a popup on click but for some reason I only get the popup for the last loaded layer.
I'm using the ready event on the layers to make sure all the data gets loaded and iterating through them using .eachLayer method before binding the popup but still no success and can't figure out what am I missing.
Please find below my code as well a reproduction on: plnkr.co
var myMap = function(options) {
var self = this;
this.settings = $.extend({
layersConfig: 'config.json',
layerData: 'layer',
accessToken: 'pk.eyJ1IjoibWF0dGJsaXNzIiwiYSI6ImNpb3dwczBwZjAwOTh3OWtqOWZ1aG5ob3gifQ.Ot6GdtKew9u27TROm_4A6Q'
}, options);
this.map;
this.layers;
$.ajax({
url: this.settings.layersConfig,
cache: true
}).done(function(data) {
self.init(data);
});
};
myMap.prototype = {
init: function(data) {
var self = this,
settings = this.settings;
L.mapbox.accessToken = settings.accessToken;
var map = this.map = L.mapbox.map('map', 'mapbox.streets')
.setView([54.6, -2.3], 4);
var popup = new L.Popup({
minWidth: 250
});
for (var i = 0; i < data.length; i++) {
var featureLayers = this.layers = L.mapbox.featureLayer(null, {
style: {
weight: 2,
color: data[i].color,
fillColor: data[i].color,
fillOpacity: 0.4
}
}).addTo(map);
// load layers data
featureLayers.loadURL(settings.layerData + data[i].layerId + '.json')
.on('ready', function(e) {
featureLayers.eachLayer(function(layer) {
// cache layer properties
var layerProps = layer.feature.properties;
// cache feature bounds
var bounds = layer.getBounds().toBBoxString();
// bind modal
layer.bindPopup(showPopup(layer, bounds));
});
});
}
map.on('popupopen', function() {
$('.zoom-to').on('click', function() {
var array = $(this).data('zoom').split(',');
map.fitBounds([
[array[1], array[0]],
[array[3], array[2]]
])
});
});
function showPopup(popup, bounds) {
var popupData = popup.feature.properties;
var popupLabel = popupData.NAME;
var popupStructure = '<div class="leaflet-popup-label">' + popupLabel + '</div><button class="zoom-to" data-zoom="' + bounds + '">Zoom to</button></div>'
return popupStructure;
}
}
}
var map = new myMap();
.on('ready',...)
^ Has nothing to do with an AJAX call.
You need to perform actions after the ajax call is finished, that is, inside the AJAX callback.
Here:
}).done(function(data) {
/* do stuff */
});
Found the issue.
Just replace featureLayers.eachLayer with e.target.eachLayer and the popup will show as desired.
I have used Bing Maps AJAX Control, Version 7.0. and shows the Pins on map. the requirement is like, user can drag and drop the pin and when pin gets drop, it should move to its actual location.
now the issue is, when pin's dragend event called, pin successfully set to its original location, but the mouse is not released and when mouse move, map also gets moved.
code is as below :
var isPinDragged = false;
Microsoft.Maps.Events.addHandler(pin, 'dragstart', startDragDetails);
Microsoft.Maps.Events.addHandler(pin, 'drag', dragDetails);
Microsoft.Maps.Events.addHandler(pin, 'dragend', endDragDetails);
function startDragDetails(e) {
lastLocation = e.entity.getLocation();
currentLatitude = e.entity._location.latitude;
currentLongitude = e.entity._location.longitude;
isPinDragged = false;
$(e.entity.cm1002_er_etr.dom).find("img").removeClass("droppable");
}
dragDetails = function (e) {
isPinDragged = true;
};
endDragDetails = function (e) {
if (isPinDragged) {
isPinDragged = false;
$(e.entity.cm1002_er_etr.dom).find("img").addClass("droppable");
e.entity.setLocation(new Microsoft.Maps.Location(currentLatitude, currentLongitude)); //update pin: move back to old position
}
};
Update:
I don't know, this info. how much helps to resolve. My pin creation is dynamic, there would be N no. of pins as per user logged in.
Microsoft.Maps.loadModule('Microsoft.Maps.Overlays.Style',
{
callback: function () {
map = new Microsoft.Maps.Map(document.getElementById("divDailyCashMap"), mapOptions);
var center = map.getCenter();
var loc = null;
var pin = null;
var pinLayers = new Microsoft.Maps.EntityCollection();
map.entities.push(pinLayers);
var infoboxLayers = new Microsoft.Maps.EntityCollection();
map.entities.push(infoboxLayers);
pinInfobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false });
infoboxLayers.push(pinInfobox);
$.each(codes, function (index, item) {
loc = new Microsoft.Maps.Location(item.Latitude, item.Longitude);
pin = new Microsoft.Maps.Pushpin(loc, { text: '', draggable: true });
pin.Title = item.Title;
pin.Description = item.CodeDescription;
Microsoft.Maps.Events.addHandler(pin, 'click', displayInfobox);
Microsoft.Maps.Events.addHandler(pin, 'dragstart', startDragDetails);
Microsoft.Maps.Events.addHandler(pin, 'drag', dragDetails);
Microsoft.Maps.Events.addHandler(pin, 'dragend', endDragDetails);
Microsoft.Maps.Events.addHandler(map, 'viewchange', hideInfobox);
Microsoft.Maps.Events.addHandler(map, 'mousemove', mousemoveDetails);
pinLayers.push(pin);
$(pin.cm1002_er_etr.dom).find('img').addClass("droppable").attr({ "data-pinid": item.Code, "data-lat": item.Latitude, "data-long": item.Longitude });
});
}
}
In your dragDetail() function, try:
e.handled = true;
It will tell the event engine that other underlying events should not be fired.
You can also try to add this if it does not work:
return false;
I'm creating a tool which displays nearby points of interests on a map. When a marker is clicked the map should display a list of WikiPedia articles relating to that landmark.
I'm wondering if anyone can point me in the right direction as far as getting ko.observables working with my API return. I would like to avoid appending everything to the page like I am right now, I also believe it's causing some issues with my info windows not closing properly when another marker is clicked.
Some of the things I've tried was changing the $wikiData.append to an observable and then changing the contentString variable to include the data-bindings, but alas it did not work out.
The API I'm using is the WikiPedia API. Here is the code:
function mapPin(name, lat, long, text) {
this.name = ko.observable(name);
this.lat = ko.observable(lat);
this.long = ko.observable(long);
this.text = ko.observable(text);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, long),
map: mapView,
animation: google.maps.Animation.DROP
});
function toggleBounce() {
if (marker.getAnimation() != null) {
marker.setAnimation(null);
} else {
marker.setAnimation(google.maps.Animation.BOUNCE);
}
}
function article(content, url) {
var self = this;
self.content = content;
self.url = url;
}
function apiData() {
var wikipediaURL = 'http://en.wikipedia.org/w/api.php?action=opensearch&search=' + name + '&format=json&callback=wikiCallback';
var wikiRequestTimeout = setTimeout(function () {
$wikiData.text ("Failed to get Wikipedia resources");
}, 5000);
$.ajax({
url: wikipediaURL,
dataType: "jsonp",
success: function (response) {
viewModel.articleList.removeAll();
var articleList = response[1];
for (var i = 0; i < articleList.length; i++) {
articleStr = articleList[i];
var url = 'http://en.wikipedia.org/wiki/' + articleStr;
viewModel.articleList.push(new article(articleStr, url));
}
clearTimeout(wikiRequestTimeout);
}
});
}
var contentString = '<!-- ko foreach: articleList --><li><a data-bind="attr: {href: url}, text: content"></a></li>';
var infowindow = new google.maps.InfoWindow({});
google.maps.event.addListener(mapView, 'click', function () {
infowindow.close();
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.close();
toggleBounce();
infowindow = new google.maps.InfoWindow({
content: text + contentString
});
infowindow.open(mapView, marker);
apiData();
});
}
var mapView = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 12,
center: new google.maps.LatLng(61.196148, -149.885577),
});
var viewModel = {
articleList: ko.observableArray([]),
pins: ko.observableArray([
new mapPin("Alaska Communications", 61.196148, -149.885577, "test11"),
new mapPin("Moose's Tooth", 61.190491, -149.868937, "test2")
]),
// TODO
query: ko.observable(''),
search: function (value) {
viewModel.pins[0].removeAll();
for (var i in pins) {
if (pins[i].name.toLowerCase().indexOf(valkue.toLowerCase()) >= 0) {
this.pins.push(pins[i])
}
}
}
};
// Initiates the viewModel bindings.
ko.applyBindings(viewModel);
You can find a working version of the site here:
http://jamesiv.es/projects/map
Your articleList should be an observableArray in your view model with a binding in the view for that.
var viewModel = {
articleList: ko.observableArray([]),
pins: ko.observableArray([
new mapPin("Alaska Communications", 61.196148, -149.885577, "test11"),
new mapPin("Moose's Tooth", 61.190491, -149.868937, "test2")
]),
};
First make a little DTO:
function article(content, url) {
var self = this;
self.content = content;
self.url = url;
}
When you get the data back from our ajax call, first clear the array:
viewModel.articleList.removeAll();
Then just loop through and do something like this:
viewModel.articleList.push(new article(articleStr, url));
Do the formatting in your view with a binding like this:
<!-- ko foreach: articleList -->
<li><a data-bind="attr: {href: url}, text: content"></a></li>
<!-- /ko -->
I have a map on my index page. I want to click on the map and place a marker on the position. The click event has a function where i want to open up a modal (jquery dialog box) and load a form from another child html page with the position now filled in the right form-field.
My problem is passing the value (the marker position) to the input field in the form. My function seems to work if i put the input field somewhere on the index page but not in the child template in the dialogbox.
I'm trying with this $('#test_input').val(lng + ',' + lat); But it only show the value for millisecond then disappears. Do you have any ideas why this isn't working? Or how to reconstruct this? Thanks!
function onMapClick(e) {
var lat = e.latlng.lat;
var lng = e.latlng.lng;
if (typeof marker != 'undefined') {
map.removeLayer(marker);
marker = L.marker([lat, lng], {icon: redMarker}).addTo(map);
}
else {
marker = L.marker([lat, lng], {icon: redMarker}).addTo(map);
}
$('#upload-modal').load('upload/ #myform');
$('#test_input').val(lng + ',' + lat); //This is what I'm trying<----------
$('#upload-modal').dialog({
height: 550,
width: 500,
modal: false,
buttons: {
Upload: function() {
var dialog = $(this),
form = $('#myform'),
data = form.serialize();
$('.off').remove();
$.ajax({
url: 'upload/',
data: data,
type: 'post',
success: function(response) {
res = $.parseJSON(response);
if (res['status'] == 'OK') {
alert('Thank you! Form has been submitted');
dialog.dialog('close');
}
else if (res['status'] == 'bad') {
delete res['status']
var errors = res;
$.each(errors, function(key, value) {
var err = $('<span></span>', {
'class': 'off',
'text': value
}),
br = $('<br></br>', {
'class': 'off',
}),
input = $('#id_'+key).parent();
br.appendTo(input);
err.appendTo(input);
err.css('color', 'red').css('font-size', '10px');
});
}
}
});
}
}
});
}
It seems #test_input is in your form so you have to wait until the other form is completely loaded, use a callback like this:
$('#upload-modal').load('upload/ #myform', function(){
$('#test_input').val(lng + ',' + lat);
});
I'm trying to create a mash Up of sorts... I want the functions to be in one file but when I add my Ajax functions (half way down ) nothing displays.
Also I want to display them with jQuery, and the top function(Google maps with marker and info) all works a treat until I add the bottom functions.
Should I add them in the (function () {} ) like Google has and what is the (); on the end of the googlemap function?
and when I call my functions in my code how will I call the ajax for the preview as the window.onload has been called in the Google one.
I know that I can use the $.ready function(){} but do I just put the function names in the .ready function { }
I am unsure how to add all the functions in one file and make them work. Basically
this is the code:
(function() {
//define global variables
var map, geocoder, marker, infowindow;
window.onload = function() {
//creating the map
var options = {
zoom: 5,
center: new google.maps.LatLng(53.383, -1.483),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'), options);
//code for catching the form submit event goes here
//Getting the reference to the HTML form
var form = document.getElementById('addressForm');
//Catching the forms submit event
form.onsubmit = function () {
//getting the address from the text input
var address = document.getElementById('address').value;
//Making the geocode call
getAddress(address);
//Preventing the form from doing a page submit
return false;
}
}
//Function Stub
function getAddress(address) {
//Check to see if we already have a geocode object.
//If not we create one
if(!geocoder) {
geocoder = new google.maps.Geocoder();
}
//Creating the geoCoderRequest Object
var geocoderRequest = {
address: address
}
//Making the geocode request
geocoder.geocode(geocoderRequest, function (results, status) {
//Check if status is ok beofre proceeding
if (status == google.maps.GeocoderStatus.OK){
//Center the map on the returned location
map.setCenter(results[0].geometry.location);
//Check to see if already a Marker there
if (!marker){
//Create a new marker and add it to the map
marker = new google.maps.Marker({
map: map
});
}
//Setting position of the Marker to returned location
marker.setPosition(results[0].geometry.location);
//Check to see if we've already an info window
if(!infowindow) {
//Creating a new info window
infowindow = new google.maps.InfoWindow();
}
//Creating the content of the info window to the Address
//and the returned position
var content = '<strong>' + results[0].formatted_address + '</strong><br />';
content += 'Lat: ' + results[0].geometry.location.lat() + '<br />';
content += 'Lng: ' + results[0].geometry.location.lng();
//Adding the content to the info window
infowindow.setContent(content);
//Opening the infoWindow
infowindow.open(map, marker);
}
});
}
})();
// beginning of new function
var xhr = false;
var xPos, yPos;
function prev(){
var link = document.getElementByTagName("a").onmouseover = showPreview;
}
function showPreview(evt) {
if (evt) {
var url = evt.target;
}
else{
evt = window.event;
var url = evt.srcElement;
}
xPos = evt.clientX;
yPos = evt.clientY;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else {
if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) { }
}
}
if (xhr) {
xhr.onreadystatechange = showContents;
xhr.open("GET", url, true);
xhr.send(null);
}
else {
alert("Sorry, but I couldn't create an XMLHttpRequest");
}
return false;
}
function showContents() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var outMsg = xhr.responseText;
}
else {
var outMsg = "There was a problem with the request " + xhr.status;
}
var preview = document.getElementById('preview');
preview.innerHTML = outMsg;
preview.style.top = parseInt(yPos)+2 + "px";
preview.style.left = parseInt(xPos)+2 + "px";
preview.style.visibility = "visible";
preview.onmouseout = function(){
document.getElementById('preview').style.visibility = "hidden";
}
}
It depends on why you're adding functions. but here is a simple formula. If you want you're functions to be called on document ready only and want them to be called once when the document is loaded. Then you add them as "anonymous functions"
EXAMPLE:
$(function () {
//you code
...............
// you can call your named functions also here.
//like
somefunction();
});
But if you expect them to be called later on as well, when the document has already been loaded. Then add the "named functions"
EXAMPLE:
function somename()
{
............
}
In both cases you can have them in one file and regarding the (); at the end of the function, it is a way of calling anonymous functions immediately in JavaScript, like document.ready in jQuery.