In my render function,I make a request,so 'loading' will show when loading.After received the data ,I called 'setState' to make the DOM rerender. I want to show the modal,but the modal do not present. What' wrong with me?
render: function() {
if (!this.props.data) {
return (<View style={{flex:1}}>
<Text>loading</Text>
</View>);
}
return (
<View style={{flex:1, width:screenWidth}}>
<Modal
visible={true}
transparent={true}
onRequestClose={()=>{
}}
onShow={()=>{
}}>
<View
style={{flex:1,justifyContent:'center',alignItems:'center',backgroundColor:'rgba(0, 0, 0, 0.3)'}}>
<View style={{height:200,width:275,backgroundColor:'white'}}>
<Button title='confirm' onPress={()=>{}}/>
<Button title='cancel' onPress={()=>{}}/>
</View>
</View>
</Modal>
</View>
);
}
You can check condition in single return like:
render(){
return(
{(!this.props.data)
? (<View style={{flex:1}}>
<Text>loading</Text>
</View>)
: (<View style={{flex:1, width:screenWidth}}>
<Modal/> { /*your modal code */}
</View>)
}
);
}
First check your modal opens without condition or not, if yes then it is style or re-rending issue.
Related
I have a modal that shown on a button click and the modal is fetched from another component using prop.
In the modal there is a button to close the modal, How to close the modal onclick the button. I have tried but doesn't worked.
//InvalidUser
const InvalidUser = (props) => (
<Modal
visible={props.display}
animationType="slide"
onRequestClose={() => console.log('closed')}
>
<View style={styles.modalBox}>
<View style={{width: 300}}>
<Text style={styles.text}>
{props.data}
</Text>
<TouchableOpacity
onPress={() =>
this.closeModal()
}>
<Text style={styles.buttonOk}>Ok</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
);
//Login
export default class LoginFirst extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
modalVisible: false
};
}
nextBtn = () => {
let reg = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/;
if (this.state.email !== '') {
if (reg.test(this.state.email) === false) {
}
else {
this.setState({modalVisible: true});
}
}
}
render() {
let notRegistered = this.state.email+' is not recognized as a registered user. Please contact us for further assistance.';
return (
<View style={styles.container}>
<ScrollView contentContainerStyle={styles.scroller}>
<View
style={styles.inputSection}
>
<Text style={styles.label}>Email Address:</Text>
<View style={styles.section}>
<Image
style={styles.icon}
source={require('../../../../assets/user.png')}
/>
<TextInput
style={styles.input}
placeholder='johnsmith#gmail.com'
underlineColorAndroid='transparent'
onChangeText={(text) => this.setState({email:text})}
/>
</View>
<TouchableOpacity
style={styles.button}
onPress={() =>
this.nextBtn()
}
>
<Text style={styles.next}>Next</Text>
</TouchableOpacity>
</View>
</ScrollView>
<InvalidUserModal
data={notRegistered}
display={this.state.modalVisible}
/>
</View>
);
}
}
The above code is perfectly displaying the modal, but I cannot close the modal. Is there any way to close.
Please have a look into below image.
from parent component, create closeModal function and pass it to InvalidUserModal
closeModal = () => {
this.setState({modalVisible: false});
}
<InvalidUserModal
data={notRegistered}
display={this.state.modalVisible}
closeModal={this.closeModal}
/>
and call it inside InvalidUserModal on press the button
<TouchableOpacity onPress={props.closeModal}>
<Text style={styles.buttonOk}>Ok</Text>
</TouchableOpacity>
For parent, pass the closeModal method as a props to your component
class LoginFirst extends Component {
closeModal = () => {
this.setState({modalVisible: false});
}
render() {
return (
<InvalidUserModal
data={notRegistered}
display={this.state.modalVisible}
closeModal={this.closeModal}
/>
)
}
}
For your modal component
<Modal
visible={props.display}
animationType="slide"
onRequestClose={() => console.log('closed')}
>
<TouchableOpacity onPress={props.closeModal}>
<Text style={styles.buttonOk}>Ok</Text>
</TouchableOpacity>
</Modal>
I want a RN Modal to pop up on a Dropdown (RN Material Dropdown) onChangeText call. However, even though the this.state.modalVisibleTwo is changed to true through this function, the modal doesn't show up on the state change.
Is there a way to directly trigger the Modal opening.
I attempted conditional rendering based on this.state.modalVisibleTwo with a Modal that's visible={true} and still nothing.
<Modal
animationType='slide'
presentationStyle='overFullScreen'
transparent={true}
visible={this.state.modalVisibleTwo}
ref={component => this.inputModal = component}
onRequestClose={() => {
// console.log('Modal has been closed.');
}}>
<View style={styles.inputContainer}>
<View style={styles.innerContainer}>
<Text style={styles.howMany}>test</Text>
<TextInput
style={styles.textInput2}
underlineColorAndroid={'rgba(0,0,0,0)'}
maxLength={3}
autoCorrect= {false}
clearButtonMode="while-editing"
keyboardType="numbers-and-punctuation"
ref={component => this._textInput2 = component}
onChangeText={(q) => this.setState({currentQuantity: q})}
placeholder= {strings.enter}/>
<View style={{flexDirection: 'row'}}>
<Button
onPress={() => {
this.setModalVisibleTwo(false);
}}>
{strings.close}
</Button>
<TouchableOpacity style={styles.Button2} onPress={()=> {this.addToCart(order, orderNumber, isCartEmpty)}}>
<Text style={styles.addToOrderButtonText2}>{strings.add}</Text>
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
<TouchableWithoutFeedback onPress={()=>Keyboard.dismiss()} accessible={false}>
<View>
<Text style={styles.bodyTitle}>{strings.schedTitle}</Text>
<View style={styles.dropdownContainer}>
<Dropdown
label={strings.select}
data={this.state.services}
itemTextStyle={{fontFamily: 'Heiti TC', }}
containerStyle={styles.dropDown}
baseColor={'#002d62'}
itemColor={'rgba(0, 0, 0, .54)'}
selectedItemColor={'#002d62'}
itemPadding={9}
itemCount={7}
dropdownPosition={-8}
pickerStyle={{width: screenWidth*(3/4), marginLeft: screenWidth*0.032}}
onChangeText={(val)=>{this.updateView(val)}}
/>
<TouchableOpacity style={styles.Button} onPress={()=> {this.addToCart(order, orderNumber, isCartEmpty)}}>
<Text style={styles.addToOrderButtonText}>{strings.ok}</Text>
</TouchableOpacity>
</View>
<TouchableOpacity onPress={()=>{this.setModalVisibleTwo(true)}}>
<Text style={styles.modalTitle1}>{strings.which}</Text>
</TouchableOpacity>
</View>
</TouchableWithoutFeedback>
updateView(val){
//this.inputModal.open();
if(val == strings.dobox || val == strings.pubox){
// How Many Boxes
this.setState({modalVisibleTwo: true, currentService: val, isBox: strings.isBox, updatedDrop: false});
} else if(val == strings.dobar || val == strings.pubar){
// How Many Barrels
this.setState({modalVisibleTwo: true, currentService: val, isBox: strings.isBarrel, updatedDrop: false});
}
else{
// Nothing
this.setState({currentService: val, currentQuantity: '', isBox: '', updatedDrop: false});
}
}
I expect the modal to pop up after a modalVisibleTwo state change to true after onChangeText call in Dropdown, but the actual output is a state change and no modal pop up.
I am trying to render the child component on onPressevent, the console.log works fine but components in the return function doesn't works.
Parent component:
onPress = (img,title,content) => {
this.setState({
show:true,
img:img,
title:title,
content:content
})
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.data}
renderItem={({item}) => (
<TouchableOpacity
onPress={() => this.onPress(item.urlToImage,item.title,item.content)}
>
<View style={styles.picsCont}>
<Image style={styles.pics} source={{uri: item.urlToImage}}/>
<Text style={{color:'white', fontSize: 15, fontWeight: '700', paddingTop:10}}>
{item.title}
</Text>
</View>
</TouchableOpacity>
)}
keyExtractor={item => item.title}
/>
{this.state.show ?
<NewsView
img={this.state.img}
title={this.state.title}
content={this.state.content}
/> :
null
}
</View>
);
}
}
Child Component:
export default class NewsView extends Component {
render() {
console.log(this.props.img)
return (
<View style={styles.container}>
<Image style={styles.picsCont} source={{uri:this.props.img}} />
<Text style={styles.news}>{this.props.title}</Text>
<Text style={styles.news}>{this.props.content}</Text>
</View>
)
}
}
Thanks for the help...!
It might be the styles. If your child component has position:'absolute', it´s probably under your parent component, you can try to put on your child component view zIndex:10
I have problem when trying to submit data from the TextInput component. When trying to press the button that invoke the callback that handle the text, there is a need to press it twice for it to work. Once for the TextInput lose its focus and the second time to invoke the callback.
I tried this solution but it didnt worked for me.
COMPONENT:
<Modal>
<ScrollView>
<Card>
<CardImage source={{uri: this.props.linkImage}}/>
<CardContent/>
</Card>
{
this.state.single.map((comment) => {
return comment[3] ?
<Comp/> : null
})
}
</ScrollView>
<KeyboardAvoidingView behavior="padding" enabled>
<CardAction>
<TouchableOpacity>
<IconFA name="reply"/>
</TouchableOpacity>
<TouchableOpacity>
<IconEn name="thumbs-up"/>
</TouchableOpacity>
<TouchableOpacity>
<IconEn name="thumbs-down"/>
</TouchableOpacity>
</CardAction>
<CardAction>
<TextInput ref={input => this.input = input}/>
<TouchableOpacity>
<IconFA name="rocket"/>
</TouchableOpacity>
</CardAction>
</KeyboardAvoidingView>
</Modal>
Just pass keyboardShouldPersistTaps="always" prop to ScrollView wrapping your component like this:
<ScrollView keyboardShouldPersistTaps="always">
...content
<ScrollView>
I am newbie to react native developing. I want to close the modal component on pressing outside the modal in reactnative. Below is my code.
state = {
visibleModal : false,
};
_hideModal(){
this.setState({
visibleModal: true,
})
}
render(){
return(
<View style={
[styles.container,
{backgroundColor: this.state.visibleModal ? 'rgba(47, 60, 73, 0.75)': 'white'}
]}>
<Text>Text Behind Modal</Text>
{ this._renderButton('BUTTON', () => this.setState({ visibleModal: true}) ) }
<TouchableWithoutFeedback onPress={() => {this._hideModal()}}>
<Modal animationType={"slide"}
transparent={true}
visible={this.state.visibleModal}>
<View style={styles.modalContent}>
<Row />
</View>
</Modal>
</TouchableWithoutFeedback>
</View>
);
}
}
Just add this prop in Modal
onRequestClose={() => { this.visibleModal(false); } }
It will close your modal on pressing back button
<Modal animationType={"slide"}
transparent={true}
visible={this.state.visibleModal}
onRequestClose={() => { this.visibleModal(false); } }
>
EDIT
Above code will work only on Android as per the document.
For both,
You can add custom button to close modal
<TouchableOpacity
onPress={() => {
this.setState({visibleModal: false})
} }>
<Image
style={[styles.modalBackIcon]}
source={require('../../theme/images/back-icon.png')} />
</TouchableOpacity>
<Modal animationType={"slide"}
transparent={true}
visible={this.state.visibleModal}>
<TouchableWithoutFeedback onPress={() => {this.close_modal()}}>
<View style={styles.modalContent}>
....
</View>
</TouchableWithoutFeedback>
</Modal>
this is sample of my code when you tap outside to close your modal
than so close_modal function visibleModal get false value
for exp.
this.setState({ visibleModal: false });
Question :
To close modal when clicking outside the modal.
Solution:
Just remove function call on TouchableWithoutFeedback,it will work..
<TouchableWithoutFeedback onPress={() => {}}>
<Modal animationType={"slide"}
transparent={true}
visible={this.state.visibleModal}>
<View style={styles.modalContent}>
<Row />
</View>
</Modal>
</TouchableWithoutFeedback>