Display attributes for Selected Store
Listen to the Selected Store and pass it to a component where you would like to display your stores attributes.This tutorial is outdated and will be taken down shortly. To integrate Woosmap Map with React, please use the Woosmap Map JS library. You can refer to this code sample for guidance: React Map Basic.
MVC Object
The Woosmap Store Locator JS API provide a class called MVCObject()
implementing the KVO mechanism, for Key Value Observing.
Using it you can observe properties changes of an object.
The woosmap.TiledView
handles the click event on all store markers and save the store clicked into property called selectedStore
.
As the TiledView
extends the MVCObject
this property is bindable.
Therefore, to be aware that a user select a store on the Map, create a new MVCObject
and bind it to this property on the TiledView
.
Map.js
const mapView = new window.woosmap.TiledView(map, conf.markersOptions);
const selectedStoreObserver = new window.woosmap.utils.MVCObject();
selectedStoreObserver.selectedStore_changed = () => {
console.log(selectedStoreObserver.get('selectedStore'));
};
selectedStoreObserver.bindTo('selectedStore', mapView);
Set SelectedStore State
The purpose here is to create a state for the Map component to save the selected store.
With useState
hook, React can remember a state variable for us, making sure it gets passed into our component instance correctly.
Map.js
const Map = () => {
const [selectedStore, setSelectedStore] = useState()
//in initMap()
selectedStoreObserver.selectedStore_changed = () => {
setSelectedStore(selectedStoreObserver.get('selectedStore'));
};
}
Create an InfoBox Component
Now that you are able to collect and remember the selected store, you can create a component and pass in this state, so the component will update on selected store change.
Create a new file components/InfoBox.js
and build a component accepting the store as parameter.
components/InfoBox.js
const Infobox = ({store}) => {
return (
<div className='infoBox' id={`infobox-${store.properties.store_id}`}>
<div className="infoBox__storeName">{store.properties.name}</div>
{store.properties.address && <div>
<h4 className="infoBox__addressTitle">Address</h4>
<div className="infoBox__addressLines">{store.properties.address.lines}</div>
<div className="infoBox__addressCity">{store.properties.address.city}</div>
</div>}
{store.properties.contact && <div>
<h4 className="infoBox__contactTitle">Contact</h4>
<div className="infoBox__contactPhone">{store.properties.contact.phone}</div>
<div className="infoBox__contactWebsite"><a href={store.properties.contact.website} target='_blank'>go
to website</a>
</div>
</div>}
</div>
);
};
export default Infobox;
You can also add a default return when no store is selected, which is the case before the user clicks on a marker.
if (!store) {
return (<div className="infoBox">Click on a Store Marker...</div>);
}
The infobox needs a few styling rules to display over the Map component correctly. Add the following CSS to the InfoBox.css
file:
components/InfoBox.css
.infoBox {
display: inline-block;
position: absolute;
top: 0;
left: 0;
margin: 15px;
padding: 15px;
background-color: #FFF;
border-radius: 4px;
color: #1d1d1d;
z-index: 1;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
max-width: 300px;
}
Finally, in your Map component, add your newly created InfoBox with the state property store={selectedStore}
.
Map.js
import Infobox from "./components/InfoBox";
/*...*/
return (
<div>
<Infobox store={selectedStore}/>
<div className='mapContainer' ref={mapContainerRef}/>
</div>
);
Result
You have created a React app that uses Woosmap Store Locator JS API to render a map, display your stores on top of it, and let the user interacts with them to display relative attributes.
You can explore this example and other more complex in the Woosmap React examples GitHub repository.