Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a button in infowindow with google-maps-react?

Tags:

reactjs

I want to integrate a button in my infowindow. It appears and I can click it but it doesn't trigger the onClick.

This is details text for post, i dont think i can more explain this.This is details text for post, i dont think i can more explain this.This is details text for post, i dont think i can more explain this.

My code:

export class MapPage extends Component {
  state = {
    activeMarker: {},
    selectedPlace: {},
    selectedText: {},
    selectedId: {},
    showingInfoWindow: false
  };

  send = () => {

      console.log('fzf');

}    

  onMarkerClick = (props, marker) => {
    this.setState({
      activeMarker: marker,
      selectedPlace: props,
      selectedText: props,
      selectedId: props,
      showingInfoWindow: true
    });  
  };

  onInfoWindowClose = () =>
    this.setState({
      activeMarker: null,
      showingInfoWindow: false
    });

  onMapClicked = () => {
    if (this.state.showingInfoWindow)
      this.setState({
        activeMarker: null,
        showingInfoWindow: false
      });
  };

  handleClick = () => {
    this.setState({ open: true });
  };

  handleClose = (event, reason) => {
    if (reason === 'clickaway') {
      return;
    }

    this.setState({ open: false });
  };

  render() {
    const { classes } = this.props;


    return (
      <div>
        <Map google={this.props.google} 
             onClick={this.onMapClicked}
             zoom={13} 
             initialCenter={{
             lat: 48.724865087482755,
             lng: -3.4469044744779467
                          }}
        >

         <Marker>
          name='Paris'
          onClick={this.onMarkerClick}
          position={{ lat: 48, lng: -3 }}
        />

        <InfoWindow
          marker={this.state.activeMarker}
          onClose={this.onInfoWindowClose}
          visible={this.state.showingInfoWindow}>
          <div>
            <h2>{this.state.selectedPlace.name}</h2>
            <p>{this.state.selectedPlace.description}</p>
            <button type="button" onClick={this.send}>Click Me</button>

          </div>
        </InfoWindow>
        </Map>
        </div>
    );
  }
}

export default GoogleApiWrapper({
  apiKey: ('APIKEY')
})(MapPage)
like image 508
Pierre Le Brun Avatar asked Dec 04 '18 14:12

Pierre Le Brun


People also ask

How do I add buttons to infowindow?

addListener(marker, 'click', function() { infowindow. setContent('<p>Event Name: '+this. title+'</p>' + '<p>Event Type: '+this. etype+'</p>' + '<p>Cause: '+this.

What is infowindow in Google Map?

An InfoWindow displays content (usually text or images) in a popup window above the map, at a given location. The info window has a content area and a tapered stem. The tip of the stem is attached to a specified location on the map. Info windows appear as a Dialog to screen readers.

How do I show multiple Infowindows on Google Maps?

By assigning the infowindow to a marker property, each marker can have it's own infowindow. This was how I approached the problem, with the relevant sample code. //create a marker object first, or instantiate it by passing a JSON to the constructor. //this can be done inside a for loop var infowindow = new google.


2 Answers

The way how InfoWindow component is implemented in google-maps-react library does not support to attach event handlers to info window dynamic content. The similar issue has been discussed in this thread.

The solution would be render InfoWindow children into a DOM node in order to prevent losing the React context, the following component could be introduced for that matter:

export default class InfoWindowEx extends Component {
  constructor(props) {
    super(props);
    this.infoWindowRef = React.createRef();
    this.contentElement = document.createElement(`div`);
  }

  componentDidUpdate(prevProps) {
    if (this.props.children !== prevProps.children) {
      ReactDOM.render(
        React.Children.only(this.props.children),
        this.contentElement
      );
      this.infoWindowRef.current.infowindow.setContent(this.contentElement);
    }
  }

  render() {
    return <InfoWindow ref={this.infoWindowRef} {...this.props} />;
  }
}

Now once InfoWindow replaced with InfoWindowEx event handlers could be attached to Component children:

<InfoWindowEx
        marker={this.state.activeMarker}
        visible={this.state.showingInfoWindow}>
        <button type="button" onClick={this.showDetails}>
            Show details
        </button>
</InfoWindowEx>

Demo

like image 160
Vadim Gremyachev Avatar answered Sep 23 '22 00:09

Vadim Gremyachev


Here's an updated implementation of Vadim Gremyachev's answer using React hooks:

import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import { InfoWindow } from "google-maps-react";

export default function InfoWindowEx(props) {
  const infoWindowRef = React.createRef();
  const contentElement = document.createElement(`div`);
  useEffect(() => {
    ReactDOM.render(React.Children.only(props.children), contentElement);
    infoWindowRef.current.infowindow.setContent(contentElement);
  }, [props.children]);
  return <InfoWindow ref={infoWindowRef} {...props} />;
}

Implementation JSX stays the same :)

<InfoWindowEx
        marker={this.state.activeMarker}
        visible={this.state.showingInfoWindow}>
        <button type="button" onClick={this.showDetails}>
            Show details
        </button>
</InfoWindowEx>

Cheers!

like image 42
Raz Chiriac Avatar answered Sep 26 '22 00:09

Raz Chiriac