Hi Paul,
I am trying to use clickable elements in popups, but without success.
For example imagine the following:
<Marker position={position}>
<Popup>
<button onClick={this.bus}>thorsten</button>
</Popup>
</Marker>
Now if you click on the button there is nothing happening (at least there should be a complain about "bus" not defined. On a side note I tried as well with "onclick" and as well with onClick="this.bus()"
Now when I patch the marker like:
--- a/src/Marker.js
+++ b/src/Marker.js
@@ -16,6 +16,9 @@ module.exports = React.createClass({
componentWillMount() {
var {map, position, ...props} = this.props;
- this._leafletElement = Leaflet.marker(position, props);
+ var marker = Leaflet.marker(position, props);
+ if (this.props.onClick) {
+ marker.on('click', this.props.onClick);
+ }
+ this._leafletElement = marker;
},
And do
<Marker position={position} onClick={this.bus}"/>
Then it is working as expected but I have no popup.
To bring back the popup and not having React.renderToStaticMarkup (which is in the Popup.js) remove all onClicks or logic I use, I came up with the following:
--- a/src/Marker.js
+++ b/src/Marker.js
@@ -16,6 +16,9 @@ module.exports = React.createClass({
componentWillMount() {
var {map, position, ...props} = this.props;
- this._leafletElement = Leaflet.marker(position, props);
+ var marker = Leaflet.marker(position, props);
+ if (this.props.onClick) {
+ marker.on('click', this.props.onClick);
+ }
+ this._leafletElement = marker;
+ var popup = this.props.popup;
+ if (popup) {
+ var LPopup = Leaflet.popup().setContent(popup);
+ marker.bindPopup(LPopup);
+ }
+ this._leafletElement = marker;
},
and in my calling code I have:
function bus(){
console.log("ssssssssserererererssss")
}
Leaflet.thorsten={};
Leaflet.thorsten.bus = bus;
...
var xxx = '<div><h2>bus</h2><button onclick="L.thorsten.bus()">thorsten</button></div>';
<Marker position={position} popup={xxx}"/>
This finally works, but it really feels like a workaround more then the way to go.
Do you know a better way?
Hi,
I use React.renderToStaticMarkup() because Leaflet sets the content of the Popup by manipulating the DOM itself (https://github.com/Leaflet/Leaflet/blob/master/src/layer/Popup.js#L172), so at this point it is not possible to use React elements.
Instead of having to patch react-leaflet, I think another way you could do it is to instantiate a Leaflet Popup and attach it to the Marker in your application instead of using the <Popup> element, this way you would have full control over it.
The best solution may be to render an empty element with a specific ID as the content of the Popup so that Leaflet inserts it in the DOM, and then call React.render() on this element, but I've never tried this so I have no idea how it would behave. I'll try this when I can find some time.
Thanks Paul, I will now look into your suggestion and let you know.
Hi Pau, I came up with a Mixin which is capable of what you describe in the earlier comment, you may want to check the pull request.
Hi,
Great if that works for you.
I think this kind of code should be in the application, not the library as it introduces specific handlers, that goes against the purpose of this library to simply wrap Leaflet in React components.
ok, I understand
Hm. I must admit that I have not understood how @scherler achieved this.
I have the same need.
And I can imagine many people would like to make interactive popups.
Is there some example of how to do this?
+1 for this feature
+1
@barbalex @prabuvenkat @RoryShively you can find the PR https://github.com/PaulLeCam/react-leaflet/pull/13
I have to admit that I did not looked at this since back then and I guess that would be better implemented as ComposedComponent
Im trying yo add a D3 graph into the pop up. Is this possible ?
@ayanez17 should work, since the popup is a DOM element:
var svg = d3.select(".leaflet-popup-content").append("svg")
Most helpful comment
Hm. I must admit that I have not understood how @scherler achieved this.
I have the same need.
And I can imagine many people would like to make interactive popups.
Is there some example of how to do this?