Open Menu on click of Icon in React Native - react-native

I am not able to identify how to display Menu items when clicked on Icon in React Native
Expo Link
Code
_onPressItem = () => {
this.setState({ opened: true });
};
render() {
return (
<View style={styles.container}>
<ListItem
title={
<View>
<Text style={{ fontWeight: "bold" }}>Mason Laon Roah</Text>
<Text>9886012345</Text>
</View>
}
subtitle={
<View>
<Text>445 Mount Eden Road, Mount Eden, Auckland. </Text>
<Text>Contact No: 134695584</Text>
</View>
}
leftAvatar={{ title: 'MD' }}
rightContentContainerStyle={{ alignSelf: 'flex-start'}}
rightTitle={<Icon type="material" color="red" name="more-vert" />}
/>
</View>
);
}
getMenuView() {
const { opened } = this.state;
return (
<MenuProvider style={{flexDirection: 'column', padding: 30}}>
<Menu
opened={opened}
onBackdropPress={() => this.onBackdropPress()}
onSelect={value => this.onOptionSelect(value)}>
<MenuTrigger onPress={() => this._onPressItem()} text="Menu Icon Here" />
<MenuOptions>
<MenuOption value={1} text='One' />
<MenuOption value={2}>
<Text style={{color: 'red'}}>Two</Text>
</MenuOption>
<MenuOption value={3} disabled={true} text='Three' />
</MenuOptions>
</Menu>
</MenuProvider>
);
}
Please let me know how to integrate Menu with Icon..
Basically all the items are displayed in FlatList where each item have its own Menu Item

Just Update Code below:
instead of:
rightTitle={<Icon type="material" color="red" name="more-vert" />}
update to:
rightTitle={this.getMenuView()}
Because this Method returns view not Menu popup.
and instead of:
<MenuTrigger onPress={() => this._onPressItem()} text="Menu Icon Here" />
update to:
<MenuTrigger onPress={() => this._onPressItem()}>
<Icon type="material" color="red" name="more-vert" />
</MenuTrigger>
so that instead of printing text, it shows icon.
I tried this code on your given link, it works..

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}
/>
)

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

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...

Rating not choosing more than 3 stars - React Native Elements - Rating)

I am using the Rating Element from the react-native-elements component. I noticed I can't choose more/less than 3 stars for my rating and I do not understand why.
Here is my code:
<Modal animationType={"slide"} transparent={false}
visible={this.state.showModal}
onDismiss={() => this.openModal()}
onRequestClose={() => this.openModal()}>
<View style={styles.modal}>
<Text style={styles.modalTitle}>Rating</Text>
<Rating
showRating
type="star"
imageSize={30}
onFinishRating={this.ratingCompleted}
style={{ paddingVertical: 10 }}
/>
<View style={styles.btnView}>
<Button
onPress={() => { this.handleFormSubmit() }}
color="#512DA8"
title="Submit"
style={styles.formBtn}
/>
<Button
onPress={() => { this.openModal();
this.resetForm(); }}
color="gray"
title="Cancel"
/>
</View>
</View>
</Modal>
What am I doing wrong?
I recommand to use AirbnbRating instead of Rating because it work for me.
Example code :
import {AirbnbRating } from 'react-native-elements';
<AirbnbRating
count={11}
reviews={["Terrible", "Bad", "Meh", "OK", "Good", "Hmm...", "Very Good", "Wow", "Amazing", "Unbelievable", "Jesus"]}
defaultRating={11}
size={20}
onFinishRating={rating => console.log(rating)}
/>
According to,
https://react-native-training.github.io/react-native-elements/docs/rating.html#ratingcount
you can use the prop ratingCount to set the number of rating images to display.
Try setting this to something other than 3.
Edit
Seems I misunderstood the query, please try setting readonly to false explicitly.
I would ask what do you have in function
onFinishRating={this.ratingCompleted}
I also used this component in my project and updated the state there:
<Rating
showRating
startingValue={4}
onFinishRating={rating => this.setState({ rating: rating })}
/>
Move the rating component in a function that returns the rating:
NOTE: this is a little bit strange, but it worked for me
Change your code like the following:
const RatingView=()=>{
return (
<Rating
showRating
type="star"
imageSize={30}
onFinishRating={this.ratingCompleted}
style={{ paddingVertical: 10 }}
/>
)
}
You Modal :
<Modal animationType={"slide"} transparent={false}
visible={this.state.showModal}
onDismiss={() => this.openModal()}
onRequestClose={() => this.openModal()}>
<View style={styles.modal}>
<Text style={styles.modalTitle}>Rating</Text>
<RatingView /> // Here ...
<View style={styles.btnView}>
<Button
onPress={() => { this.handleFormSubmit() }}
color="#512DA8"
title="Submit"
style={styles.formBtn}
/>
<Button
onPress={() => { this.openModal();
this.resetForm(); }}
color="gray"
title="Cancel"
/>
</View>
</View>
</Modal>

react-native-popup-menu : Error: (0 , _react2.createContext) is not a function

I have a listView. I want to open a popup menu when user long press on "name". But i am getting error of createContext.
import {
MenuContext,
Menu,
MenuOptions,
MenuOption,
MenuTrigger,
} from 'react-native-popup-menu';
render()
{
...
return(
<View style={{ flex: 1, flexDirection: 'row' }} >
<MenuContext>
<TouchableWithoutFeedback onLongPress = {this.openMenu}>
<Text style={styles.textViewContainer} >{rowData.Ad_name}</Text>
<Menu ref={c => (this.menu = c)}>
<MenuTrigger text = "Select Action.." />
<MenuOptions>
<MenuOption onSelect = {() => this.onEditCampaignAction.bind(this, rowData.campaign_id)}>
{rowData.Status == '0' ?
<TouchableOpacity
style={styles.SubmitButtonStyle}
activeOpacity={.5}
onPress={this.onEditCampaignAction.bind(this, rowData.campaign_id)}>
<FontAwesomeIcon name='pencil' style={styles.icon} />
</TouchableOpacity>
:
<TouchableOpacity
style={styles.SubmitButtonStyle}
activeOpacity={.5}
onPress={this.onViewDetailsAction.bind(this, rowData.campaign_id)}>
<FontAwesomeIcon name='eye' style={styles.icon} />
</TouchableOpacity>
}
</MenuOption>
</MenuOptions>
</Menu>
</TouchableWithoutFeedback>
</MenuContext>
</View>
);
}
Issue has been fixed. react-native-popup-menu requires following versions:
React: 16.3.2
React-Native : 0.55.3
I upgraded versions of both and package installed successfully.
You are using incompatible version of RN. Downgrading to 0.12.x will solve your problem.
See https://github.com/instea/react-native-popup-menu#react-native-compatibility for more details