How to add pop up list menu in list icon? - reactjs

Please help me out on how to add pop menu list like the picture I attached. I'm quite knew to react native. Please help me out. Below are the codes. I would like to add the pop menu list in member list page. By the way i have imported the icon from headerbar.js.
Attached Image Of Pop menu list
MemberList.js
import React from 'react';
import { HeaderBar4 } from '../components/HeaderBar';
import {GrayScrollView, EventTitle,SearchBarAlign} from '../components/styles';
import { MemberCell, SearchBarCell } from '../components/MemberInput';
const MemberList = ({navigation}) => {
return (
<GrayScrollView contentContainerStyle={{justifyContent: 'center'}}>
<HeaderBar4/>
<EventTitle>Members List</EventTitle>
<SearchBarAlign>
<SearchBarCell/>
</SearchBarAlign>
<MemberCell/>
</GrayScrollView>
);
}
export default MemberList;
HeaderBar.js
export const HeaderBar4 = () => {
const navigation = useNavigation();
return (
<HeaderBarContainer>
<LeftBarContainer>
<TouchableOpacity activeOpacity={0.6} onPress={() => navigation.goBack()}>
<BackIcon name="arrow-left"/>
</TouchableOpacity>
</LeftBarContainer>
<RightBarContainer>
<TouchableOpacity activeOpacity={0.6} onPress={undefined}>
<CartIcon name="cart-outline" />
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.6} onPress={undefined}>
<BellIcon name="bell" />
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.6} onPress={undefined}>
<SliderIcon name="list"/>
</TouchableOpacity>
</RightBarContainer>
</HeaderBarContainer>
);
}

I am not 100% I get your question if you are trying to make a pop-up menu you will need to work with the z-index of your component styles or you can use pre-made packages like this Pop up menu package. If you are interested in making your own component you can follow this article Link to custom pop up menu article
If you are trying to make circular checkboxes you can use this package. Link to circular checkbox package.

Related

How can I open BottomSheetModal (#gorhom/bottom-sheet) in different component, using React-Native (Expo)

I am using https://gorhom.github.io/react-native-bottom-sheet/.
I was wondering how can I open "BottomSheetModal" in a different file e.g Navbar Component.
This is what my code looks like at the moment to open the Bottom Sheet inside of the same component.
const BottomSheetModal: FC = () => {
const bottomSheetModalRef = useRef<BottomSheet>(null);
const snapPoints = useMemo(() => ["25%", "50%"], []);
const handlePresentModalPress = useCallback(() => {
bottomSheetModalRef.current?.present();
}, []);
return (
<>
<Button title="Test" onPress={() => handlePresentModalPress()} />
<BottomSheet
index={1}
style={{ ...shadows.bottomSheet }}
ref={bottomSheetModalRef}
snapPoints={snapPoints}>
<View style={styles.container}>
<Text>Awesome 🎉</Text>
</View>
</BottomSheet>
</>
);
};
So how can I use the opening code of the Bottom Sheet inside of my Navbar Component?
Navbar Component:
// Open BottomSheet here
<TouchableWithoutFeedback onPress={() => openBottomSheet()}>
<View>
<Image
style={styles.avatar}
source={{
uri: "https://lumiere-a.akamaihd.net/v1/images/character_themuppets_kermit_b77a431b.jpeg?region=0%2C0%2C450%2C450",
}}
/>
</View>
</TouchableWithoutFeedback>
Thank you!
I found out to do this, incase anyone comes across this question, I'll post it here!
So what you have to do is pass the ref to the bottom sheet component. So in the Navbar component I created the ref for the bottom sheet, and then passed it into the bottom sheet.
Navbar:
// Create Ref
const userBottomSheetRef = useRef<BottomSheetModal>(null);
// Pass ref into the bottom sheet component
<BottomSheet ref={userBottomSheetRef} snapPoints={["30%"]}/>
Then inside the bottom sheet component you forward the ref using a react function, and then pass it in as normal:
<BottomSheetModal ref={ref} >
<BottomSheetScrollView>
<View style={styles.container}>{children}</View>
</BottomSheetScrollView>
</BottomSheetModal>

InfiniteScroll using ScrollView - React Native

I have a list using the ScrollView of react native itself. Basically, I build a list dynamically through an API return.
async fetchData(userSearch) {
const {route} = this.props;
const {params} = route;
const {type} = params;
this.setState({
loading: true,
});
const responseProcedures = await scheduleResource.getProcedures(userSearch);
this.setState({
procedures: responseProcedures.data,
loading: false,
});
}
<ScrollView
onScroll={(event) => this.shouldLoadMoreContent(event)}
>
{procedures.map(procedure => (
<ArrowBox key={procedure.id} onPress={() => RootNavigation.navigate('ProcedureDetails', {procedure})}>
<Text bold style={styles.ProcedureTitle}>
{procedure.name}
</Text>
{!!procedure.synonyms.length && (
<>
<Text bold style={styles.ProcedureSynonymTitle}>
Sinônimos
</Text>
<View style={styles.ProcedureSynonymOptionsContainer}>
{procedure.synonyms.map(synonym => <Text style={styles.ProcedureSynonymOption} key={synonym}>{synonym}</Text>)}
</View>
</>
)}
</ArrowBox>
))}
</ScrollView>
The problem is that I load the entire return from the API and it slows down.
I would like to know how to dynamically load the content and make new calls in the api, when I reach the end of the page.
Api allows me to place offset and limit.
Could someone give me some example?
Thanks!!!!!
Basically the ScrollView is not designed to handle dynamic data, the correct component that is designed to perform this function is called Flatlist. It works almost exactly like ScrollView but it is faster and will only render components that are shown on the screen.
Please import Flatlist from React Native like this...
//At the top of your file, please import FlatList together with all the modules that you want
import { FlatList, Text, View } from "react-native";
Then replace the entire ScrollView in your code with a Flatlist like this:
<FlatList
keyExtractor={(procedure) => procedure.id}
data={this.state.procedures}
renderItem={(procedure) => {
return (
<ArrowBox
key={procedure.id}
onPress={() =>
RootNavigation.navigate("ProcedureDetails", {
procedure })}>
<Text bold style={styles.ProcedureTitle}>
{procedure.name}
</Text>
{!!procedure.synonyms.length && (
<>
<Text bold style={styles.ProcedureSynonymTitle}>
Sinônimos
</Text>
<View
style={styles.ProcedureSynonymOptionsContainer}>
{procedure.synonyms.map((synonym) => (
<Text
style={styles.ProcedureSynonymOption}
key={synonym}>
{synonym}
</Text>
))}
</View>
</>
)}
</ArrowBox>
);
}}
></FlatList>;

How can I create a modal and render it on the fly?

I am building my first app in React Native, I have a ListView that displays a number of items and each one is clickable. My question is when I click on a row I would like a modal to appear above. Similar in IOS to clicking and the adding a subview.
renderRow( rowData ){
return (
<TouchableHighlight onPress={() => this.pressRow()}>
<View style={styles.parcelInfoContainer}>
</View>
</TouchableHighlight>
);
}
Now the problem is I am unsure about what to do in the function called by pressRow in relation to rendering the new component. In IOS I would simply add the view at this point but I am not sure how to go about it in React Native. I understand the idea of components just not how to render a new component on the fly.
If you're going to render the same Modal, in terms of layout, you should define it in render() function. Rendering on the fly is not possible, but you can change the states to make modal show what you like.
onPressRow = (dataFromRow) => {
this.setState({
modalText: dataFromRow.text
})
this.showModal(); //Call your function to show modal
}
render() {
return (
<View>
<FlatList />
<Modal>
<View>
...
<Text>{this.state.modalText}</Text>
</View>
</Modal>
</View>
)
}
However, if you want different layout for each row, you should write a this.getModalContent() like function to determine which layout should be rendered. You should call this function in render => <Modal> {this.getModalContent()} </Modal>
getModalContent = () => {
switch (this.state.modalText) { // define a better logic here.
case 'a':
return ( <Text> hey </Text>)
...
}
}

How to add a button in react native environment?

could you please tell me how to add button in view using react native .
here is my code
https://rnplay.org/apps/0TPePA
can I used this this
https://npmcdn.com/react-native-button#1.6.0
in my demo ?
I need to add button in my view here is code
class First extends Component {
render (){
return (<View><Text>"hello"</Text>
</View>
)
}
}
Creating a button yourself is quite simple. You can use toucableopacity and the onPress method attached to it.
Put the following in your render method
<TouchableOpacity onPress={this._onButtonPress}>
<Text>Button Text</Text>
</TouchableOpacity>
And put this in a react function.
_onButtonPress: function () {
console.log ("Button has been pressed");
}
To make it look more like a button you can add styling directly to the <Text style={{flex: 1, backgroundColor: 'blue', etc...}}

Hide keyboard in react-native

If I tap onto a textinput, I want to be able to tap somewhere else in order to dismiss the keyboard again (not the return key though). I haven't found the slightest piece of information concerning this in all the tutorials and blog posts that I read.
This basic example is still not working for me with react-native 0.4.2 in the Simulator. Couldn't try it on my iPhone yet.
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onEndEditing={this.clearFocus}
/>
</View>
The problem with keyboard not dismissing gets more severe if you have keyboardType='numeric', as there is no way to dismiss it.
Replacing View with ScrollView is not a correct solution, as if you have multiple textInputs or buttons, tapping on them while the keyboard is up will only dismiss the keyboard.
Correct way is to encapsulate View with TouchableWithoutFeedback and calling Keyboard.dismiss()
EDIT: You can now use ScrollView with keyboardShouldPersistTaps='handled' to only dismiss the keyboard when the tap is not handled by the children (ie. tapping on other textInputs or buttons)
If you have
<View style={{flex: 1}}>
<TextInput keyboardType='numeric'/>
</View>
Change it to
<ScrollView contentContainerStyle={{flexGrow: 1}}
keyboardShouldPersistTaps='handled'
>
<TextInput keyboardType='numeric'/>
</ScrollView>
or
import {Keyboard} from 'react-native'
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={{flex: 1}}>
<TextInput keyboardType='numeric'/>
</View>
</TouchableWithoutFeedback>
EDIT: You can also create a Higher Order Component to dismiss the keyboard.
import React from 'react';
import { TouchableWithoutFeedback, Keyboard, View } from 'react-native';
const DismissKeyboardHOC = (Comp) => {
return ({ children, ...props }) => (
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<Comp {...props}>
{children}
</Comp>
</TouchableWithoutFeedback>
);
};
const DismissKeyboardView = DismissKeyboardHOC(View)
Simply use it like this
...
render() {
<DismissKeyboardView>
<TextInput keyboardType='numeric'/>
</DismissKeyboardView>
}
NOTE: the accessible={false} is required to make the input form continue to be accessible through VoiceOver. Visually impaired people will thank you!
This just got updated and documented! No more hidden tricks.
import { Keyboard } from 'react-native'
// Hide that keyboard!
Keyboard.dismiss()
Github link
Use React Native's Keyboard.dismiss()
Updated Answer
React Native exposed the static dismiss() method on the Keyboard, so the updated method is:
import { Keyboard } from 'react-native';
Keyboard.dismiss()
Original Answer
Use React Native's dismissKeyboard Library.
I had a very similar problem and felt like I was the only one that didn't get it.
ScrollViews
If you have a ScrollView, or anything that inherits from it like a ListView, you can add a prop that will automatically dismiss the keyboard based on press or dragging events.
The prop is keyboardDismissMode and can have a value of none, interactive or on-drag. You can read more on that here.
Regular Views
If you have something other than a ScrollView and you'd like any presses to dismiss the keyboard, you can use a simple TouchableWithoutFeedback and have the onPress use React Native's utility library dismissKeyboard to dismiss the keyboard for you.
In your example, you could do something like this:
var DismissKeyboard = require('dismissKeyboard'); // Require React Native's utility library.
// Wrap your view with a TouchableWithoutFeedback component like so.
<View style={styles.container}>
<TouchableWithoutFeedback onPress={ () => { DismissKeyboard() } }>
<View>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
<TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}} />
</View>
</TouchableWithoutFeedback>
</View>
Note: TouchableWithoutFeedback can only have a single child so you need to wrap everything below it in a single View as shown above.
use this for custom dismissal
var dismissKeyboard = require('dismissKeyboard');
var TestView = React.createClass({
render: function(){
return (
<TouchableWithoutFeedback
onPress={dismissKeyboard}>
<View />
</TouchableWithoutFeedback>
)
}
})
The simple answer is to use a ScrollView instead of View and set the scrollable property to false (might need to adjust some styling though).
This way, the keyboard gets dismissed the moment I tap somewhere else. This might be an issue with react-native, but tap events only seem to be handled with ScrollViews which leads to the described behaviour.
Edit: Thanks to jllodra. Please note that if you tap directly into another Textinput and then outside, the keyboard still won't hide.
You can import keyboard from react-native like below:
import { Keyboard } from 'react-native';
and in your code could be something like this:
render() {
return (
<TextInput
onSubmit={Keyboard.dismiss}
/>
);
}
static dismiss()
Dismisses the active keyboard and removes focus.
I'm brand new to React, and ran into the exact same issue while making a demo app. If you use the onStartShouldSetResponder prop (described here), you can grab touches on a plain old React.View. Curious to hear more experienced React-ers' thoughts on this strategy / if there's a better one, but this is what worked for me:
containerTouched(event) {
this.refs.textInput.blur();
return false;
}
render() {
<View onStartShouldSetResponder={this.containerTouched.bind(this)}>
<TextInput ref='textInput' />
</View>
}
2 things to note here. First, as discussed here, there's not yet a way to end editing of all subviews, so we have to refer to the TextInput directly to blur it. Second, the onStartShouldSetResponder is intercepted by other touchable controls on top of it. So clicking on a TouchableHighlight etc (including another TextInput) within the container view will not trigger the event. However, clicking on an Image within the container view will still dismiss the keyboard.
Use ScrollView instead of View and set the keyboardShouldPersistTaps attribute to false.
<ScrollView style={styles.container} keyboardShouldPersistTaps={false}>
<TextInput
placeholder="Post Title"
onChange={(event) => this.updateTitle(event.nativeEvent.text)}
style={styles.default}/>
</ScrollView>
Wrapping your components in a TouchableWithoutFeedback can cause some weird scroll behavior and other issues. I prefer to wrap my topmost app in a View with the onStartShouldSetResponder property filled in. This will allow me to handle all unhandled touches and then dismiss the keyboard. Importantly, since the handler function returns false the touch event is propagated up like normal.
handleUnhandledTouches(){
Keyboard.dismiss
return false;
}
render(){
<View style={{ flex: 1 }} onStartShouldSetResponder={this.handleUnhandledTouches}>
<MyApp>
</View>
}
The simplest way to do this
import {Keyboard} from 'react-native'
and then use the function Keyboard.dismiss()
That's all.
Here is a screenshot of my code so you can understand faster.
Now wrap the entire view with TouchableWithoutFeedback and onPress function is keyboard.dismiss()
Here is the example
In this way if user tap on anywhere of the screen excluding textInput field, keyboard will be dismissed.
There are a few ways,
if you control of event like onPress you can use:
import { Keyboard } from 'react-native'
onClickFunction = () => {
Keyboard.dismiss()
}
if you want to close the keyboard when the use scrolling:
<ScrollView keyboardDismissMode={'on-drag'}>
//content
</ScrollView>
More option is when the user clicks outside the keyboard:
<KeyboardAvoidingView behavior='padding' style={{ flex: 1}}>
//inputs and other content
</KeyboardAvoidingView>
If any one needs a working example of how to dismiss a multiline text input here ya go! Hope this helps some folks out there, the docs do not describe a way to dismiss a multiline input at all, at least there was no specific reference on how to do it. Still a noob to actually posting here on the stack, if anyone thinks this should be a reference to the actual post this snippet was written for let me know.
import React, { Component } from 'react'
import {
Keyboard,
TextInput,
TouchableOpacity,
View,
KeyboardAvoidingView,
} from 'react-native'
class App extends Component {
constructor(props) {
super(props)
this.state = {
behavior: 'position',
}
this._keyboardDismiss = this._keyboardDismiss.bind(this)
}
componentWillMount() {
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
}
componentWillUnmount() {
this.keyboardDidHideListener.remove()
}
_keyboardDidHide() {
Keyboard.dismiss()
}
render() {
return (
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={this.state.behavior}
>
<TouchableOpacity onPress={this._keyboardDidHide}>
<View>
<TextInput
style={{
color: '#000000',
paddingLeft: 15,
paddingTop: 10,
fontSize: 18,
}}
multiline={true}
textStyle={{ fontSize: '20', fontFamily: 'Montserrat-Medium' }}
placeholder="Share your Success..."
value={this.state.text}
underlineColorAndroid="transparent"
returnKeyType={'default'}
/>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
)
}
}
Updated usage of ScrollView for React Native 0.39
<ScrollView scrollEnabled={false} contentContainerStyle={{flex: 1}} />
Although, there is still a problem with two TextInput boxes. eg. A username and password form would now dismiss the keyboard when switching between inputs. Would love to get some suggestions to keep keyboard alive when switching between TextInputs while using a ScrollView.
const dismissKeyboard = require('dismissKeyboard');
dismissKeyboard(); //dismisses it
Approach No# 2;
Thanks to user #ricardo-stuven for pointing this out, there is another better way to dismiss the keyboard which you can see in the example in the react native docs.
Simple import Keyboard and call it's method dismiss()
I just tested this using the latest React Native version (0.4.2), and the keyboard is dismissed when you tap elsewhere.
And FYI: you can set a callback function to be executed when you dismiss the keyboard by assigning it to the "onEndEditing" prop.
If i'm not mistaken the latest version of React Native has solved this issue of being able to dismiss the keyboard by tapping out.
How about placing a touchable component around/beside the TextInput?
var INPUTREF = 'MyTextInput';
class TestKb extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={{ flex: 1, flexDirection: 'column', backgroundColor: 'blue' }}>
<View>
<TextInput ref={'MyTextInput'}
style={{
height: 40,
borderWidth: 1,
backgroundColor: 'grey'
}} ></TextInput>
</View>
<TouchableWithoutFeedback onPress={() => this.refs[INPUTREF].blur()}>
<View
style={{
flex: 1,
flexDirection: 'column',
backgroundColor: 'green'
}}
/>
</TouchableWithoutFeedback>
</View>
)
}
}
Wrap your whole component with:
import { TouchableWithoutFeedback, Keyboard } from 'react-native'
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
...
</TouchableWithoutFeedback>
Worked for me
Using KeyBoard API from react-native does the trick.
import { Keyboard } from 'react-native'
// Hide the keyboard whenever you want using !
Keyboard.dismiss()
Keyboard module is used to control keyboard events.
import { Keyboard } from 'react-native'
Add below code in render method.
render() {
return <TextInput onSubmitEditing={Keyboard.dismiss} />;
}
You can use -
Keyboard.dismiss()
static dismiss() Dismisses the active keyboard and removes focus as per react native documents.
https://facebook.github.io/react-native/docs/keyboard.html
Use
Keyboard.dismiss(0);
to hide the keyboard.
Using keyboardShouldPersistTaps in the ScrollView you can pass in "handled", which deals with the issues that people are saying comes with using the ScrollView. This is what the documentation says about using 'handled': the keyboard will not dismiss automatically when the tap was handled by a children, (or captured by an ancestor). Here is where it's referenced.
First import Keyboard
import { Keyboard } from 'react-native'
Then inside your TextInput you add Keyboard.dismiss to the onSubmitEditing prop. You should have something that looks like this:
render(){
return(
<View>
<TextInput
onSubmitEditing={Keyboard.dismiss}
/>
</View>
)
}
We can use keyboard and tochablewithoutfeedback from react-native
const DismissKeyboard = ({ children }) => (
<TouchableWithoutFeedback
onPress={() => Keyboard.dismiss()}
>
{children}
</TouchableWithoutFeedback>
);
And use it in this way:
const App = () => (
<DismissKeyboard>
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="username"
keyboardType="numeric"
/>
<TextInput
style={styles.input}
placeholder="password"
/>
</View>
</DismissKeyboard>
);
I also explained here with source code.
Use Keyboard.dismiss() to dismiss keyboard at any time.
Wrap the View component that is the parent of the TextInput in a Pressable component and then pass Keyboard. dismiss to the onPress prop. So, if the user taps anywhere outside the TextInput field, it will trigger Keyboard. dismiss, resulting in the TextInput field losing focus and the keyboard being hidden.
<Pressable onPress={Keyboard.dismiss}>
<View>
<TextInput
multiline={true}
onChangeText={onChangeText}
value={text}
placeholder={...}
/>
</View>
</Pressable>
in ScrollView use
keyboardShouldPersistTaps="handled"
This will do your job.
There are many ways you could handle this, the answers above don't include returnType as it was not included in react-native that time.
1: You can solve it by wrapping your components inside ScrollView, by default ScrollView closes the keyboard if we press somewhere. But incase you want to use ScrollView but disable this effect. you can use pointerEvent prop to scrollView
pointerEvents = 'none'.
2: If you want to close the keyboard on a button press, You can just use Keyboard from react-native
import { Keyboard } from 'react-native'
and inside onPress of that button, you can useKeyboard.dismiss()'.
3: You can also close the keyboard when you click the return key on the keyboard,
NOTE: if your keyboard type is numeric, you won't have a return key.
So, you can enable it by giving it a prop, returnKeyType to done.
or you could use onSubmitEditing={Keyboard.dismiss},It gets called whenever we press the return key. And if you want to dismiss the keyboard when losing focus, you can use onBlur prop, onBlur = {Keyboard.dismiss}
Keyboard.dismiss() will do it. But sometimes it may lose the focus and Keyboard will be unable to find the ref. The most consistent way to do is put a ref=_ref to the textInput, and do _ref.blur() when you need to dismiss, and _ref.focus() when you need to bring back the keyboard.
Here is my solution for Keyboard dismissing and scrolling to tapped TextInput (I am using ScrollView with keyboardDismissMode prop):
import React from 'react';
import {
Platform,
KeyboardAvoidingView,
ScrollView
} from 'react-native';
const DismissKeyboard = ({ children }) => {
const isAndroid = Platform.OS === 'android';
const behavior = isAndroid ? false : 'padding';
return (
<KeyboardAvoidingView
enabled
behavior={ behavior }
style={{ flex: 1}}
>
<ScrollView
keyboardShouldPersistTaps={'always'}
keyboardDismissMode={'on-drag'}
>
{ children }
</ScrollView>
</KeyboardAvoidingView>
);
};
export default DismissKeyboard;
usage:
render(){
return(
<DismissKeyboard>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
</DismissKeyboard>
);
}

Resources