How to enable responsiveness to Plotly-Dash app within an Iframe? - html

I have created a dash app, that is hosted to serve on the Heroku server. The dash app is completely responsive. If I access it on a mobile, iPad, desktop,.. the plot size auto-scales and fits the width of the window. This is perfect. However, embedding this dash app URL in an iframe of my website, the plot's responsiveness is lost. It does not autoscale to fit the width of the iframe.
How to ensure that the iframe and the plot responsively auto-scales to fit the width of the window?
My dash app: https://isb-hpi.herokuapp.com/
My iframe code:
<div class="iframe-container">
<iframe class="responsive-iframe" src="https://isb-hpi.herokuapp.com/"></iframe>
</div>
My CSS:
.iframe-container {
position: relative;
overflow: hidden;
width: 100%;
padding-top: 45%;
}
.responsive-iframe {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
}
code to construct plot:
from warnings import showwarning
import pandas as pd
import numpy as np
import os
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
config = {'responsive': True}
figq1 = px.line(dfq1, x="month", y="final_Index", color="Bedroom",template='presentation', line_shape='spline', labels={"Bedroom": "Type"}, category_orders={"Bedroom":['1bhk', '2bhk', '3bhk']})
figq1.update_traces(line=dict(width=1))
figq1.add_trace(
go.Scatter(
x=dfqa1.month,
y=dfqa1.final_Index,
mode="lines",
line=go.scatter.Line(color="gray", width=2),
showlegend=True, name='all')
)
figq1.update_layout(width=750,height=500, autosize=True)
figq1.update_layout(
xaxis=dict(
rangeslider=dict(
visible=True,
thickness=.05
),
type="date"
)
)
figq1.update_layout(
xaxis_title="Time", yaxis_title="final_Index",legend_title="",
font=dict(
family="Courier New, monospace",
size=11,
color="RebeccaPurple"
), legend=dict(
orientation="h",
yanchor="bottom",
y=1.05,
xanchor="right",
x=1
)
)
figq1.update_yaxes(
title=' '
)
figq1.layout.legend.itemsizing = 'constant'
figq1.layout._config= config
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
server=app.server
app.css.append_css({
'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css'
})
server=app.server
tabs_styles = {'zIndex': 99, 'display': 'inlineBlock', 'height': '4vh', 'width': '12vw',
'position': 'fixed', "background": "#323130", 'top': '12.5vh', 'left': '7.5vw',
'border': 'grey', 'border-radius': '4px'}
tab_style = {
"background": "#323130",
'text-transform': 'uppercase',
'color': 'white',
'border': '#A9A9A9',
'font-size': '9px',
'font-weight': 600,
'align-items': 'center',
'justify-content': 'center',
'border-radius': '4px',
'padding':'6px'
}
tab_selected_style = {
"background": "#A9A9A9",
'text-transform': 'uppercase',
'color': 'white',
'font-size': '9px',
'font-weight': 600,
'align-items': 'center',
'justify-content': 'center',
'border-radius': '4px',
'padding':'6px'
}
app.layout = html.Div([
dcc.Tabs(id='tabs-example', value='tab-1', children=[
dcc.Tab(label='India', value='tab-1',style=tab_style, selected_style=tab_selected_style),
html.Div(id='tabs-example-content')
])
#app.callback(Output('tabs-example-content', 'children'),
Input('tabs-example', 'value'))
def render_content(tab):
if tab == 'tab-1':
return html.Div([
html.Div([
html.Div([
dcc.Graph(id='g2', figure=figq1)
], className="row", style={
'width': 750,
"display": "block",
"margin-left": "auto",
"margin-right": "auto",
}),
], className="row")
])
if __name__ == '__main__':
app.run_server(debug=True, use_reloader=False)
Edit:

When building dash apps with responsive layouts,
always use:
config = {'responsive': True}
autosize=True
Never set the width and height explicitly as you can see in my code to construct the plot.

Related

"temporary" variant not showing in Drawer component Material-ui

I am trying to make the drawer component on material-ui a responsive drawer, by making it to be toggled open and close on smaller screens and permanent on desktop
I followed the documentation on mui, which says to add the temporary variant to the drawer, however it doesn't show up at all on desktop mode
Below is my drawer component
import React from "react";
import ReactDOM from "react-dom";
import { useHistory } from "react-router-dom";
import { makeStyles, Typography, Drawer, Toolbar, Divider, List, ListItem, ListItemText, ListItemIcon, Container, Box } from "#material-ui/core";
import HomeOutlinedIcon from '#material-ui/icons/HomeOutlined';
import AlternateEmailOutlinedIcon from '#material-ui/icons/AlternateEmailOutlined';
import NotificationsNoneOutlinedIcon from '#material-ui/icons/NotificationsNoneOutlined';
import DashboardOutlinedIcon from '#material-ui/icons/DashboardOutlined';
import ArchiveOutlinedIcon from '#material-ui/icons/ArchiveOutlined';
const drawerWidth = 280
const useStyles = makeStyles((theme) => ({
drawer : {
width: drawerWidth,
},
drawerPaper : {
width: drawerWidth,
},
list : {
marginLeft: '24px',
marginRight: '24px'
},
listItem : {
padding: '8px',
borderRadius: '5px',
},
text : {
color: theme.palette.primary.light,
fontWeight: '500',
lineHeight: '2000'
},
title : {
color: theme.palette.primary.light,
textAlign: 'center',
display: 'block',
fontWeight: '500',
fontSize: '20px',
marginTop: '10px',
marginBottom: '10px'
}
}));
export default function LeftBar(){
const classes = useStyles();
const [mobileOpen, setMobileOpen] = React.useState(false);
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
const list = [
{
text : 'Home',
icon : <HomeOutlinedIcon />,
path : '/'
},
{
text : 'Personal',
icon : <AlternateEmailOutlinedIcon />,
path : '/'
},
{
text : 'Notificatons',
icon : <NotificationsNoneOutlinedIcon />,
path : '/'
},
{
text : 'Dashboard',
icon : <DashboardOutlinedIcon />,
path : '/'
},
{
text : 'Archives',
icon : <ArchiveOutlinedIcon />,
path : '/'
}
];
return (
<Box>
<Drawer
className={classes.drawer}
anchor="left" classes={{
paper: classes.drawerPaper
}}
open={mobileOpen}
onClose={handleDrawerToggle}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
sx={{
display: { xs: 'block', sm: 'none' },
flexShrink: 0,
'& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth },
}}
>
<Toolbar />
<Container>
<Typography variant="h5" component="h2" className={classes.title} gutterBottom>
My Account
</Typography>
</Container>
<Divider />
<List className={classes.list}>
{ list.map((item) => (
<ListItem key={item.text} className={classes.listItem} button>
<ListItemIcon className={classes.icon}>
{item.icon}
</ListItemIcon>
<ListItemText sx={{color: 'primary'}} primary={item.text} className={classes.text}/>
</ListItem>
))}
</List>
</Drawer>
</Box>
);
};
You have only included the drawer for xs - with display: { xs: 'block', sm: 'none' } that drawer will not display for any size but xs. You will need another drawer for sm and up. The MUI docs show a second drawer like this:
<Drawer
variant="permanent"
sx={{
display: { xs: 'none', sm: 'block' },
'& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth },
}}
open
>
{you would put your list stuff here}
</Drawer>
You will probably need to move the Toolbar component outside of the Drawer component.

expo - react native - webview - html5 - obeject tag - issue

I tried to use Expo - Webview to display an HTML5 content(.html) using <object> but it does not work.
The same html5 content is working perfectly in a regular webpage.
Can somebody guide with a simple example to achieve the above mentioned scenario ?
Here is the code,
I tried both react-native-render-html and webview, nothing works.
import React, { Component } from 'react';
import { withNavigation } from '#react-navigation/compat';
import { StyleSheet, Dimensions, Image, TouchableWithoutFeedback,ScrollView } from 'react-native';
import { Block, Text, theme } from 'galio-framework';
import HTML from 'react-native-render-html';
import Constants from 'expo-constants';
import materialTheme from '../constants/Theme';
import { heightPercentageToDP } from 'react-native-responsive-screen';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
import {WebView} from 'react-native-webview';
import { Video } from 'expo-av';
class CourseDetail extends React.Component {
render() {
const imageStyles = [styles.image, styles.normalImage];
const {navigation,route}= this.props;
const Course = route.params.course;
const imageUrl = route.params.imageUrl;
const videoUrl = route.params.videoUrl;
return (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.catalogItems}>
<Block flex style={[styles.article]}>
<Text size={30} style={styles.CourseTitle}>{Course.Title}</Text>
<HTML containerStyle={styles.courseWrap } html={ '<object type="text/html" data="https://domainname.com/story_html5.html" ></object>'} />
<WebView source={{ uri: 'https://domainname.com/story_html5.html' }} />
</Block>
</ScrollView>
);
}
}
export default withNavigation(CourseDetail);
const styles = StyleSheet.create({
article:{
backgroundColor: theme.COLORS.WHITE,
padding:hp('3%')
},
content: {
flex:1,
},
CourseTitle:{
flex: 1,
flexWrap: 'wrap',
paddingBottom: 10,
paddingTop:5,
fontFamily:'manifa-regular',
color:'#333333',
},
imageContainer: {
elevation: 1,
},
shadow: {
shadowColor: 'rgba(0,51,160,0.15)',
shadowOffset: { width: 0, height: 5 },
shadowRadius:15,
shadowOpacity: 1,
elevation:15,
},
image: {
borderRadius: 3,
marginHorizontal: wp('1%'),
marginTop: hp('5%'),
backgroundColor:'#84BD00',
},
normalImage: {
height:hp('25%'),
width:'auto',
// / marginTop:hp('3.3%'),
marginHorizontal: 0,
marginRight: wp('0%'),
marginLeft:wp('0%'),
marginTop:hp('3 %'),
marginBottom:hp('1%'),
flex: 1,
flexDirection: 'row',
padding:0
},
courseWrap:
{
marginVertical:10,
width:'100%',
height:hp('50%'),
backgroundColor:'red'
},
description:
{
marginTop:10
}
});

React-simple-map "Unexpected token < in JSON at position 0"

I would like to use react-simple-map for my project in react.
I used the example on github to try to display a simple map :
import React, { Component } from "react"
import {
ComposableMap,
ZoomableGroup,
Geographies,
Geography,
} from "react-simple-maps"
const wrapperStyles = {
width: "100%",
maxWidth: 980,
margin: "0 auto",
}
class BasicMap extends Component {
render() {
return (
<div style={wrapperStyles}>
<ComposableMap
projectionConfig={{
scale: 205,
rotation: [-11,0,0],
}}
width={980}
height={551}
style={{
width: "100%",
height: "auto",
}}
>
<ZoomableGroup center={[0,20]} disablePanning>
<Geographies geography="/static/world-50m.json">
{(geographies, projection) => geographies.map((geography, i) => geography.id !== "ATA" && (
<Geography
key={i}
geography={geography}
projection={projection}
style={{
default: {
fill: "#ECEFF1",
stroke: "#607D8B",
strokeWidth: 0.75,
outline: "none",
},
hover: {
fill: "#607D8B",
stroke: "#607D8B",
strokeWidth: 0.75,
outline: "none",
},
pressed: {
fill: "#FF5722",
stroke: "#607D8B",
strokeWidth: 0.75,
outline: "none",
},
}}
/>
))}
</Geographies>
</ZoomableGroup>
</ComposableMap>
</div>
)
}
}
export default BasicMap
But, I have the error message "Unexpected token < in JSON at position 0" in the console. I kept exactly the same folders. The only error message is this.
If you have an idea about a map in react, with which i would be able to color each country with different color depending on certains criteria...
Thank you in advance.
I faced same problem. If you place world-50m.json inside src folder, react cannot load it with get request - it tries to load it from http://localhost:3000/static/world-50m.json. In my case it returns custom 404 HTML page -> and that is why error "Unexpected token < in JSON at position 0" occurs.
Solution is to move json with map inside react public folder and than it starts to work.

React Native: How to use Webview to read video post from Wordpress?

I am quite new in react native. I am using expo and trying to read data from WordPress. But the problem appeared when the post contains a video.
The video is running well but the video size showed inside the is bigger than the screen size.
I have tried scalesPageToFit={true}. However, it did not work for me.
Is there any way to solve this issue?
const styles = {
featuredImage: {
backgroundColor: 'black',
width: window.width,
height: 200
},
title: {
fontFamily: 'roboto-slab-regular',
fontSize: 20,
lineHeight: 22,
marginTop: 16,
marginHorizontal: 16
},
content: {
flex: 1,
height: 400,
alignItems: 'center'
},
meta: {
marginTop: 16,
marginHorizontal: 16,
}
}
export default class Post extends Component {
webview = null;
constructor(props) {
super(props);
this.state = {
tamanho: 122,
post: props.post,
scalesPageToFit: true,
};
}
_postMessage = ( ) => {
this.webview.postMessage( "Hello" );
console.log( "Posted message" );
scalesPageToFit=true
}
_receivedMessage = ( e ) => {
console.log("Received message");
this.setState( { tamanho: parseInt(e.nativeEvent.data)} );
scalesPageToFit=true
}
componentDidMount() {
this._postMessage();
}
render() {
let post = this.state.post;
let HTML ='<html>' +
'<head>' +
'<title></title>' +
'</head>' +
'<body>' +
post.content.rendered +
'</body>' +
'</html>';
let javascript = 'window.location.hash = 1;' +
'document.title = document.body.scrollHeight;' +
'window.postMessage( document.body.scrollHeight );';
return (
<View>
<PostImage post={post} style={styles.featuredImage} showEmpty />
<Text style={styles.title}>{entities.decode(post.title.rendered)}</Text>
<PostMeta style={styles.meta} post={post} />
<WebView
scrollEnabled={false}
ref={webview => { this.webview = webview; }}
injectedJavaScript={javascript}
javaScriptEnabled={true}
javaScriptEnabledAndroid={true}
onMessage={this._receivedMessage}
scalesPageToFit={true}
allowsInlineMediaPlayback={true}
decelerationRate="normal"
style={styles.content}
automaticallyAdjustContentInsets={false}
domStorageEnabled={true}
startInLoadingState={true}
source={{html: HTML}}
/>
</View>
);
}
}
Add the width property to fit the webview to device's screen to the styles in your react-native project.
import { Dimensions } from 'react-native';
const deviceWidth = Dimensions.get('window').width;
Add this below snippet in styles
content: {
flex: 1,
backgroundColor: 'yellow',
width: deviceWidth,
height: 400//deviceHeight
}

How to get the address from google maps autocomplete in React Native

I am using react-native-google-places-autocomplete to select a location. I want to extract the location selected and use it in other component.
How can I save the address
This is my code
import React, {Component} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
const homePlace = { description: 'Home', geometry: { location: { lat: 48.8152937, lng: 2.4597668 } }};
const workPlace = { description: 'Work', geometry: { location: { lat: 48.8496818, lng: 2.2940881 } }};
export default class google extends Component {
render(){
return (
<View style={styles.container}>
<View style={styles.top}>
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={false}
returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
listViewDisplayed='auto' // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description} // custom description render
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);
this.setState(
{
address: data.description, // selected address
coordinates: `${details.geometry.location.lat},${details.geometry.location.lng}` // selected coordinates
}
);
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaS#################',
language: 'es', // language of the results
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
}}
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: 'distance',
types: 'food'
}}
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
predefinedPlaces={[homePlace, workPlace]}
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
renderRightButton={() => <Text>Custom text after the input</Text>}
/>
</View>
<View style={styles.container2}>
<Text>
hola {this.setState.address}
</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
width: '100%',
height: '100%',
},
welcome: {
fontSize: 40,
textAlign: 'center',
margin: 10,
color:'black',
},
instructions: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
},
top: {
height: '50%',
justifyContent: 'center',
alignItems: 'center',
},
container2: {
height:'75%',
justifyContent: 'center',
},
buttonContainer: {
alignItems: 'center',
backgroundColor: 'rgba(255, 255,255, 0.5)',
padding: 1,
margin: 50,
borderRadius: 25,
borderWidth: 2,
borderColor: '#0B0B3B'
},
textoboton: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
fontSize: 12
},
})
I've been also using another library with some differences
app.js
import React,{Component} from 'react';
import { Constants } from 'expo';
import Icon from 'react-native-vector-icons/FontAwesome';
import { View, Image, Text, StyleSheet, AsyncStorage, Button,ScrollView, TextInput, ActivityIndicator } from 'react-native';
import {
NavigationActions
} from 'react-navigation';
import { GoogleAutoComplete } from 'react-native-google-autocomplete';
import {Card, Input} from "react-native-elements";
import LocationItem from './locationItem';
export default class App extends React.Component {
state={
datos:[],
}
componentDidMount(){
this._loadedinitialstate().done();
}
_loadedinitialstate =async() => {
AsyncStorage.getItem('datos');
}
render() {
return (
<View style={styles.container}>
<GoogleAutoComplete apiKey={'AIzaSyB2HyNTBm1sQJYJkwOOUA1LXRHAKh4gmjU'} debounce={20} minLength={2} getDefaultValue={() => ''} onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);}} returnKeyType={'default'} fetchDetails={true}
>
{({
locationResults,
isSearching,
clearSearchs,
datos,
handleTextChange
}) => (
<React.Fragment>
<View style={styles.inputWrapper}>
<Input
style={styles.textInput}
placeholder="Ingresa tu direccion"
onChangeText={(datos) => this.setState({datos})}
value={datos}
/>
</View>
{isSearching && <ActivityIndicator size="large" color="red" />}
<ScrollView>
{locationResults.map(el => (
<LocationItem
{...el}
key={el.id}
/>
))}
</ScrollView>
</React.Fragment>
)}
</GoogleAutoComplete>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
textInput: {
height: 40,
width: 300,
borderWidth: 1,
paddingHorizontal: 16,
},
inputWrapper: {
marginTop: 80,
flexDirection: 'row'
},
});
locationitem.js
import React, { PureComponent } from 'react';
import { View, Alert, Text, StyleSheet, TouchableOpacity, AsyncStorage} from 'react-native';
class LocationItem extends PureComponent {
constructor(props) {
super(props);
this.state = {datos:''};
}
_handlePress = () => {
AsyncStorage.setItem('datos',datos)
}
render() {
return (
<TouchableOpacity style={styles.root} onPress={this._handlePress} >
<Text value={this.state.datos}> {this.props.description} </Text>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
root: {
height: 40,
borderBottomWidth: StyleSheet.hairlineWidth,
justifyContent: 'center'
}
})
export default LocationItem;
The source of both codes is here react-native-google-places-autocomplete enter link description here
Which code will be easy to use, and How can I solve my Issue (get the address) ??
Any Answer will be Helpful
first install
npm i react-native-google-places-autocomplete
then
import React from 'react';
import { View, Image } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
const homePlace = { description: 'Home', geometry: { location: { lat: 48.8152937, lng: 2.4597668 } }};
const workPlace = { description: 'Work', geometry: { location: { lat: 48.8496818, lng: 2.2940881 } }};
const GooglePlacesInput = () => {
return (
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={false}
returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
listViewDisplayed='auto' // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description} // custom description render
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'YOUR API KEY',
language: 'en', // language of the results
types: '(cities)' // default: 'geocode'
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
}}
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: 'distance',
types: 'food'
}}
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
predefinedPlaces={[homePlace, workPlace]}
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
renderLeftButton={() => <Image source={require('path/custom/left-icon')} />}
renderRightButton={() => <Text>Custom text after the input</Text>}
/>
);
}
After a long journey, these steps helped me solve the problem.
1) Install npm install react-native-google-places-autocomplete --save.
2) Then use this code below, as an element in your component.
<GooglePlacesAutocomplete
query={{
key: "GOOGLE_PLACES_API_KEY",
language: "en", // language of the results
}}
onPress={(data, details = null) => {
console.log(details);
console.log(data);
console.log("data.description",data.description.split(','));
}}
onFail={(error) => console.error(error)}
listViewDisplayed="false"
requestUrl={{
url:
"https://cors-
anywhere.herokuapp.com/https://maps.googleapis.com/maps/api",
useOnPlatform: "web",
}} // this in only required for use on the web. See https://git.io/JflFv
more for details.
styles={{
textInputContainer: {
backgroundColor: "rgba(0,0,0,0)",
borderTopWidth: 0,
borderBottomWidth: 0,
},
textInput: {
marginLeft: 0,
marginRight: 0,
height: 38,
color: "#5d5d5d",
fontSize: 16,
},
predefinedPlacesDescription: {
color: "#1faadb",
},
}}
/>
3) You may have the same problem that i had, which the list disappears when i try to select result. However, this is the action that solved this problem for me.
Commenting out onBlur on node_modules. path: "..\node_modules\react-native-google-places-autocomplete\GooglePlacesAutocomplete.js".
...
onFocus={onFocus ? () => {this._onFocus(); onFocus()} : this._onFocus}
// onBlur={this._onBlur}
underlineColorAndroid={this.props.underlineColorAndroid}
...
4) For saving the address you can check the console.log in the code, and then use setState or something like this.
5) For more information and options of these element check out this repository:
https://github.com/FaridSafi/react-native-google-places-autocomplete.
hope this will help for you :)
First of all, I used listViewDisplayed={false} because otherwise the list view get stuck with the results, and even on location press the list doesn't closes.
Second, to answer your question: The results are in the onPress function of GooglePlacesAutocomplete, you can update the state with the chosen location and then use it where ever you want in your component:
onPress={(data, details = null) => {
this.setState({
latitude: details.geometry.location.lat,
longitude: details.geometry.location.lng,
moveToUserLocation: true
});
this._gotoLocation();
}
}
As i wrote it, onPress also trigger the function that moves the map to display the new location.
import React, {Component} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
export default class google extends Component {
constructor(props) {
super(props);
this.state = {
address:null,
lat:null,
lng:null,
}
}
getAdd(data){
console.log("add",data);
this.setState(
{
address: data.formatted_address, // selected address
lat: data.geometry.location.lat,// selected coordinates latitude
lng:data.geometry.location.lng, // selected coordinates longitute
}
);
console.log("this.state.address",this.state.address); ///to console address
console.log("this.state.coordinates",this.state.lat,this.state.lng); /// to console coordinates
}
render(){
return (
<View style={styles.container}>
<View style={styles.top}>
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={false}
fetchDetails={true}
returnKeyType={'default'}
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
var data = details;
this.getAdd(data);
}}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaS#################',
language: 'en',
types: 'geocode', // default: 'geocode'
}}
listViewDisplayed={this.state.showPlacesList}
textInputProps={{
onFocus: () => this.setState({ showPlacesList: true }),
onBlur: () => this.setState({ showPlacesList: false }),
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
// predefinedPlaces={[]}
predefinedPlacesAlwaysVisible={true}
/>
</View>
{ this.state.address !=null ?(
<View style={styles.container2}>
<Text>
Address: {this.state.address}
</Text>
</View>
):null }
</View>
);
}
}
const styles = StyleSheet.create({
container: {
width: '100%',
height: '100%',
},
welcome: {
fontSize: 40,
textAlign: 'center',
margin: 10,
color:'black',
},
instructions: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
},
top: {
height: '50%',
justifyContent: 'center',
alignItems: 'center',
},
container2: {
height:'75%',
justifyContent: 'center',
},
buttonContainer: {
alignItems: 'center',
backgroundColor: 'rgba(255, 255,255, 0.5)',
padding: 1,
margin: 50,
borderRadius: 25,
borderWidth: 2,
borderColor: '#0B0B3B'
},
textoboton: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
fontSize: 12
},
})