Geoman event pm:create doesn't fire when adding layers programmatically - leaflet

I'm using react-leaflet with the Geoman plugin, and I notice that pm:create doesn't fire when I add new layers programmatically. This code runs on startup and again anytime the activeFeatureGroup is changed:
map.pm.setGlobalOptions({
...map.pm.getGlobalOptions(),
layerGroup: activeFeatureGroup,
hintlineStyle: { color },
templineStyle: { color },
})
This is my function to programmatically add new layers from GeoJSON:
const opts = { style: { color } }
geoJSON(newGeoJsonObject, opts).addTo(activeFeatureGroup)
How can I get pm:create to fire after this code runs? The main concern is that I'm adding event listeners to every layer that pm:create sees, so an alternative solution would be a way to set one listener on the map instance that fires anytime a layer is added in Geoman, but I don't see support for this in the Geoman docs.

How can I get pm:create to fire after this code runs?
You can achive this in 3 different ways:
Create a function and call it after running the geoJson part and in the pm:create listener
add a listener on the map layeradd (leaflet event) and run the same code as in pm:create
you can fire pm:create manually with map.fire('pm:create',{layer: XYZ}); (I don't recommand this!)
alternative solution would be a way to set one listener on the map instance that fires anytime a layer is added in Geoman
This is pm:create ... if you mean to fire an event for each layer that is intialized and is added to Geoman, you can achive this by listening on layeradd and then check if the Geoman property layer.pm exists.

Related

Prevent Leaflet .flyTo() animation stop when map clicked

The default behavior of Leaflet's map.flyTo() method is that if the user clicks on the map during the flyTo animation, the animation stops.
I would like to keep the map animating until the desired view is reached, regardless of user interaction.
Is there a way to disable the map mouse/touch interactions for the duration of the animation?
Use the methods described by #IvanSanchez within the function that fires theflyTo() method (let's call this function "triggersFlyTo()")and the 'moveend' event. I hope that the following code solves your problem:
//stop user interaction when flyTo() is fired
function triggersFlyTo() {
...
map.dragging.disable();
map.doubleClickZoom.disable();
map.scrollWheelZoom.disable();
map.flyTo(...)
...
}
//restart user interaction when the "flying" stops.
map.on('moveend', function() {
map.dragging.enable();
map.doubleClickZoom.enable();
map.scrollWheelZoom.enable();
}
Is there a way to disable the map mouse/touch interactions for the duration of the animation?
You probably want to temporarily disable the interaction handlers, like so:
map.dragging.disable();
map.doubleClickZoom.disable();
map.scrollWheelZoom.disable();
...
map.dragging.enable();
map.doubleClickZoom.enable();
map.scrollWheelZoom.enable();
Check the full list at http://leafletjs.com/reference-1.0.3.html#map-handlers , along with the rest of the documentation.

Event handling between two custom controls

I have two custom controls. Control A attaches an event handler on Control B by calling
b.attachEventName( function(event, data){ ... })
after instantiating b.
Control B reacts on a click and fires the relevant event by doing something like this:
this.fireEventName( { key: value } );
I observe that I don't have access to the object, I gave as parameter in the firing of the event in the attached function in control A. How can I get access to that object?
PS: For clarification: I want to reuse Control B, and different controls, which use B might want to attach different functions for a specific event.
Thanks,
Christian
The problem is with syntax you are using to attach event to the control.
If you want to pass an object along with the event object when firing the event, code would be:
b.attachEventName(oData, function(oEvent){
// your stuff
});
This should do:
b.attachEventName(function(event, data) {
var sKey = event.getParameter("key")
});
The second parameter data in this function is the data that you potentialy passed when registering the event listener as described above by Dopedev.
BR
Chris

Dojo DnD delete selected items

Is there a way to delete selected items from a dojo DnD Source by dragging them out their container, or by pressing DEL key? I tried to achieve this by adding a dojo.connect->onkeypress but It seems Source doesn't listen to this events.
...
In response to Rodrigo QuiƱones I've created a jsfiddle
//[...]
on(dom.byId('sortByItems'), 'keypress', function(evt) {
if (evt.charOrCode == keys.DELETE)
console.log('User wants to unselect:', sortByDnDTarget.getSelectedNodes());
});
//[...]
Thanks in advance.
First off; The dndSource does no listen to keypress events. I believe it never gains 'focus', only items contained in it can get focused. It does however listen to things like 'click' etc.
Secondly, DELETE key is not captured in the keypressed event handler, since this is designed only to capture printable stuff, so <enter>, <del> and <esc> etc. does not apply for that event.
Instead use keyup or keydown listeners - and apply them on window
The following snippet should do what youre aiming for:
sortByDnDTarget.getSelectedNodes().forEach(function(li) {
sortByDnDTarget.delItem(sortByDnDTarget.getItem(li.id));
});

polymer 1.0 event when element appears on page

I can't understand how to make css animations to an element no sooner than it appears on page, like css3 transform rotate. when I set in attached(){performRotation()} when the element appears on page it's already rotated. I couldn't find in all documentation which event I need to subscribe to in order to start animation.
You can do that with the help of NeonAnimatableBehavior and NeonAnimationRunnerBehavior, you may configure your animations in animationConfig property and then play them with playAnimation('name') function which is implemented by NeonAnimationRunnerBehavior .
Please check lifecycle callbacks and neon-animation demos.
behaviors: [
Polymer.NeonAnimatableBehavior,
Polymer.NeonAnimationRunnerBehavior
],
properties: {
animationConfig: { ... },
}
...
ready: function() {
this.playAnimation('entry');
}
I've made you a simple example using the above elements to give you a quick start.
Update
You can modify each configured animation based on given properties in one of the lifecycle callbacks, e.g. ready callback:
var entryAnimation = this.animationConfig.entry[0];
entryAnimation.transformFrom = this.doSomethingTo(this.someProperty);
Please check the updated demo.

Get properties from other class (d3)

Hey im using the d3 plugin to work with the Collapse Tree. This is my example: http://bl.ocks.org/mbostock/4339083
Now i created 2 Widgets which are in 2 different classes. One for the tree and one for a control element. Now i want to change the properties of clicked nodes with my control element widget. So I need to get the Data(Object) from the clicked node in my other class. After I need to manipulate that data using my control widget.
"Dojo on" / "Dojo connect" are just for DOM interactions right?.
I want to communicate between the javascript classes.
Here is my onclick function for clicking the nodes:
.on("click", function (d) {
toggle(d);
update(d)
})
You can create a custom event in the tree class and handle it from the other class. First, define an event handler for the onClick event on the tree node.
onClick: function(evt) {
// here comes your code
// when you're finished, fire a custom event
this.onNodeClicked(params);
},
onNodeClicked: function(params) {}
In the other class, listen for the custom event. Here I assume you create the tree widget from there. Otherwise, you can pass a reference to your tree object.
var tree = new MyTree();
dojo.on(tree, "onNodeClicked", this._handleOnNodeClicked);
Hope this helps.