How can I use tabs in a modal in react-native - react-native

I have modal for filtering search resluts , something like foursquare app . I have filters in diffrent categories and I need to use tabs for each category . for example when user clicks each tabs it shows the filters related to that tab . and user can select checkboxes or radio buttons . and at the end when user checks all of their needed filters I need to make http request with the new filters.
Something like the image below . I created the modal but I need the functionality for tabs and at the end making the api request with the selected options:

You can also create custom tabs using <Text> with state and depending on a state value render a View associated with that tab. for example
state = {
modalVisible: false,
currentTab: 1,
};
onTabClick = (currentTab) => {
this.setState({
currentTab: currentTab,
});
};
// inside render
<Modal
animationType="slide"
transparent={true}
visible={this.state.modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View style={styles.tabs}>
<Text
onPress={() => {
this.onTabClick(1);
}}
style={[
styles.tabTextStyle,
this.state.currentTab === 1 ? styles.tabUnderline : null,
]}>
GENDER
</Text>
...
</View>
{this.state.currentTab === 1 && (
<View>
<Text>GENDER</Text>
</View>
)}
...
snack example

Modal is just a Container like View. You can draw anything inside it.
First, import {Modal} from 'react-native'
Then, in your modal, embed anything what you want:
<Modal visible={ this.state.modal }
animationType="fade" transparent={true}
onRequestClose={_ => this.setState({ modal: false }) }>
<View>
{/*
Do anything. Its an open ground.
Whatever component, styles, props and/or anything else you want, you can design
*/}
{/* For example, I am adding a close button */}
<TouchableOpacity style={{ alignSelf: 'flex-end' }} onPress={_ => this.setState({ modal: false }) }>
<Icon type="FontAwesome" name='times' style={ styles.closeIcon } />
</TouchableOpacity>
</View>
</Modal>
And you can open your modal from anywhere like:
<TouchableOpacity style={ styles.button } onPress={_ => this.setState({ modal: true }) }>
<Text style={ styles.buttonText }>Open Modal</Text>
</TouchableOpacity>
Finally, for tabs, you can use either of:
NativeBase Tab Component
React Native Tab View

Related

Use Modal in ReactNative

I am making an android app with ReactNative. When a button is clicked, an alert shows up with the result (My code is Alert.alert(''Results:", returnResults(a,b,c)). Is there a way I can use Modal and the function returnResults(a,b,c) with it to show the message in a more customised way?
The problem is that when I use normal alert, the text is different on every device and I want to prevent that.(I want to specify the font, its size etc)
const Modal = () => {
const [modal, setModal] = useState(false);
return (
<View>
<Button title="Open Modal" onPress={() => setModal(true)} />
<Modal
animationType="slide"
transparent={false}
visible={modal}
onRequestClose={() => setModal(false)}
>
<View style={{ marginTop: 22 }}>
<View>
<Text>This is the modal content</Text>
<Button title="Close" onPress={() => setModal(false)} />
</View>
</View>
</Modal>
</View>
);
};
I actually found what i had been looking for. I just had to write the following code:
{returnResults(a,b,c)}

How can I link the button outside flatlit to hide and show the items inside the flatlist in each section react native

I am using flatlist in my app to show the result of the game by using API, I have a button outside the flatlist, I want the user to click the button and by clicking the button toggle switch will appear with each game and a user can switch off to hide the games and switch on to show the games.
First problem how can I link the button with the render function of flatlist to show the toggle switch.
Seconde is that how can I use the toggle switch to show and hide the games in flatlist.
<View style={{flex:1,}}>
<TouchableOpacity onPress={this.renderItem }> // What should I do here?
<Text style={{fontSize:30,color:'blue'}}>show/hide</Text>
</TouchableOpacity>
<DraggableFlatList
data={this.state.dataSource}
onDragEnd={this.dataSource}
renderItem={this.renderItem}
keyExtractor={item => item.GameId.toString()}
ItemSeparatorComponent={this.renderSeprator}
refreshing = {this.state.refreshing}
onRefresh = {this.handleRefresh}
/>
renderItem=({item,navigation,drag,btnvalue1})=>{
const current = new Date();
const currentHour = current.getHours();
return(
<ScaleDecorator>
<TouchableOpacity style={styles.item}
onLongPress={drag}
onPress={
() => this.props.navigation.navigate('ResultsStack',
{ screen: 'Result', params: { resultDate: this.state.resultDate ,GameId: item.GameId } }
//() => this.props.navigation.navigate('ResultsStack', { screen: 'Result' }
)} >
<Image style={styles.img}
source={{
uri: item.ImgUrl,
}}
/>
<Text style={styles.title}>{item.GameDescp} [{item.DrawRef}] [{item.DayName?.slice(0, 3)}]</Text>
<Text style={styles.txt3}>{item.Result03}</Text>
**//On click I want to hide this Ionicon and show a toggle switch**
<Ionicons
name="chevron-forward-outline"
style={styles.iconarrow}
//color={color}
size={30}
></Ionicons>
{this.btnvalue1 === 1 ? (
<Switch
style={styles.iconarrow}
trackColor={{ false: "#767577", true: "#81b0ff" }}
ios_backgroundColor="#3e3e3e"
/>) : null}
</TouchableOpacity>
</ScaleDecorator>

"react-native-loading-spinner-overlay" is not working when modal is open in iOS

"react-native-loading-spinner-overlay" is not working when modal is open in iOS. If I set modal visible to false, it works.
(Android is working well in any case.)
That is my code.
When modal is open, if I click upload button on modal,
_onUpload = () => {
this.setState({ isLoading: true }) //-----> Loading spinner is not working.
}
If I make like this
_onUpload = () => {
this.setState({ modalVisible:false }) //-----> After modal turns off
setTimeout(() => {
this.setState({ isLoading: true }) //----> Loading spinner works.
}, 500);
}
render
render() {
return (
<View>
<Spinner
visible={this.state.isLoading}
textContent={'Loading...'}
textStyle={{ color: 'white' }}
/>
</View>
)
}
I used modal from 'react-native-modal'
import Modal from 'react-native-modal';
<Modal
isVisible={modalVisible}
backdropColor="#B4B3DB"
backdropOpacity={0.8}
animationIn="zoomInDown"
animationOut="zoomOutUp"
animationInTiming={1000}
animationOutTiming={1000}
backdropTransitionInTiming={1000}
backdropTransitionOutTiming={1000}>
<View style={styles.modalBody}>
<TouchableOpacity onPress={() => this._onUpload()} >
<Text>Upload</Text>
</TouchableOpacity>
</View>
</Modal>
Why it is not working on only iOS?
How to make it work on iOS when modal is open?
You cannot use one Modal on another Modal in ios,
you have to close the first Modal before opening a second Modal.
like,
setstate({isLoading:false,modalVisible:true})
or you can use ternary like,
{modalVisible?
<View style={styles.modalBody}>
<TouchableOpacity onPress={() => this._onUpload()} >
<Text>Upload</Text>
</TouchableOpacity>
</View: null}
Add a timeout to wait for the first Modal to close.
setTimeout(() => {
setstate({modalVisible:true})
}, 2000);
Creating your own spinner is the best option I come across for this issue.
{showSpinner && (
<View style={{ ...StyleSheet.absoluteFill, zIndex: 1 }}>
<ActivityIndicator color={Colors.gray900} size="large" style={{ flex: 1, backgroundColor: Colors.gray300, opacity: 0.3 }} />
</View>
)}

Modal doesnt open when clicking on TouchableOpacity - React Native

I am trying to implement the modal component in this app and for some reasons, I cant make it work. I have done it in another app and even though everything looks as it should in this one, it still doesn't work, it just doesn't toggle!
Here is my code (i call toogleModal() here ):
<TouchableOpacity
activeOpacity={1}
style={styles.slideInnerContainer}
//onPress={() => { alert(`You've clicked '${rest_name}'`); }}
onPress={() => this.toggleModal(rest_name)}
>
<View style={styles.shadow} />
<View style={[styles.imageContainer, even ? styles.imageContainerEven : {}]}>
{this.image}
<View style={[styles.radiusMask, even ? styles.radiusMaskEven : {}]} />
</View>
<View style={[styles.textContainer, even ? styles.textContainerEven : {}]}>
<View style={{ flexDirection: 'row' }}>
{uppercaseTitle}
{ratings}
</View>
<Text
style={[styles.subtitle, even ? styles.subtitleEven : {}]}
numberOfLines={2}
>
{rest_location}
</Text>
</View>
</TouchableOpacity>
Now here is the toggleModal() which should set the state and then call the onPressItem() :
toggleModal = (item) => {
this.setState({ isModalVisible: !this.state.isModalVisible });
this.onPressItem(item);
};
and onPressItem() :
onPressItem = (item) => {
return (
<ThemeProvider theme={theme}>
<Modal animationIn="rubberBand" animationOut={"bounceOut"}
isVisible={this.state.isModalVisible}
onBackdropPress={() => this.setState({ isModalVisible: false })}
>
<View style={{ flex: 1 }}>
{item}
</View>
<View style={{ flex: 1 }}>
<Button title="Hide modal" onPress={this.toggleModal} />
</View>
</Modal>
</ThemeProvider>
)
};
Now, remember this code is taken from another app where modal is working perfectly!
Most probably your issue with click option is connected with incorrect import TouchableOpacity from correct module. Check if you are importing from react-native:
import { TouchableOpacity } from 'react-native';
change this line
onPress={() => this.toggleModal(rest_name)}
to this:
onPress={() => {this.toggleModal(rest_name)}}
you only need to put the function call in brackets

Need to double press to release focus on Text Input from within a Modal with KeyboardAvoidingView

I have a Modal wrapping a KeyboardAvoidingView wrapping a few animated components. One of them is a TextInput and the other is a Button. When clicking on the button, keyboard is first hidden, and then need to click once again to reach the buttons "onPress"
Looked into the solution of wrapping the components with a scroll view and using a the prop keyboardShouldPersistTaps={'always'} but that doesn't work.
constructor(props) {
super(props);
this.paddingInput = new Animated.Value(0);
this.state = {
modalVisible: false,
otherTip: '',
}
}
renderHoveringNote = () => {
const {total, currentTipPercent} = this.props.rootStore.orderStore;
return (
<View>
<KeyboardAvoidingView style={{flex: 1}}>
<Animated.View style={{
marginBottom: this.paddingInput,
flex: 1
}}>
<View>
<Text>Enter custom amount</Text>
</View>
<TextInput
onChangeText={value => {
this.setState({otherTip: value})
}}
autoFocus
value={this.state.otherTip}
/>
<Button title='Save'
onPress={()=>{
...do some stuff here
this.setState({modalVisible: false});
Keyboard.dismiss();
}}
</Animated.View>
</KeyboardAvoidingView>
</View>
)
};
renderOtherTipModal = () => {
return (
<Modal
isVisible={this.state.modalVisible}
onBackdropPress{()=>this.setState({modalVisible:false})}
style={{margin: 0, flex: 1}}
hideModalContentWhileAnimating={true}
>
{this.renderHoveringNote()}
</Modal>
)
};
One click should reach the onPress of the button
Figured it out - I had a few Scroll Views as parents to the Modal. It is important to have ALL of the parent Scroll Views to have keyboardShouldPersistTaps={'always'}.
After adding that, it worked great.