render(){
return(
<View style={{ flex:1 }}>
<TextInput style={{ backgroundColor:'red'}} onFocus={() => alert('Focued')}
onBlur={() => alert('Blurred') }
/>
</View>
)
}
In the above code snippet when I click on textinput the focus operation is working, but when I click outside the textinput component onBlur is not triggered.
I don't want to enclose the component in scrollview
could any one help me out on this.
Related
I am unsure how to trigger an event in my TouchableOpacity component that will target the TextInput component. I'd just like to be able to allow the user to type in a multiline area and click a button when they are finished, so that they are able to save their text (similar to how the iOS Notes app functions).
<View>
<View>
<Text>Notes</Text>
{typing &&
<TouchableOpacity
onPress={() => {
//blur() the textinput here
}}
>
<Text>Done</Text>
</TouchableOpacity>
}
</View>
<View>
<TextInput
multiline={true}
textAlignVertical='top'
value={text}
onChangeText={(text) => {
}}
onFocus={setTyping(true)}
/>
</View>
</View>
If you only need to access the text inside the same file, store your text in state in your component.
const [text, setText] = useState('');
...
<TouchableOpacity
// not sure what you want to do with the text here, but it'll be available in the `text` variable
onPress={() => saveNote(text)}
...
<TextInput
onChangeText={newText => setText(newText)
// or more simply
onChangeText={setText}
...
/>
The text input will automatically blur when you touch the Touchable.
If you need the text available in other files, have a look into React Context or look up state management libraries for React Native.
I have a number of TextInput in my react-native application and I want that if user clicks on next key, the next input must be focused. I am trying to do this with returnKeyType prop passed to all the TextInput. However this doesn't work as intended ,i.e. next input is not focused. And my code for same looks like
<TextInput
ref={firstInputForDaysInterestTextInputRef}
value={closingCosts.firstInputForDaysInterest}
onChangeText={value =>
onStateChange('firstInputForDaysInterest', value)
}
onEndEditing={event =>
onEndEditing(
'firstInputForDaysInterest',
event.nativeEvent.text,
)
}
placeholderTextColor={colors.placeholderColor}
placeholder={constants.common.zeroPlaceholder}
autoCapitalize="none"
returnKeyType="next"
onFocus={() => onFocus(elementName)}
keyboardType="decimal-pad"
style={[
styles.textInput,
styles.textInputWidth,
styles.textInputMargin,
]}
/>
The workaround that I thought was passing ref and then focusing the next input onEndEditing, but if I does this the textinput will not be closed when I tap outside the textInput. So how can I make my text input to focus on next one?
You can use onSubmitEditing prop to focus the next input for example:
const firstInputForDaysInterestTextInputRef = React.useRef()
const secondInputForDaysInterestTextInputRef = React.useRef()
return (
<View style={styles.container}>
<TextInput
ref={firstInputForDaysInterestTextInputRef}
placeholderTextColor={'gray'}
placeholder={'first'}
autoCapitalize="none"
returnKeyType="next"
keyboardType="decimal-pad"
onSubmitEditing={()=>secondInputForDaysInterestTextInputRef.current?.focus()}
style={[
styles.textInput,
styles.textInputWidth,
styles.textInputMargin,
]}
/>
<TextInput
ref={secondInputForDaysInterestTextInputRef}
placeholderTextColor={'gray'}
placeholder={'second'}
autoCapitalize="none"
returnKeyType="next"
onFocus={() => alert('I am focused !')}
keyboardType="decimal-pad"
style={[
styles.textInput,
styles.textInputWidth,
styles.textInputMargin,
]}
/>
</View>
);
Example on Snack
If you want to hide the textinput (hide keyboard) when pressing somewhere else in the app, wrap it it like this for example:
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.container}>
<TextInput />
</View>
</TouchableWithoutFeedback>
Don't forget to import TouchableWithoutFeedback and Keyboard from 'react-native'
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.
I am developing an app on react native. I want to call a date picker when i press on a Text-Input and after selecting a date it should show on the Text-Input
Wrap TextInput into a view and set pointerEvents as none.
Now you can use Pressable component from react-native to listen to the onpress event.
<Pressable onPress={() => alert('Hi!')}>
<View pointerEvents="none">
<TextInput />
</View>
</Pressable>
You cannot explicitly call onPress for TextInput. You could only use. onFocus which will be called when you press the input box to get cursor over there. No need to focus on onBlur as your use case doesn't required.. Handle close within onFocus if possible.
onFocus = () => {
// do something
}
render() {
<TextInput onFocus={onFocus} />
}
What you have to do is use onFocus and onBlur of TextInput.
<TextInput
onFocus={this.onFocus}
onBlur={this.onBlur}
/>
onFocus = () => {
// Open date picker
}
onBlur = () => {
// Close date picker and add value to textinput
}
You can make text input field read only by providing
editable={false}
pointerEvents="none"
prop to TextInput.
Wrap TextInput inside View and set pointerEvents="none", wrap that view with TouchableOpacity or any other Touchable Component. Please see below example!
<TouchableOpacity
onPress={() => {
alert('hello');
}}>
<View pointerEvents="none">
<TextInput
onChange={() => {}}
value={''}
placeholder={waterMark}
editable={!isDisabled}
selectTextOnFocus={!isDisabled}
/>
</View>
</TouchableOpacity>
I have a TextInput with multiLine true. However, after two lines the text disappear behind the keyboard. I have tried wrapping the TextInput in KeyboardAvoidingView, but it doesn't work.
The keyboard does push up the TextInput when I unfocus the TextInput and then click on the bottom line. Any idea how I can make the last line of the TextInput stay on top of the keyboard?
The code:
<View style={styles.descriptionFlexStyle}>
<Text
style={[
styles.headerTextStyle,
{ marginTop: Window.height * 0.04 }
]}> Please fill in a reason </Text>
<ScrollView>
<TextInput
style={styles.reasonTextInput}
placeholder="Reason"
value={reasonText}
multiline={true}
onChangeText={input =>
this.setState({
reasonText: input
})
}
underlineColorAndroid="transparent"
ref="reasonTextInput"
/>
</ScrollView>
</View>
hello my dear you must use KeyboardAvoidingView Component from React-Native and put a behavior on it like below :
<KeyboardAvoidingView behavior={'postion' || 'height' || 'padding'}>
<View style={styles.descriptionFlexStyle}>
<Text
style={[
styles.headerTextStyle,
{ marginTop: Window.height * 0.04 }
]}> Please fill in a reason </Text>
<ScrollView>
<TextInput
style={styles.reasonTextInput}
placeholder="Reason"
value={reasonText}
multiline={true}
onChangeText={input =>
this.setState({
reasonText: input
})
}
underlineColorAndroid="transparent"
ref="reasonTextInput"
/>
</ScrollView>
</View>
</KeyboardAvoidingView>
This answer may be a little too late. However, I have found a workaround without using the KeyboardAvoidingView component. A ScrollView could be used instead to scroll the multiline TextInput to the top to have the 'keyboard avoiding' effect. I would use the ref measure() method to get the top y value of the TextInput, before using the scrollTo() method to scroll the TextInput directly to the top of the screen, effectively avoiding the keyboard.
import React, { useRef } from "react";
import { ScrollView, TextInput, View } from "react-native";
export default function Test() {
const scrollViewRef = useRef(null);
const viewRef = useRef(null);
const handleFocus = () => {
viewRef.current.measure((x, y) => {
scrollViewRef.current.scrollTo({ x: 0, y });
});
};
return (
<ScrollView ref={scrollViewRef}>
{/* View to fill up space */}
<View
style={{
width: "80%",
height: 600,
}}
/>
<View ref={viewRef}>
<TextInput
onFocus={handleFocus}
multiline={true}
style={{
width: "80%",
height: 100,
backgroundColor: "whitesmoke",
alignSelf: "center",
}}
/>
{/* View to fill up space */}
<View
style={{
width: "80%",
height: 600,
}}
/>
</View>
</ScrollView>
);
}
Ok i have finally solved it using "KeyboardAvoidingView". I did two things. First i removed the height on my TextInput and then i set the behavior attribute on the "KeyboardAvoidingView" to "padding". Works perfect for me now. Let me know if this help! :)