Prevent React Google Maps from jumping to the center of the page when opening InfoWindow - react-google-maps

When I click on the map icon and open the info window the page jumps to the center of my screen. How can i prevent the page from jumping when i open an info window?
const UserMarker = props => (
<Marker
position={props.location}
icon={props.icon}
onClick={() => props.users.setIsOpen()}
>
{props.users.isOpen && <InfoWindow onCloseClick={() => props.users.setIsOpen()}>
<div>
<h3 className="margin-bottom-1">{props.users.hasDescription ? <img alt={props.users.name} src={props.icon} /> : <i className="fa fa-user" />} {props.users.name}</h3>
{props.users.hasDescription ? <p>{props.users.description}</p> : ''}
<p>{props.users.hasDescription ? '' : `Bid: ${props.users.bidAmount && convertToDollars(props.users.bidAmount)}`}</p>
</div>
</InfoWindow>}
</Marker>
)
export const UserMap = withScriptjs(withGoogleMap((props) => {
const { users, area, zoom } = props;
const markers = users.map((user, idx) => <UserMarker
key={idx}
users={user}
location={{ lat: user.lat, lng: user.lon }}
icon={user.marker}
/>);
return (
<React.Fragment>
<GoogleMap
defaultZoom={zoom}
center={{ lat: area.lat, lng: area.lon }}
>
{markers}
</GoogleMap>
</React.Fragment>
);
}
))

I guess you mean info window auto pan, if so, this is the default behavior, to disable info window auto-pan on open set disableAutoPan property to true for InfoWindow component like this:
<InfoWindow options={{disableAutoPan: true}}>
<div>
content
</div>
</InfoWindow>
Here is a demo

Related

How to send trigger onClick to child component in soldjs and display it in parent?

I was trying to take example from react but seem it doesn't work as I expected.
I am trying to open a modal when user click the button in parent component, but function to open modal is located in the child component.
Parent component just where i try to invoke a modal:
<label class="text-white m-5 p-1">
<input type="checkbox" checked={false} onChange={handleCheck} />
I have read and agree to the <button onClick={}>Privacy</button>
<Portal>
<TermsModal />
</Portal>
</label>
How to do that?
If you want the Modal component to control the state, instead of it being passed with props you can use this pattern:
const { Modal, openModal } = createModal();
return (
<>
<button type="button" onClick={openModal}>
open modal
</button>
<Modal />
</>
);
It may be weird at first, but it's really fun and powerful :)
https://playground.solidjs.com/anonymous/d3a74069-e3d4-4d3e-9fb2-bafc5d6f5bf5
Create a signal inside parent component and pass it to the child component. Bind the visibility of the modal window to the signal's value:
import { Component, createSignal, Show } from 'solid-js';
import { Portal, render } from 'solid-js/web';
const Modal: Component<{ show: boolean }> = (props) => {
return (
<Show when={props.show}>
<div>Modal Window</div>
</Show>
);
};
const App = () => {
const [show, setShow] = createSignal(false);
const toggleShow = () => setShow(prev => !prev);
return (
<div>
<div>Show: {show() ? 'true': 'false'} <button onClick={toggleShow}>Toggle Show</button></div>
<Portal><Modal show={show()} /></Portal>
</div>
)
};
render(() => <App />, document.body);
https://playground.solidjs.com/anonymous/adf9ba7a-3e1b-4ce9-92b2-e78ff3fa55ec
You can further improve your component by creating a close handler and passing it to the child component. Now, modal window can show a close button.
Also you can add an event handler to the document in order to close the window whenever Escape key is pressed:
import { Component, createSignal, onCleanup, onMount, Show } from 'solid-js';
import { Portal, render } from 'solid-js/web';
const Modal: Component<{ show: boolean, close: () => void }> = (props) => {
const handleKeydown = (event) => {
if (event.key === 'Escape') {
props.close();
}
};
onMount(() => {
document.addEventListener('keydown', handleKeydown);
});
onCleanup(() => {
document.removeEventListener('keydown', handleKeydown);
});
return (
<Show when={props.show}>
<div>Modal Window <button onclick={props.close}>close</button></div>
</Show>
);
};
const App = () => {
const [show, setShow] = createSignal(false);
const close = () => setShow(false);
const toggleShow = () => setShow(prev => !prev);
return (
<div>
<div>Show: {show()} <button onClick={toggleShow}>Toggle Show</button></div>
<Portal><Modal show={show()} close={close} /></Portal>
</div>
)
};
render(() => <App />, document.body);
https://playground.solidjs.com/anonymous/0ae98cf1-19d6-487f-80dc-72d3c2e554dc
You can use a state in the parent component to keep track of whether the modal should be open or closed, and pass a function as a prop to the child component that updates that state:
const [isModalOpen, setIsModalOpen] = React.useState(false);
const handleButtonClick = () => {
setIsModalOpen(true);
};
return (
<div>
<label className="text-white m-5 p-1">
<input type="checkbox" checked={false} onChange={handleCheck} />
I have read and agree to the <button onClick={handleButtonClick}>Privacy</button>
<Portal>
<TermsModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} />
</Portal>
</label>
</div>
);
// Child component
const TermsModal = ({ isOpen, onClose }) => {
if (!isOpen) {
return null;
}
return (
<div className="modal">
{/* Modal content */}
<button onClick={onClose}>Close</button>
</div>
);
};

(create-react-app) Extra small box in InfoWindow of Google Map API

I am trying to create an InfoWindow with Google Map API, but there is always an extra small box with the same class to the big InfoWindow. Any way I can get rid of the small InfoWindow?
Here's the link of the image showing the extra small box
Here's my code. Full code here: https://gist.github.com/juifuhung/c2ca99cfbb20bf53686b8bc57d8a8524
return (
<div style={{ display: "flex" }}>
{console.log(array)}
<GoogleMap
zoom={12}
center={center}
mapContainerClassName="map-container"
>
{array.map((location) => (
<Marker
key={uuidv4()}
icon={location.icon}
position={{ lat: location.lat, lng: location.lng }}
onClick={() => {
setSelected(location);
}}
/>
))}
{selected && (
<InfoWindow
position={{ lat: selected.lat, lng: selected.lng }}
onCloseClick={() => setSelected(null)}
>
<div>
<h1>{selected.title}</h1>
<p>{selected.description}</p>
<FaHeart />
<img src={selected.image} alt="" />
</div>
</InfoWindow>
)}
</GoogleMap>
<p>map</p>
</div>
);
};
Try setting the size for your info window, or there might be a bool to set the small info box into hidden
<InfoWindow
this.state.isOpen &&
<InfoWindow onCloseClick={() => this.setState({isOpen:
false})}>
position={{ lat: selected.lat, lng: selected.lng }}
onCloseClick={() => setSelected(null)}
>
<div>
<h1>{selected.title}</h1>
<p>{selected.description}</p>
<FaHeart />
<img src={selected.image} alt="" />
</div>
</InfoWindow>
But if this is an old api, please update to the latest one
#react-google-maps/api

How can I do a close button to a mui-select and a mui-datepicker?

I would like to add a close button to a mui-select and a mui-datepicker.
Tried to find but couldn't.
Does anyone know how to do that?
You can do this by controlling the state of the select manually. Properties open, onOpen, onClose can help you.
import * as React from 'react';
import {
OutlinedInput,
InputLabel,
MenuItem,
FormControl,
Select,
Checkbox,
Button
} from '#mui/material';
const names = [
'Oliver Hansen',
'Van Henry',
'April Tucker',
];
export default function MultipleSelectCheckmarks() {
const [personName, setPersonName] = React.useState([]);
const [showSelect, setShowSelect] = React.useState(false);
const handleChange = (e) => {
setPersonName(e.target.value.filter(Boolean));
};
return (
<FormControl sx={{ m: 1, width: 300 }}>
<InputLabel id="demo-multiple-checkbox-label">Tag</InputLabel>
<Select
multiple
open={showSelect}
onOpen={() => setShowSelect(true)}
onClose={() => setShowSelect(false)}
labelId="demo-multiple-checkbox-label"
id="demo-multiple-checkbox"
value={personName}
onChange={handleChange}
input={<OutlinedInput label="Tag" />}
renderValue={(selected) => selected.join(', ')}
>
{names.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.includes(name)}/>
{name}
</MenuItem>
))}
<Button
color='success'
variant='contained'
onClick={() => {
setShowSelect(false);
}}
>
Close
</Button>
</Select>
</FormControl>
);
}
Thanks for the pointer Валерий Зайцев
In case you want to also close the FormControl when the user clicks away (without a dedicated close button for example), set the FormControl attribute 'focus' to false.
e.g.
<FormControl sx={{ m: 1, width: 300, focus={showSelect} }}>

How to remove markers in react-google-maps

I create my markers like this, a recurisve function call every 5 seconds to
change layers on the map.
var MeterLocations= Object.keys(dict)
var currloc = 0;
var markers;
function cycleMeteors(callback){
markers = dict[MeterLocations[currloc]].map(function(arr,i){
return(
<Marker
icon={purpleS}
key={i+"marker-num"+MeterLocations[currloc]}
position={{ lat: parseFloat(arr.val[4]),
lng: parseFloat(arr.val[5]) }}
/>)
})
currloc +=1;
setTimeout(function(){
callback(markers);
},5000);
}
I attempt here to remove the markers from the map by popping the entire array into length = 0. but that does not remove the markers from the map. another post mentioned settng the map to null map[map.length-1].setMap(null) but that doesnt work in reactjs
var [map, setMap] = useState([]);
cycleMeteors(function(s){
console.log(s.length);
while(map.length){
console.log(map.length)
map.pop()
}
// s is the new array of markers
setMap(s);
})
idk if you need this but here is my app.js
const MapWithAMarker = withScriptjs(withGoogleMap(props => {
console.log(props.children);
return (
<GoogleMap
defaultZoom={2}
defaultCenter={{ lat: 0, lng: 0 }}
>
{props.children.length ? props.children : []}
</GoogleMap>
)
}));
function App() {
var [map, setMap] = useState({});
cycleMeteors(function(s){
console.log(s.length);
while(map.length){
console.log(map.length)
map[map.length-1].setMap(null)
map.pop()
}
setMap(s);
})
return (
<div className="App">
<article>
<div id="maps-widget">
</div>
</article>
<article>
<h4>Data stuff</h4>
<p> These items amount of </p>
<p> Metory type | number in class </p>
{/*<MClassView data={dict}/>
*/}
<MapWithAMarker
googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${apikey}&v=3.exp&libraries=geometry,drawing,places`}
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `600px`, width: "1000px" }} />}
mapElement={<div style={{ height: `100%` }} />}
>{map}</MapWithAMarker>
</article>
</div>
);
}

DatePicker in Redux Form

i'd like to use DatePicker for selecting date using redux form.
I create this:
import React from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
export default field => (
<div>
<DatePicker
onChange={field.value}
selected={field.value}
isClearable={true}
>
{field.children}
</DatePicker>
{field.meta.touched && field.meta.error &&
<span className="error">{field.meta.error}</span>}
</div>
);
<div className="form-group">
<div className="col-xs-12 col-sm-3 ">
<div className="label" htmlFor="date-to">DATE TO</div>{' '}
<Field
id="date-to"
name="date-to"
component={DateInput}
/>
</div>
</div>
But it does not return any values and the does not show the date in the field
What should i do?
You want to wrap the DatePicker element that it can be used as a component on "Field" like this:
const renderDatePicker = ({input, placeholder, defaultValue, meta: {touched, error} }) => (
<div>
<DatePicker {...input} dateForm="MM/DD/YYYY" selected={input.value ? moment(input.value) : null} />
{touched && error && <span>{error}</span>}
</div>
);
export default renderDatePicker
Refer to this GitHub issue for more information: https://github.com/Hacker0x01/react-datepicker/issues/543
export const renderDatePicker = ({ input, label, meta: { touched, error }, ...custom }) => {
return (
<DatePicker {...input} {...custom} autoOk={true} dateForm='MM/DD/YYYY' onChange={(event, value) => input.onChange(value)} />
);
};
export const Datepicker = ({
input, id, label, required, className, disabled, intl, popoverAttachment, popoverTargetAttachment, popoverTargetOffset, todayButton,
meta: { touched, error, invalid } }) => (
<FormGroup color={`${touched && invalid ? 'danger' : ''}`} className={`${required ? 'required ' : ' '}${className}`}>
{label && <Label htmlFor={id}>{label}</Label>}
<DatePicker
className="form-control"
{...input}
fixedHeight
todayButton={todayButton}
label={label}
id={id}
dateForm="MM/DD/YYYY"
selected={input.value ? moment(input.value) : null}
disabled={disabled}
popoverAttachment={popoverAttachment}
popoverTargetAttachment={popoverTargetAttachment}
popoverTargetOffset={popoverTargetOffset}
/>
{touched && error && <FormFeedback>{intl.formatMessage(error)}</FormFeedback>}
</FormGroup>
);
You can make your own component field of datepicker like i mentioned above and used it in Field of redux