infowWindow onclick event and infowWindow options not working?
This is the code that i am trying:
import React from 'react'
import { withGoogleMap, GoogleMap, Marker, InfoWindow } from 'react-google-maps'
const mapOptions = {
scrollwheel: false,
draggable: true,
rotateControl: false,
scaleControl: false,
streetViewControl: false,
panControl: false
}
const num10 = 10
const descriptionLentgh = 35
const GettingStartedGoogleMap = withGoogleMap((props) => (
<GoogleMap
options={mapOptions}
ref={props.onMapLoad}
defaultZoom={4}
center={props.center}
onClick={props.onMapClick}
>
{props.markers.map((marker, index) => (
<Marker
key={index}
position={marker.position}
onClick={() => props.onMarkerClick(marker)}
icon={marker.markerIcon === true
? '/images/markerlogo2.png' : '/images/markerlogo.png'}
label={{ text: `$${marker.rate}`, color: 'white' }}
{...marker}
//onRightClick={() => props.onMarkerRightClick(index)}
>
{marker.showInfo && (
<InfoWindow onClick={props.onWindowClick}
onCloseClick={() => props.onMarkerClose(marker)}
>
<div className="">
<div className="map-info-box">
<div className="parking-inner-container">
<div className="parking-inner">
<div className="parking-container">
<div className="parking-image-wrapper">
<div className="parking-image"
style={{ 'backgroundImage': `url(${marker.photos})` }}
/>
</div>
</div>
</div>
</div>
<div className="parking-info">
<div className="parking-title">
<h5><b>${marker.rate} {marker.infoContent}</b></h5>
</div>
<div className="parking-location">
<h2>{`${marker.description.substring(0, descriptionLentgh)}...`}</h2>
</div>
<div className="">
<h2 className="label label-default" style={marker.secured === false
? { backgroundColor: 'gray', fontSize: '100%' }
: { backgroundColor: 'green', fontSize: '100%' } }
>
{marker.secured === false ? 'open' : 'secured'}</h2>
</div>
</div>
</div>
</div>
</InfoWindow>
)}
</Marker>
))}
</GoogleMap>
))
class GoogleMaps extends React.Component {
constructor(props) {
super(props)
this.state = {
center: {
lat: 47.853287,
lng: -93.646775
},
markers: [],
true: true
}
}
componentWillReceiveProps(nextProps) {
this.setState({ markers: [], center: nextProps.bound.location }, () => {
const m = nextProps.pageNo - 1
if (nextProps.markers[0] !== undefined) {
let obj = {}
let newArray = []
for (let i = m * num10; i <= nextProps.markers.length; i++) {
if (i === m * num10 + num10) { break }
obj = {
position: { lat: nextProps.markers[i].loc[1], lng: nextProps.markers[i].loc[0] },
rate: nextProps.markers[i].spaces[0].rate,
infoContent: nextProps.markers[i].listingName || nextProps.markers[i].spaces[0].name,
showInfo: false,
photos: nextProps.markers[i].photos[0],
description: nextProps.markers[i].basic_details.notes,
secured: nextProps.markers[i].isSecured,
markerIcon: false
}
newArray = this.state.markers
newArray.push(obj)
this.setState({ markers: newArray })
}
} else {
this.setState({ markers: this.props.markers })
}
})
}
handleMarkerClick(targetMarker) {
this.setState({
markers: this.state.markers.map((marker) => {
if (marker === targetMarker) {
return {
...marker,
showInfo: true,
markerIcon: true
}
} else {
return {
...marker,
showInfo: false
}
}
})
})
}
handleMarkerClose(targetMarker) {
this.setState({
markers: this.state.markers.map((marker) => {
if (marker === targetMarker) {
return {
...marker,
showInfo: false
}
}
return marker
})
})
}
handleMarkerClose2(targetMarker) {
this.setState({
markers: this.state.markers.map((marker) => {
if (targetMarker) {
return {
...marker,
showInfo: false
}
}
return marker
})
})
}
onWindowClick() {
console.log('fdgdsfg')
}
render() {
return (<div>
<div id="mapcanvas"
className="col-md-6"
style={{ 'height': '556px', 'width': '674px', paddingLeft: '0px', paddingRight: '0px' }}
>
<GettingStartedGoogleMap
containerElement={<div style={{ height: '100%' }} />}
mapElement={<div style={{ height: '100%' }} />}
//onMapLoad={_.noop}
onMapClick={this.handleMarkerClose2.bind(this)}
onMarkerClick={this.handleMarkerClick.bind(this)}
markers={this.state.markers}
center={this.state.center}
//onMarkerRightClick={this.handleMarkerRightClick.bind(this)}
onMarkerClose={this.handleMarkerClose.bind(this)}
/>
</div>
<style>{'\
.gm-style-iw + div {\
display: none;\
left: 26px;}\
'}</style>
</div>)}
}
GoogleMaps.propTypes = {
markers: React.PropTypes.array
}
export default GoogleMaps
I just ran into this issue some days ago and seems that the only way to attach an onClick to an InfoWindow is with google.maps.event in place.
I used 'react-dom/server' to set the content of it, where content is a React.Component.
Here you have an example:
const info = new googleMaps.InfoWindow({
map,
disableAutoPan: true,
maxWidth: 300,
content: ReactDom.renderToString(content)
});
google.maps.event.addListener(info, 'domready', () => {
document.querySelector('.gm-style-iw').addEventListener('click', onClick);
});
Related
I have a problem with React Final Form. I tried to follow the example on the official documentation, but I still don't understand why my form doesn't want to call the onSubmit as the example, and I'm still trying to understand what the role of handlesubmit is.
I think that the problem is that my fields are called from another component that uses the useField hook.
import React, { FC } from 'react'
import { Form, Field } from 'react-final-form'
import {
Grid,
Box,
Button,
createStyles,
makeStyles,
Theme,
} from '#material-ui/core'
import { render } from 'react-dom'
import InputField from './InputField'
interface InputFinalFormModalProps {
fieldsValue: { title: string; value: string }[]
}
const useStyles = makeStyles((theme: Theme) =>
createStyles({
annullaBtn: {
backgroundColor: '#fff',
border: `1px solid ${theme.palette.secondary.main}`,
color: theme.palette.secondary.main,
fontFamily: 'HouschkaHead',
fontSize: '17px',
fontWeight: 'bold',
paddingLeft: '40px',
paddingRight: '40px',
marginRight: '15px',
},
salvaBtn: {
fontFamily: 'HouschkaHead',
fontSize: '17px',
fontWeight: 'bold',
paddingLeft: '40px',
paddingRight: '40px',
marginLeft: '15px',
},
row: {
width: '100%',
textAlign: 'end',
},
container: {
'& > .MuiGrid-item': {
paddingBottom: '20px',
paddingTop: '0px',
paddingLeft: '11px',
paddingRight: '11px',
},
},
})
)
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
const onSubmit = async (values: {}) => {
await sleep(300)
console.log(JSON.stringify(values))
}
const validate = (values: {}) => {
const errors = {message: ''}
if (!Object.values(values).toString()) {
errors.message = "Required";
}
return errors
}
const InputFinalFormModal: FC<InputFinalFormModalProps> = ({ fieldsValue }) => {
const classes = useStyles()
return (
<Form
onSubmit={onSubmit}
validate={validate}
render={({ handleSubmit, form, submitting, pristine, values }) => (
<form onSubmit={handleSubmit}>
<Grid container className={classes.container}>
{fieldsValue.map((field) => {
return (
<InputField title={field.title} value={field.value} />
)
})}
</Grid>
<Box className={classes.row} mt="20px">
<Button className={classes.annullaBtn}>Annulla</Button>
<Button
type="submit"
onClick={() => onSubmit(values)}
className={classes.salvaBtn}
disabled={submitting || pristine}
>
Salva
</Button>
</Box>
{/* <button
type="submit"
onClick={() => onSubmit(values)}
disabled={submitting || pristine}
>
Submit
</button>
<button
type="button"
onClick={form.reset}
disabled={submitting || pristine}
>
Reset
</button>
<pre>{JSON.stringify(values)}</pre>*/}
</form>
)}
/>
)
}
InputFinalFormModal.displayName = 'InputFinalFormModal'
export default InputFinalFormModal
And here my snippet about the inputField
import React, { FC, useEffect, useState } from 'react'
import { useField } from 'react-final-form'
import {
Box,
Grid,
createStyles,
makeStyles,
Theme,
withStyles,
} from '#material-ui/core'
import InputLabel from '#material-ui/core/InputLabel'
import InputBase from '#material-ui/core/InputBase'
import { parse } from 'path'
interface InputFieldProps {
title: string
value: string
}
const BootstrapInput = withStyles((theme: Theme) =>
createStyles({
input: {
borderRadius: 4,
position: 'relative',
backgroundColor: theme.palette.common.white,
border: '1px solid #bdc7d3',
width: '100%',
padding: '10px 12px',
transition: theme.transitions.create(['border-color', 'box-shadow']),
// Use the system font instead of the default Roboto font.
fontFamily: 'Montserrat',
fontSize: '14px',
lineHeight: '1.21',
fontWeight: 'normal',
color: theme.palette.text.primary,
'&:focus': {
boxShadow: 'inset 0 0 12px 4px rgba(0, 179, 152, 0.05)',
borderColor: theme.palette.secondary.main,
},
},
})
)(InputBase)
const useStyles = makeStyles((theme: Theme) =>
createStyles({
inputTitle: {
color: '#7C92A8',
fontSize: '19px',
lineHeight: 1.76,
transition: 'font-weight 0.5s, color 0.5s',
'&.Mui-focused': {
color: theme.palette.secondary.main,
fontWeight: 'bold',
},
},
requiredText:{
color: 'red'
}
})
)
const InputField: FC<InputFieldProps> = ({ title, value}) => {
let {input, meta} = useField(title)
const classes = useStyles()
let [handleValidate, setHandleVlidate] = useState(false)
let [required, setRequired] = useState('')
useEffect(() => {
if(parseInt(value)){
setRequired('valore non valido')
setHandleVlidate(true)
/* if(isNaN(input.value)){
} */
}else{
if(!input.value){
setRequired('Campo Obbligatorio')
setHandleVlidate(true)
}
}
},[input.value])
return (
<Grid item xs={12} md={6}>
<InputLabel
shrink
htmlFor="bootstrap-input"
className={classes.inputTitle}
>
{title}
</InputLabel>
<BootstrapInput
{...input}
defaultValue={value}
id="bootstrap-input"
placeholder={value}
/>
{meta.touched && !input.value && (
<span className={classes.requiredText}>{required}</span>
)}
</Grid>
/* <Grid item xs={6} lg={6}>
<Box>
<label className={classes.inputTitle} onClick={() => console.log('check')}>{title}</label>
</Box>
<input {...field.input} className={classes.inputField} placeholder={value} />
{field.meta.touched && field.meta.error && (
<span>{field.meta.error}</span>
)}
</Grid> */
)
}
InputField.displayName = 'InputField'
export default InputField
If your form is valid, the validation function needs to return {}, not { message: '' }.
I did a google map with a list of resellers using "react-google-maps"
The markers properly looping and showing in the map
How can I list the 'Marker'/'Resellers' in the Map into a list(UL) too, Also the list(li) click should pop the info window?
This is the one I used, https://gist.github.com/jwo/43b382fc60eb09d3a415c9953f4057f8
import React, { Component } from "react"
import { compose } from "recompose"
import {
withScriptjs,
withGoogleMap,
GoogleMap,
Marker,
InfoWindow, Listing
} from "react-google-maps"
const MapWithAMarker = compose(withScriptjs, withGoogleMap)(props => {
const listStyle = {
width: '250px',
position: "relative"
}
return (
<div style={{ position: "relative" }}>
<GoogleMap defaultZoom={4} defaultCenter={{ lat: 56.263920, lng: 9.501785 }}>
{props.markers.map(marker => {
if (marker.lat != null) {
const onClick = props.onClick.bind(this, marker)
return (
<Marker
key={marker.customerNumber}
onClick={onClick}
position={{ lat: parseFloat(marker.lat), lng: parseFloat(marker.lng) }}
>
{props.selectedMarker === marker &&
<InfoWindow>
<div>
<h1> {marker.name}</h1>
<br />
{marker.address}
<br />
{marker.zipcode} {marker.city}
<br />
Telephone: {marker.phone}
</div>
</InfoWindow>}
{/* List resellers here, so info window can be reused I guess, not sure */}
</Marker>
)
}
})}
</GoogleMap>
</div>
)
})
export default class ResellerGoogleMap extends Component {
constructor(props) {
super(props);
this.state = {
showingInfoWindow: false,
selectedMarker: {},
selectedPlace: {}
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(marker, event) {
console.log(this.props)
this.setState({
selectedMarker: marker
});
}
render() {
return (
<div style={{ padding: "24px 13px 2px 2px" }}>
<input type="button" value="My Location" style={{ marginBottom: "20px" }} onClick={(e) => this.onBtnClick()} />
<MapWithAMarker
selectedMarker={this.state.selectedMarker}
markers={this.props.resellerData}
onClick={this.handleClick}
googleMapURL="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places"
loadingElement={<div style={{ height: `100%`, padding: `61px 55px 55px 55px` }} />}
containerElement={<div style={{ height: `800px` }} />}
mapElement={<div style={{ height: `511px` }} />}
/>
</div>
);
}
}
Expecting
a Google map/
Markers of 'resellers'/
List the resellers in a list too/
On click of list item should populate info window like when we click on Markers/
First two points are working, Need a hand on the rest, Please help somebody
Thank you all for your time, I found the solution
Simply we can add the following line of code just after the infowindow close tag
<a onClick={onClick}>{marker.name}</a>
So, I have been trying to use google-maps and fill my data with marker and show info-window.
For reference see img
But, my goal is to make the page responsive also, i have got many thing done but making infowindow resposnive is a prob.
My goal is to show info-window full screen upon click event. But currently its a stupid.
See img for reference
So, how to make my infowindow to show full screen upon click.
Thanks and appreciate your help.
EDIT:
my code
import React, { Component } from 'react';
import { Map, InfoWindow, Marker, GoogleApiWrapper } from 'google-maps-react';
import DRINKING_WATER_PUMP from './pins/strop3.png'
import ROOFTOP from './pins/strop2.png'
import IRRIGATION_PUMP from './pins/strop1.png'
import PATVAN from './pins/strop5patvan.png'
import MINIGRID from './pins/strop4.png'
import farmer from './pins/user.png'
import axios from 'axios'
import config from './config.js'
import Swal from 'sweetalert2'
const mapStyles = {
width: '100%',
height: '100%',
position:'relative',
display: 'flex',
flexFlow: 'row nowrap',
justifyContent: 'center',
};
class MapList extends Component{
constructor(props) {
super(props);
this.markersRendered = false;
}
shouldComponentUpdate(nextProps, nextState) {
if (JSON.stringify(this.props.places) === JSON.stringify(nextProps.places) && this.markersRendered) {
return false;
}
this.markersRendered = true;
return true;
}
render() {
return (
<span>
{
this.props.places.map((marker, index) => {
let assetType=marker.assetType
let icon={
url:'' ,
anchor: new this.props.google.maps.Point(12,23),
origin: new this.props.google.maps.Point(0,0),
scaledSize: new this.props.google.maps.Size(20,20)
}
switch(assetType){
case 'PATVAN':icon.url=PATVAN; break;
case 'MINIGRID':icon.url=MINIGRID; break;
case 'IRRIGATION_PUMP':icon.url=IRRIGATION_PUMP; break;
case 'DRINKING_WATER_PUMP':icon.url=DRINKING_WATER_PUMP; break;
case 'ROOFTOP':icon.url=ROOFTOP; break;
default: break;
}
return (
<Marker {...this.props} key={index} assetId={marker.assetId} assetType={assetType} icon={icon} position={{lat: parseFloat(marker.lat), lng: parseFloat(marker.lng)}} />
)
})
}
</span>
)
}
}
class MapContainer extends Component {
constructor(props){
super(props)
this.state = {
showingInfoWindow: false, //Hides or the shows the infoWindow
activeMarker: {}, //Shows the active marker upon click
selectedPlace: {'owner':{}} //Shows the infoWindow to the selected place upon a marker
};
this.onMarkerClick=this.onMarkerClick.bind(this)
this.onClose=this.onClose.bind(this)
}
onMarkerClick(props, marker, e){
let url;
switch(props.assetType){
case 'PATVAN':url=config.patvan; break;
case 'MINIGRID':url=config.minigrid; break;
case 'IRRIGATION_PUMP':url=config.irrigation; break;
case 'DRINKING_WATER_PUMP':url=config.drinkingwater; break;
case 'ROOFTOP':url=config.rooftop; break;
default: break;
}
axios({
url:url,
method:'POST',
data:{
assetId:props.assetId
},
headers:{
'Content-Type': 'application/json'
}
}).then((res)=>{
if(res.data.data!==null){
let data=res.data.data
data['assetType']=props.assetType
this.setState({
selectedPlace: data,
activeMarker: marker,
showingInfoWindow: true
});
}
else if(res.data.error!==undefined){
if(res.data.error.errorCode===153){
window.location.href='../login.html?redirect=dashboard';
}
else{
Swal({
type: 'error',
title: 'Oops...',
text: res.data.error.errorMsg,
})
}
}
})
}
onClose(props) {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
});
}
}
render() {
return (
<Map id="map"
mapTypeControl={false}
gestureHandling= {'greedy'}
zoomControl= {false}
streetViewControl={false}
fullscreenControl={false}
google={this.props.google}
zoom={5}
style={mapStyles}
initialCenter={{
lat: 21.5937,
lng: 78.9629
}}
>
<MapList google={this.props.google} places={this.props.datapins} onClick={this.onMarkerClick} />
<InfoWindow className="infoWindowCard"
pixelOffset={new this.props.google.maps.Size(185,310)}
marker={this.state.activeMarker}
visible={this.state.showingInfoWindow}
onClose={this.onClose}
// disableAutoPan={true}
>
<div style={{'overflow':'hidden'}}>
{this.state.selectedPlace.owner.image!=='NA'&&this.state.selectedPlace.owner.image!==null?(
<img src={this.state.selectedPlace.owner.image} alt='farmer' className="infoWindowImg"/>
):(
<img src={farmer} alt='farmer' className="infoWindowImg"/>
)}
<h4 className="infoWindowName" style={{'maxWidth': '262px'}}> {this.state.selectedPlace.owner.name} </h4>
<h6 className="infoWindowName"> Customer ID: {this.state.selectedPlace.id} </h6>
<div>
<ul className="infoWindowDetail">
<li>
<div className="row">
<div className="col-md-2">
<i className="fa fa-calendar" aria-hidden="true"></i>
</div>
<div className="col-md-10">
<span>Installed on {this.state.selectedPlace.dateOfInstallation}</span>
</div>
</div>
</li>
<li>
<div className="row">
<div className="col-md-2">
<i className="fa fa-map-marker" aria-hidden="true"></i>
</div>
<div className="col-md-10">
<span>{this.state.selectedPlace.owner.block}</span>
<p>{this.state.selectedPlace.owner.district}, {this.state.selectedPlace.owner.state} </p>
</div>
</div>
</li>
<li>
<div className="row">
<div className="col-md-2">
<i className="fa fa-tint" aria-hidden="true"></i>
</div>
<div className="col-md-10">
{ this.state.selectedPlace.assetType==='IRRIGATION_PUMP' &&
<div>
<span>Irrigation Pump <b>{this.state.selectedPlace.pumpCapacity} {this.state.selectedPlace.powerType} {this.state.selectedPlace.pumpType}</b></span>
<p>Solar Panel Capacity {this.state.selectedPlace.panelRating} </p>
</div>
}
{ this.state.selectedPlace.assetType==='MINIGRID' &&
<span>Minigrid <b>{this.state.selectedPlace.assetName} </b></span>
}
{ this.state.selectedPlace.assetType==='PATVAN' &&
<div>
<span>Patvan <b>{this.state.selectedPlace.pumpCapacity} {this.state.selectedPlace.powerType} {this.state.selectedPlace.pumpType}</b></span>
<p>Solar Panel Capacity {this.state.selectedPlace.panelRating} </p>
</div>
}
{ this.state.selectedPlace.assetType==='DRINKING_WATER_PUMP' &&
<div>
<span>Drinking Water Pump <b>{this.state.selectedPlace.pumpCapacity} {this.state.selectedPlace.powerType} {this.state.selectedPlace.pumpType}</b></span>
<p>Solar Panel Capacity {this.state.selectedPlace.panelRating} </p>
</div>
}
{ this.state.selectedPlace.assetType==='ROOFTOP' &&
<div>
<span>Rooftop</span>
<p>Solar Panel Capacity {this.state.selectedPlace.panelRating} </p>
</div>
}
</div>
</div>
</li>
</ul>
<div className="portal">
<span>Visit portal</span><a target="_blank" rel="noopener noreferrer" href={ "../all_rms/rmspage.html?ID=" + this.state.selectedPlace.id } ><i className="fa fa-external-link-square" aria-hidden="true"></i></a>
</div>
</div>
</div>
</InfoWindow>
</Map>
);
}
}
export default GoogleApiWrapper({
apiKey: 'MYAPI'
})(MapContainer);
I'm trying to build an app that has responsive font sizes based on the screen width with the new material-ui (v1.3). I have a drawer with a menu on it for navigation. I'd like to be able to shrink the font size (among other things on the page), when the screen size is smaller.
I have the following code and it doesn't seem to work when I shrink the screen down manually in the browser. The font size will change but I actually have to refresh the page to see the changes?? With the last version I used, (v.0.13) it would shrink as the screen size was changing, by manually making the browser size smaller with clicking and dragging with mouse and making it smaller. Does anyone have any ideas as to why this is happening?
class App extends Component {
constructor(props) {
super(props);
this.state = {
open: false,
};
}
getDrawerFontSize() {
if (window.innerWidth <= 575) {
return '10px';
} else if (window.innerWidth <= 767) {
return '11px';
} else if (window.innerWidth <= 991) {
return '12px';
} else if (window.innerWidth <= 1199) {
return '13px';
}
return '14px';
}
render() {
const drawerFontSize = this.getDrawerFontSize();
const { open } = this.state;
const theme = createMuiTheme({
overrides: {
MuiDrawer: {
paper: {
background: '#333333',
borderRadius: '0',
width: '250px',
padding: '0 10px',
color: 'white',
marginTop: '80px',
},
paperAnchorDockedLeft: {
borderRight: '0px',
},
},
MuiTypography: {
subheading: {
color: '#999999',
fontSize: drawerFontSize,
},
},
MuiListItemIcon: {
root: {
color: '#999999',
},
},
MuiListItemText: {
root: {
paddingRight: '5px',
paddingLeft: '5px',
}
},
MuiDivider: {
root: {
backgroundColor: '#999999',
},
},
},
});
const styles = {
app: {
backgroundColor: 'black',
},
appBar: {
backgroundColor: '#333333',
},
titleBar: {
backgroundColor: '#111111',
height: '35px',
width: '100%',
},
venn: {
height: '50px',
display: 'inline-block',
verticalAlign: 'middle',
},
logo: {
height: '80px',
width: '80px',
display: 'inline-block',
verticalAlign: 'middle',
},
appHeader: {
backgroundColor: 'black',
height: '150px',
padding: '20px',
color: 'white',
},
menuButton: {
marginLeft: -12,
marginRight: 20,
},
appTitle: {
fontSize: '1.5em',
},
appIntro: {
fontSize: 'large',
},
rightImages: {
marginLeft: 'auto',
marginRight: -12,
},
drawer: {
width: '150',
position: 'relative',
},
title: {
marginRight: '15px',
verticalAlign: 'middle',
display:'inline-block',
},
activeLink: {
textDecoration: 'none',
color: 'white',
}
}
return (
<MuiThemeProvider theme={theme}>
<div style={styles.app}>
<AppBar style={styles.appBar} position="static">
<Toolbar >
<div style={styles.drawerHeader}>
<Typography style={styles.title} variant="display2" color="inherit">
My APP
</Typography>
<img src={venn} style={styles.venn}/>
</div>
<section style={styles.rightImages}>
<img src={logo} style={styles.logo}/>
</section>
</Toolbar>
</AppBar>
<Drawer variant={"permanent"} anchor="left">
<div
tabIndex={0}
role="button" >
<List component="nav">
<NavLink style={styles.activeLink} to="/" href="/">
<ListItem button >
<ListItemIcon>
<HomeIcon />
</ListItemIcon>
<ListItemText primary="Home" />
</ListItem>
</NavLink>
<Link style={styles.activeLink} to="/account" href="/account">
<ListItem button>
<ListItemIcon>
<PersonIcon />
</ListItemIcon>
<ListItemText primary="My Account" />
</ListItem>
</Link>
<Link style={styles.activeLink} to={"/logout"} href="/logout">
<ListItem button>
<ListItemIcon>
<ExitIcon />
</ListItemIcon>
<ListItemText primary="Logout" />
</ListItem>
</Link>
</List>
<Divider />
<List component="nav">
<Link style={styles.activeLink} to={"/help"} href="/help">
<ListItem button>
<ListItemIcon>
<HelpIcon />
</ListItemIcon>
<ListItemText primary="Help" />
</ListItem>
</Link>
</List>
</div>
</Drawer>
<div>
<Router />
</div>
</div>
</MuiThemeProvider>
);
}
}
export default withRouter(connect( mapStateToProps, mapDispatchToProps)(App));
You can make responsive font by multiple way :
1) Using JavaScript :
- Like you can use java script Library (i.e. http://simplefocus.com/flowtype/)
2) Using CSS :
- In place of px use vw or vh -
- 1vw = 1% of viewport width
-1vh = 1% of viewport height
-1vmin = 1vw or 1vh, whichever is smaller
-1vmax = 1vw or 1vh, whichever is larger
OR
You can use Media Query in css
https://www.w3schools.com/css/css_rwd_mediaqueries.asp
Thanks!! Hope it Helps.
See here
I have two sections. I want to drag and drop elements between that two sections, but here's the element is appending but I need to drop the element at the first in that sections. When we drop the element it should place as first element for that section.
this is my code:
class Sections extends React.Component {
constructor(props) {
super(props);
this.state = {
sections: [
{
"idFolder":1,
"idUser":1,
"title":"Your Materials",
"products":[
{ "id":1,
"productType":"textile",
"name":"cotton"
"images":[
{
"original_file_name":"bear.jpeg"
}
]
},
{ "id":3,
"productType":"textile",
"name":"cotton"
}
]
},
{
"idFolder":2,
"idUser":1,
"title":"Your Materials",
"products":[
{ "id":5,
"productType":"textile",
"name":"cotton"
},
{ "id":6,
"productType":"textile",
"name":"cotton"
}
]
}
]
}
};
onDragStart(e){
e.dataTransfer.dropEffect = "copy";
e.dataTransfer.setData( "text", e.target.getAttribute('id'));
}
allowDrop (ev){
ev.preventDefault();
}
onDrop(e){
const data = e.dataTransfer.getData("text");
e.target.appendChild(document.getElementById(data));
}
render(){
return(
<div>
<div className="row">
{
this.state.sections.map((sec_head, index) => {
return (
<div key={index} className="sec_container">
<h4 data-toggle="collapse" data-target={'#'+sec_head.idFolder}>{sec_head.title}</h4>
<ul id="list" className="sec_cont collapse in" id={sec_head.idFolder}
onDrop={this.onDrop}
onDragOver={this.allowDrop}
>
{
sec_head.products.map((product, i) => {
return(
<li
index={i} key={i} className="sec_items col-md-3 alert alert-dismissable"
onDragStart={ (e) => this.onDragStart(e) }
id={product.id} draggable="true"
>
×
<img />
<h5>{product.name}</h5>
</li>
)
})
}
</ul>
</div>
)
})
}
</div>
</div>
)
}
}