Modal doesnt open when clicking on TouchableOpacity - React Native - 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

Related

How to show an icon on last index of flat list

I'm trying to wrap my flat list and trying to show an Icon after last index of Flatlist. I had tried but it works fine on a single row. when we data goes to next row it would not work.
Here is my flat list code. Modal and Input both are my custom component.
const renderItem = ({item}) => {
return (
<TouchableOpacity style={[styles.tagPostContainer, styles.viewTagContainer]}>
<AppText
type={'input'}
label={`#${item}`}
color={colors.placeholder}
containerStyle={[styles.tagPostInactiveTxt, styles.BgAddedTag]}
/>
</TouchableOpacity>
);
};
return(
<>
<View style={{flexDirection:'row',justifyContent:'flex-start'}}>
<FlatList
data={tags}
renderItem={renderItem}
keyExtractor={keyExtractor}
contentContainerStyle={styles.TagFlatlist}
/>
<TouchableOpacity
style={styles.plusIconContainer}
onPress={() => setVisible(true)}>
<CreateBuildIconFocus height={13} width={13} />
</TouchableOpacity>
</View>
<Modal
visible={visible}
buttonLabel={'Done'}
containerWidth={width / 1.7}
onCancel={onCancel}
onSubmit={onClick}
containerHeight={Platform.OS === 'android' ? 200 : 200}>
<Input
placeholder={'Add Tags'}
autoFocus={true}
minWidth={120}
maxWidth={150}
value={tag}
onChangeText={text => setTag(text)}
/>
</Modal>
</>
)
FlatList styles:
TagFlatlist: {
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'center',
},
Here is my design screen.
I find a solution for this. You can implement ListFooterComponent that used for showing something on end of flatlist. Here you can see more details of ListFooterComponent.
Here are the code of Flatlist.
return(
<FlatList
data={tags}
renderItem={renderItem}
keyExtractor={keyExtractor}
ListFooterComponent={
<TouchableOpacity
style={styles.plusIconContainer}
onPress={() => setVisible(true)}>
<CreateBuildIconFocus height={13} width={13} />
</TouchableOpacity>
}
contentContainerStyle={styles.TagFlatlist}
/>
)

Keyboard won't dismiss?

I have a notes input that is multilined. Currently when I press return it goes to the next line and when I tap on a part of the screen that isn't a keyboard nothing happens. So it's just stuck right now and i have to reload the app. I have tried the keyboard dismissal and it still isn't working. This is a child component so maybe that is the issue?
My code:
render() {
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss()}> //also tried () => Keyboard.dismiss()
<Modal transparent animationType='fade' visible={this.props.createHomeworkModalVisible}>
<View style={styles.containerStyle}>
<View style={styles.modalContainer}>
<Formik
initialValues={{
assignmentName: '',
dueDate: null,
notes: '',
pictures: []
}}
validationSchema={validationSchema}
onSubmit={(values) => {
console.log(values);
}}
>
{formikProps => (
<View>
<View style={{ padding: 5 }}>
<TextInput
placeholder={'Add notes'}
placeholderTextColor='#cdd2c9'
value={formikProps.values.notes}
multiline
style={styles.notesInput}
onChangeText={formikProps.handleChange('notes')}
onBlur={formikProps.handleBlur('notes')}
/>
</View>
</View>
)}
</Formik>
</View>
</View>
</Modal>
</TouchableWithoutFeedback>
);
}
}
You can try something like,
import {Keyboard} from 'react-native'
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View>
<View style={{ padding: 5 }}>
<TextInput
placeholder={'Add notes'}
placeholderTextColor='#cdd2c9'
value={formikProps.values.notes}
multiline
style={styles.notesInput}
onChangeText={formikProps.handleChange('notes')}
onBlur={formikProps.handleBlur('notes')}
/>
</View>
</View>
</TouchableWithoutFeedback>
hope it helps. feel free for doubts
import Keyboard from 'react-native'
Call this function : Keyboard.dismiss()

TouchableOpacity is not working properly with navigation

I put TouchableOpacity for onPress because View can not make it. When i gave TouchableOpacity onPress with navigation it stopped working. Why is not working? Help me please.
Code:
<TouchableOpacity style={{flex:2}}
activeOpacity={.7}
onPress={() => navigate('Articles', {
otherParam: rowData.article_title
})}>
<Image
source = {{ uri: rowData.mobile_image }}
style={{resizeMode:'cover',width:null,height:null, flex:1, borderRadius:4,
borderWidth:1,
borderColor:'#dddddd'}}
/>
<Text
style={styles.textOfArticle}
>
{rowData.article_title}
</Text>
</TouchableOpacity>
Firstly, TouchableOpacity must have only one child component. You are adding Image and Text components separately. They must be wrapped in a View.
Change it like this,
<TouchableOpacity style={{flex:2}}
activeOpacity={.7}
onPress={() => navigate('Articles', {
otherParam: rowData.article_title
})}>
<View>
<Image
source = {{ uri: rowData.mobile_image }}
style={{resizeMode:'cover',width:null,height:null, flex:1, borderRadius:4,
borderWidth:1,
borderColor:'#dddddd'}}
/>
<Text
style={styles.textOfArticle}
>
{rowData.article_title}
</Text>
</View>
</TouchableOpacity>

How to create custom tabs in the centre of the screen in React Native

I am doing react native application. In that, One screen have custom tabs in centre of the screen.
My screen is like,
top view around 200px height with some text lines showing.
After that, Custom tabs as picture attached.
After that, I am showing for first tab on tap flat list data.
I have checked online forums and tutorials, According to tab bar, We can show either top or bottom screen with tabs.
But, How to show tabs with customisation like my requirement.
I have 4 tabs, and each tab has same top view which I mentioned in above (some text lines), And if I tap on each tab, different data bottom page should show.
Like,
First tab with some flat list,
second tab with some text lines,
likewise all tabs has different layout in bottom screen.
As I am very new to react native. How to achieve this?
Due to privacy policy, I am unable to post complete screenshot.
Here is my code.
Screen.js
onClickTelugu = () => {
alert("you clicked onClickTelugu")
}
onClickTamil = () => {
alert("you clicked onClickTamil")
}
onClickHindi = () => {
alert("you clicked onClickHindi")
}
onClickEnglish = () => {
alert("you clicked onClickEnglish");
}
render(item) {
return (
<View style={styles.container}>
<View style ={styles.Container}>
<Text style={styles.textStyle}>
Some Text
</Text>
<View style={styles.somestyles}>
<TouchableOpacity onPress={this.onClick}>
<Image
style={styles.somestyles}
source={MenuImage}
/>
</TouchableOpacity>
<TouchableOpacity onPress={this.onClick}>
<Image
style={styles.menuIcon}
source={MenuImage}
/>
</TouchableOpacity>
</View>
</View>
<View style ={styles.somestyles}>
<View style={styles.somestyles}>
<Text style= {styles.somestyles}>
Some Text
</Text>
<Text style= {styles.somestyles}>
Some Text
</Text>
<Text style= {styles.somestyles} >
<Text style= {styles.somestyles}>
Some Text
</Text>
<Text style ={styles.somestyles}>
Some Text
</Text>
</Text>
</View>
<View style={styles.somestyles}>
<Text style={styles.somestyles}>some text</Text>
<Text style={styles.somestyles} >some text</Text>
<Text style={styles.somestyles}>date</Text>
<Text style={styles.somestyles}>some other date</Text>
</View>
</View>
</View>
<View style = {styles.tabContainer}>
<View style ={styles.tabInnerContainer}>
<TouchableOpacity style={styles.tabIcons} onPress={this.onClickTelugu}>
<Image
style={styles.tabItemsImages}
source={image}
/>
</TouchableOpacity>
<Text style={styles.tabTextItems} onPress={this.onClickTelugu}>Telugu</Text>
</View>
<View style={styles.tabInnerContainer}>
<TouchableOpacity style={styles.tabIcons} onPress={this.onClickTamil}>
<Image
style={styles.tabItemsImages}
source={image}
/>
</TouchableOpacity>
<Text style={styles.tabTextItems} onPress={this.onClickTamil}>Tamil</Text>
</View>
<View style={styles.tabInnerContainer}>
<TouchableOpacity style={styles.tabIcons} onPress={this.onClickHindi}>
<Image
style={styles.tabItemsImages}
source={image}
/>
</TouchableOpacity>
<Text style={styles.tabTextItems} onPress={this.onClickHindi}>Hindi</Text>
</View>
<View style={styles.tabInnerContainer}>
<TouchableOpacity style={styles.tabIcons} onPress={this.onClicEnglish}>
<Image
style={styles.tabItemsImages}
source={image}
/>
</TouchableOpacity>
<Text style={styles.tabTextItems} onPress={this.onClicEnglish}>English</Text>
</View>
</View>
<View style = {styles.flatListContainer}>
<FlatList style = {styles.flatList}
showsVerticalScrollIndicator = {true}
data = {this.state.dataArray}
renderItem = {({item}) => (
<TouchableWithoutFeedback onPress={ () => this.flatListItemHandler(item)}>
<Image
style={styles.flatListArrowImage}
source={image}
/>
</View>
<View style={styles.flatListItemInsideSeparator}>
)
}
ItemSeparatorComponent = {() => (
<View style={{height:15, backgroundColor:'#F8F8F8'}}/>
)}
/>
</View>
</View>
);
}
}
And I have to show overlay tab images too. If 1st tab tapped, 2,3,4
tabs images should be like delighted images. Like
highlighted/delighted images.
Ok you need to give this component it's own state to keep track of what you want to show in the lower section. then you should replace all of your onClick events with just one onClick event that you pass different languages to. For Example this.onClickTelugu becomes () => this.onClick('telugu'), then your onClick event should be:
onClick = (language) => {
this.setState({selectedLanguage: language})
}
then in your renderBottomContent function, you can render different things depending on what this.state.selectedLanguage is.
something like...
class MyComponent extends Component {
constructor(props) {
super(props)
this.state = { selectedLanguage: null}
}
onClick = (language) => {
this.setState({selectedLanguage: language})
}
renderBottomContent = () => {
const {selectedLanguge} = this.state
switch(selectedLanguage) {
case "telugu":
return <View><Text>Telugu</Text></View>
case "tamil":
return <View><Text>Tamil</Text></View>
case "hindi":
return <View><Text>Hindi</Text></View>
case "english":
return <View><Text>English</Text></View>
default:
return <View><Text>No Language Selected...</Text></View>
}
}
render() {
...
<View style ={styles.tabInnerContainer}>
<TouchableOpacity style={styles.tabIcons} onPress={() => this.onClick('telugu')}>
<Image style={styles.tabItemsImages} source={image} />
<Text style={styles.tabTextItems}>
Telugu
</Text>
</TouchableOpacity>
</View>
<View style ={styles.tabInnerContainer}>
<TouchableOpacity style={styles.tabIcons} onPress={() => this.onClick('tamil')}>
<Image style={styles.tabItemsImages} source={image} />
<Text style={styles.tabTextItems}>
Tamil
</Text>
</TouchableOpacity>
</View>
...
// after all the other tab buttons, render bottom content depending on the component state
{this.renderBottomContent()}
}
}

Double Tap Button issue when keyBoard opens React native

I know there are already so many queries on this topic, I have tried every step but still won't be able to fix the issue.
Here is the code :
render() {
const {sContainer, sSearchBar} = styles;
if (this.props.InviteState.objectForDeleteList){
this.updateList(this.props.InviteState.objectForDeleteList);
}
return (
<View style={styles.mainContainer}>
<CustomNavBar
onBackPress={() => this.props.navigation.goBack()}
/>
<View
style={sContainer}
>
<ScrollView keyboardShouldPersistTaps="always">
<TextInput
underlineColorAndroid={'transparent'}
placeholder={'Search'}
placeholderTextColor={'white'}
selectionColor={Color.colorPrimaryDark}
style={sSearchBar}
onChangeText={(searchTerm) => this.setState({searchTerm})}
/>
</ScrollView>
{this.renderInviteUserList()}
</View>
</View>
);
}
renderInviteUserList() {
if (this.props.InviteState.inviteUsers.length > 0) {
return (
<SearchableFlatlist
searchProperty={'fullName'}
searchTerm={this.state.searchTerm}
data={this.props.InviteState.inviteUsers}
containerStyle={styles.listStyle}
renderItem={({item}) => this.renderItem(item)}
keyExtractor={(item) => item.id}
/>
);
}
return (
<View style={styles.emptyListContainer}>
<Text style={styles.noUserFoundText}>
{this.props.InviteState.noInviteUserFound}
</Text>
</View>
);
}
renderItem(item) {
return (
this.state.userData && this.state.userData.id !== item.id
?
<TouchableOpacity
style={styles.itemContainer}
onPress={() => this.onSelectUser(item)}>
<View style={styles.itemSubContainer}>
<Avatar
medium
rounded
source={
item.imageUrl === ''
? require('../../assets/user_image.png')
: {uri: item.imageUrl}
}
onPress={() => console.log('Works!')}
activeOpacity={0.7}
/>
<View style={styles.userNameContainer}>
<Text style={styles.userNameText} numberOfLines={1}>
{item.fullName}
</Text>
</View>
<CustomButton
style={{
flexWrap: 'wrap',
alignSelf: 'flex-end',
marginTop: 10,
marginBottom: 10,
width: 90,
}}
showIcon={false}
btnText={'Add'}
onPress={() => this.onClickSendInvitation(item)}
/>
</View>
</TouchableOpacity> : null
);
}
**I even tried with bellow code as suggested by #Nirmalsinh **:
<ScrollView keyboardShouldPersistTaps="always" style={sContainer}>
<CustomNavBar
onBackPress={() => this.props.navigation.goBack()}
/>
<TextInput underlineColorAndroid={'transparent'}
placeholder={'Search'}
placeholderTextColor={'white'}
selectionColor={Color.colorPrimaryDark}
style={sSearchBar}
onChangeText={(searchTerm) => this.setState({searchTerm})} />
{this.renderInviteUserList()}
</ScrollView>
I have followed this article:
https://medium.com/react-native-training/todays-react-native-tip-keyboard-issues-in-scrollview-8cfbeb92995b
I have tried with keyboardShouldPersistTaps=handled also but still, I have to tap twice on my Custom Button to perform an action. Can anybody tell me what I am doing wrong inside the code?
Thanks.
You need to add give value always in keyboardShouldPersistTaps to allow user tap without closing the keyboard.
keyboardShouldPersistTaps='always'
For example:
<ScrollView keyboardShouldPersistTaps='always'>
// Put your component
</ScrollView>
NOTE: Kindly put your tappable component inside the ScrollView. Otherwise it won't work.
You can use keyboardShouldPersistTaps='handled' in a ScrollView or Scrollables like FlatList SectionList etc. and embed a TouchableWithoutFeedBack to handle the case for dismiss on outside clicks.
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<ScrollView keyboardShouldPersistTaps='handled'>
// Rest of the content.
</ScrollView/>
</TouchableWithoutFeedback>
For FlatList and SectionList you will have to handle KeyBoard.dismiss separately.
Please try this, It's working for me, it will works you also, i hope it helps...