我有一个表单,用户必须在Map上指定他家的位置。在这个表单中,我使用了React Leafletmap。<Marker>
的默认位置是用户的当前位置。我想有一个按钮,每当用户点击它,标记成为可拖动的,并可以放置在用户设置它的任何地方。我还在<Popup>
中添加了一个提交按钮,当用户点击它时,标记不得拖动,并且必须更新和保存标记位置以发送到后端。
下面是我的代码:
const SetViewToCurrentLocation = ({location, setLocation}) => {
const map = useMap();
function getGeo() {
navigator.geolocation.getCurrentPosition(
(position) => {
setLocation({
lat: position.coords.latitude,
lng: position.coords.longitude,
});
},
(error) => {
console.log("--------- ERROR WHILE FETCHING LOCATION ----------- ", error);
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000}
) ;
}
useEffect(() => {
getGeo();
}, []);
useEffect(() => {
if (location.lat && location.lng) {
map.setView([location.lat, location.lng]);
}
}, [location]);
return null;
};
const CustomizeMarker = ({location, setLocation}) => {
const [draggable, setDraggable] = useState(false);
console.log("*************** THE INPUT LOCATION IS ***************** ", location);
let lat = location.lat;
let lng = location.lng;
const [position, setPosition] = useState({lat, lng});
console.log("-----------------THE POS VALUE IS ------------------- ", position);
const markerRef = useRef(null);
const eventHandlers = useMemo(
() => ({
dragend() {
const marker = markerRef.current
if (marker != null) {
console.log("+++++++++++ THE OUTPUT OF getLatLng IS ++++++++++++ ", marker.getLatLng());
setPosition(marker.getLatLng());
setDraggable(false);
}
},
}),
[],
);
const toggleDraggable = useCallback(() => {
setDraggable((d) => !d)
}, []);
const saveLocation = () => {
console.log("HELLO WORLD");
};
return (
<>
<Marker
draggable={draggable}
eventHandlers={eventHandlers}
position={[position.lat, position.lng]}
ref={markerRef}>
<Popup minWidth={90}>
<Button onClick={saveLocation}>Submit</Button>
</Popup>
</Marker>
<Button onClick={toggleDraggable} variant='contained' className='edit-location-button'>Edit Your Location</Button>
</>
);
}
const EditHome = () => {
const [location, setLocation] = useState({});
return (
<React.Fragment>
<Box
component="form"
sx={{
"& .MuiTextField-root": { m: 1, maxWidth: "100%"},
}}
noValidate
autoComplete="off"
dir="ltr"
>
<form>
<div style={{ paddingLeft: "2.5rem" }}>
<Grid item xs={12}>
<h6 style={{ fontWeight: "bold", paddingRight: "4.9rem", marginTop: "0.8rem" }}>
Specify The Location of Your Home on The Map
</h6>
<div className='map-container'>
<MapContainer center={[0, 0]} zoom={16} scrollWheelZoom={true}>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<GeoSearchField />
<SetViewToCurrentLocation location={location} setLocation={setLocation}/>
{location.lat && location.lng && (<CustomizeMarker location={location} setLocation={setLocation} />)}
</MapContainer>
</div>
</Grid>
</div>
</form>
</Grid>
</Box>
</React.Fragment>
)
}
export default EditHome;
但是我有几个问题。第一个是<Button>
在Map中不可见,我想把它设置在Map的左上角,我已经为它定义了下面的CSSclass
。
.leaflet-container {
width: 57rem;
height: 40rem;
}
.map-container {
position: relative;
}
.edit-location-button {
position: absolute;
top: 10px;
right: 10px;
}
第二个问题是标记的功能及其位置的更改处理程序。
这是我的实现的当前输出:
我将感谢任何帮助。
1条答案
按热度按时间k2arahey1#
你很接近了。
首先能够看到按钮添加一个zindex值在您的css大enought是在Map之上
第二,你需要使按钮的类型按钮,否则他们似乎是类型提交,这将导致页面刷新每一次点击。它应该是类似的材料ui。我做了纯html。添加
type="button"
到您的按钮。这个功能看起来还不错,可以用。唯一的一点是,你不需要在
Marker
组件中添加编辑位置按钮,因为它们是不相关的。我把它放在了你已经拥有的Fragment的外面。此外,要在单击提交时获得坐标,你需要调用而不是在dragend回调中记录标记。
您可以在demo中看到结果。