I am trying to update the contents of my popups in leaflet. First, I create markers and bind popups to them:
$.ajax({
type: "GET",
url: "/?p=map&json=1"+filter,
dataType: 'json',
success: function (response) {
geojson = L.geoJson(response, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng);
},
onEachFeature: onEachFeature
});
markers.addLayer(geojson);
map.addLayer(markers);
});
}
});
var layers = [];
function onEachFeature(feature, layer) {
feature.layer = layer;
layer.origID = feature.properties.id;
if (feature.properties && feature.properties.project_name) {
var divNode = document.createElement('DIV');
divNode.innerHTML = 'initial popup content from database <button onclick="makeAjaxCall('+feature.properties.id+')">more</button>';
layer.bindPopup(divNode);
}
layers.push(layer);
}
Initially, there's a button inside the popup, thats triggers an ajax call for updated popup content.
That ajax call returns and calls setPopupContent():
function setPopupContent(id,data){
for(var i=0;i<layers.length;i++){
if(layers[i].origID == id){
console.log(layers[i]);
var p = layers[i].getPopup();
p.setContent(data);
p.update();
}
}
}
Everything works as expected but the popup's size is not updating to its new content. It remains at 301px. Shouldn't p.update() also update the popup size?
Or is there a better way to handle popup content updates that are triggered from within that popup?
Here's an example: http://plnkr.co/edit/LUyOWqkSVazhiadEix2q?p=preview (thx iH8!)
Thanks for help!
Your popup width is being constrained by the maxWidth option of L.Popup which defaults to 300px:
http://leafletjs.com/reference.html#popup-maxwidth
This can easily be set when binding/initializing the popup like this:
L.Marker([0, 0]).bindPopup('Lorem', {maxWidth: 600}).addTo(map);
A fork of your fork on Plunker: http://plnkr.co/edit/nfxhuUV40dfRV21YKFpu?p=preview
Related
I've encountered a strange issue while trying to run scripts within my .cshtml file. I am trying to run a script that sets an icon depending on how the user clicks on it, and other which uses the Leaflet Javascript library to display a map.
My issue is that only the last script to be listed in the section works (aka if I put star.js after mapdisplay.js, star.js would work and mapdisplay.js would not, and vice-versa).
I am running this on .NET 5.0
Index.cshtml - #section scripts
#section scripts {
<script type="text/javascript" src="~/scripts/star.js"></script>
<script>
var lat = '#Model.Latitude';
var long = '#Model.Longitude';
</script>
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin="">
</script>
<script type="text/javascript" src="~/scripts/mapdisplay.js"></script>
}
And just in case, here's both scripts.
star.js
window.onload = function () {
//Adds click event handler to make an AJAX request to star when the star is clicked
$(".clickable").click(function () {
let star = $(this);
//Might be undefined if user deletes the attribute
if (star.attr("reportId") != undefined) {
let id = parseInt(star.attr("reportId"));
//NaN might happen if user changes reportId attribute to something which isn't a number
if (!isNaN(id)) {
let dataToSend = {
reportId: id
}
//Sends ajax request
$.ajax({
type: 'POST',
url: '/Home/Star',
data: dataToSend,
dataType: "json",
success: function (response) {
if (response) {
//If StarReport finished successfully, update the UI
if (star.hasClass("starred")) {
star.removeClass("starred").addClass("unstarred");
} else {
star.removeClass("unstarred").addClass("starred");
}
}
}
});
} else {
alert("Don't mess with the code!");
}
} else {
alert("Don't mess with the code!");
}
});
}
mapdisplay.js
window.onload = function () {
//Creates map bounds
let topLeftCorner = L.latLng(35.11111111115, 14.111111111);
let bottomRightCorner = L.latLng(35.1123231312, 14.67243783646247);
let bounds = L.latLngBounds(topLeftCorner, bottomRightCorner);
let map = L.map("map", {
center: L.latLng(lat, long),
zoom: 14,
zoomControl: false,
dragging: false,
keyboard: false,
maxBoundsViscosity: 1.0
});
map.setMinZoom(18);
L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
).addTo(map);
marker = L.marker([lat, long], { draggable: false }).addTo(map);
}
Any help would be appreciated, as this is driving me nuts.
For closure's sake I'll respond to my own question. As user:charlietfl pointed out in comments, window.onload can only be assigned to one function.
I personally simply solved this by using window.addEventListener('load', function () { in the .js files instead of window.onload, which works in my context.
I am using leaflet to show my geometry locations on the map. Now I have the popups working fine but when you hover over them, the location of the popup is in the middle of the line/string for example and not on the location of the mouse. Is it possible to change it to the location of the mouse so the map doesn't just suddenly move to a different location?
The code that I am using to open the popups in leaflet is as follows:
function addPopup(feature, layer) {
var popupContent = feature.properties.name;
layer.bindPopup(popupContent);
layer.on('mouseover', function (e) {
this.openPopup();
});
layer.on('mouseout', function (e) {
this.closePopup();
});
}
After #Falke Design pointed out that you could give the latlng coordinates to the openPopup function I made a cleaner version of the code:
function addPopup(feature, layer) {
var popupContent = feature.properties.name;
layer.bindPopup(popupContent);
layer.on('mouseover', function (e) {
this.openPopup(e.latlng);
});
layer.on('mouseout', function (e) {
this.closePopup();
});
}
You can convert the mousepoint to latlng and set the popup there.
layer.on('mouseover', function (e) {
var p = L.point([e.originalEvent.clientX,e.originalEvent.clientY])
var latlng = mymap.containerPointToLatLng(p);
this.openPopup(latlng)
});
layer.on('mousemove', function(e){
var p = L.point([e.originalEvent.clientX,e.originalEvent.clientY])
var latlng = mymap.containerPointToLatLng(p);
this.openPopup(latlng)
})
layer.on('mouseout', function (e) {
As displayed above i created some tiles in UI5 and now i want to perform different operations based on each tiles clicked?
So i used events in my view.js like (onPressTileOne, onPressTileTwo) while clicking on tiles i am printing alert message in controller but if so many tiles are there then what should i do i don't want to write event for each tile
please tell me how to check which tiles is clicked?
Here is my controller code--
sap.ui.controller("view.Main", {
handleEditPress : function (evt) {
var oTileContainer = this.getView().byId("container");
var newValue = ! oTileContainer.getEditable();
oTileContainer.setEditable(newValue);
evt.getSource().setText(newValue ? "Done" : "Edit");
},
handleTileDelete : function (evt) {
var tile = evt.getParameter("tile");
evt.getSource().removeTile(tile);
},
onPressTileOne : function (evt) {
alert("Tiles1 Pressed...");
},
onPressTileTwo : function (evt) {
alert("Tiles2 Pressed...");
} ,
onPressTileThree : function (evt) {
alert("Tiles3 Pressed...");
}
});
I'm trying to filter my markers based on a user text input but am unsure of how to get it to work. I'm using javascript and leaflet.js. This is the example of the code with a hardcoded filter, but i want to be able to filter the data based on a user input.
var stops = L.geoJson(points, {
onEachFeature: function (feature, layer) //functionality on click on feature
{
layer.bindPopup(String('Stop Name:' + ' ' + feature.properties.Stop_Name + '</br>' + 'Route:' + ' ' + feature.properties.Route));
layer.on('mouseover', function (e) {
this.openPopup();
});
layer.on('mouseout', function (e) {
this.closePopup();
});
}
, filter: function(feature, layer) {
return feature.properties.Route == '10';
}});
is there a way of setting
filter:function(feature, layer){ return feature.properties.Route == 'USER INPUT';}
i already have a search box on my page but not sure how to parse the result into the filter.
You could add a new geojson using the user input as the filter, using an event listener or on ('click') or .submit, something to grab the input and put it into a variable, then call a function that adds the new geojson.
Something like:
function onSubmit() {
var results = L.geoJson(null, {
filter: function(feature, layer) {
return feature.properties.zonecode == userinput;
}
}).addTo(map);
results.addData(stops.toGeoJSON());
}
You would have to remove the old results and add new ones, but this should get you started.
Using the NetChart of zoomcharts (1.5.1), it seems that addData() only works for navigation = showall. In case I try using navigation = manual, it requires initialNodes.
Is there a way initialNodes automatically gets populated with existing data (that was added incrementally)? The reason I want that is because, I want to intially load a specific set of nodes/links using navigation = showall and then change it to navigation = manual so that user can click to see all neighbors
Basically, the following example shows this case... node 'f-1' is getting overwritten by initialNodes of 'm-1'.
<script>
var t = new NetChart({
container: document.getElementById("demo"),
area: { height: 350 }
});
t.addData({nodes: [{loaded: true,id: "f-1",name: "Anna"},{id: "m-1",name: "Joe"}],links: [{to: "f-1",from: "m-1",id: "l01",type: "friend"}]});
t.updateSettings({
data:
{
preloadNodeLinks:true,
dataFunction: function(nodeList, success, error){
//return just the first node, net chart will ask for more
jQuery.ajax({
url:"/dvsl/data/net-chart/friend-net/"+nodeList[0]+".json",
success: success,
error: error});
}
},
navigation:{
initialNodes:["m-1"],
mode:"manual"
}
});
</script>
Found a workaround by use of doubleclick:
<script>
var t = new NetChart({
container: document.getElementById("demo"),
area: {
height: 350
},
events:{
onDoubleClick: dclickEvent
}
});
t.addData({nodes: [{loaded: true,id: "f-1",name: "Anna"},{id: "m-1",name: "Joe"}],links: [{to: "f-1",from: "m-1",id: "l01",type: "friend"}]});
function dclickEvent(event){
if (!$("#click")[0].checked) return;
console.log('event.clickNode', event.clickNode);
if (event.clickNode) {
jQuery.ajax({
url: "/dvsl/data/net-chart/friend-net/" + event.clickNode.id + ".json",
success: function(data) {
console.log('test-foo-data', data);
t.addData(data);
}
})
}
}
</script>