Search code examples
javascriptreactjsleaflettogglereact-leaflet

Check if Dialog is already open


I'm working on application where I'm displaying a map & multiple different locations with markers. These markers can be clicked in order to open simple dialog, which shows some information about that specific location. Here is code sample:

Mapping through array of locations & calling the function on each marker.

      {markers && (
    <>
      {markers.map((marker, idx) => (
        <MarkerDialog key={idx} marker={marker} />
      ))}
    </>
  )}

Adding dialog to marker.

const MarkerDialog = ({ marker }) => {
const [dialog, setDialog] = useState(false);

const handleClickOpen = () => {
setDialog(true);
};

const handleClose = () => {
setDialog(false);
};

const handleMarkerClick = (e, marker) => {
if (dialog) {
  handleClose();
} else {
  handleClickOpen();
}
};

return (
<div>
  <Marker
    position={marker.location}
    icon={status(marker)}
    eventHandlers={{
      click: handleMarkerClick,
    }}
  />

  {dialog && (
    <Dialog
      marker={marker}
      dialog={dialog}
      handleClose={handleClose}
    />
  )}
</div>
);
};

export default MarkerDialog;

This creates a problem if you click on multiple markers. In that case the dialogs stack on top of each other, because application never closes previous dialog.

If I click on marker and dialog opens, and then I'll go and click on another marker, I would like that previous dialog closes. How can I achieve this?


Solution

  • Lift the state up and maintain a selected index for the click of the marker.

    MarkerDialog

    const MarkerDialog = ({ marker,  handleMarkerClick, handleClose,dialog }) => {
      return (
        <div>
          <Marker
            position={marker.location}
            icon={status(marker)}
            eventHandlers={{
              click: handleMarkerClick
            }}
          />
    
          {dialog && (
            <Dialog marker={marker} dialog={dialog} handleClose={handleClose} />
          )}
        </div>
      );
    };
    
    export default MarkerDialog;
    

    Parent

    const [selectedMarkerIndex, setSelectedMarkerIndex] = useState(null);
    
    const handleClose = () => {
      setSelectedMarkerIndex(-1)
    };
    
    const handleMarkerClick = (e, marker,index) => {
      /* Do stuff with e and marker */
      setSelectedMarkerIndex(index)
    };
    
    {
      markers && (
        <>
          {markers.map((marker, idx) => (
            <MarkerDialog
              key={idx}
              marker={marker}
              handleMarkerClick={(e, marker) => handleMarkerClick(e, marker, idx)}
              handleClose={handleClose}
              dialog={idx === selectedMarkerIndex}
            />
          ))}
        </>
      );
    }