I want to pass focus to next text input on press of buttons.Everything was working fine till when I created customTextInput in another class and calling it through props.But now problem is focus is not changing on button press and I think it is related to some scope problem .Maybe it is not accessing this of other class(child component).
Following is the stuff I had done:
This is Custom Text input I had created in other js file
<View>
<CustomTextInput
textLogo={logo}
placeholder={placeholder}
value={value}
onChangeText={onTextChange}
isMultiline={isMultiline}
onFocus={() =>
{
this.setState({index:index,isFocused:true})
this.refs.scrollView.scrollTo({ x: 0, y: position, animated: true })}
}
ref={input =>(this[arrTextInput[index]] = input)}/>
</View>
This is function for changing the focus
customFocusNavigator = () => {
return(
<View style={styles.FocusNavigator}>
<TouchableOpacity onPress={() => {this[arrTextInput[this.state.index - 1]].focus()}} style={styles.bottomSubView}>
<Text>Previous</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() =>{this[arrTextInput[this.state.index + 1]].focus()}} style={styles.bottomSubView}>
<Text>Next</Text>
</TouchableOpacity>
</View>
)
}
And I am changing index of textInput on focus .
I hope I gave sufficient matter for my problem.Any help will be appreciated.Thank you
You dont need a function to change the focus, you can simply do it using onSubmitEditing
For example with 3 inputs you could do it like this:
<Input
placeHolder="Input1"
ref={input => (this.Input1 = input)}
onSubmitEditing={() => {this.Input2.focus(); }}
/>
<Input
placeHolder="Input2"
ref={input => (this.Input2 = input)}
onSubmitEditing={() => {this.Input3.focus(); }}
/>
<Input
placeHolder="Input3"
ref={input => (this.Input3 = input)}
onSubmitEditing={() => **GO SOMEWHERE ELSE** }}
/>
You set the ref on the later input and then pass the focus() on the previous one
Related
I have trying to create Textinput box with use of map so when I will press the first input the paste option should come and it get filled in each box with maxlength of 1.
const [isInputBoxFocused, setIsInputBoxFocused] = useState(true);
const handleOnPress = () => {
setIsInputBoxFocused(true);
inputRef.current?.focus();
};
<View>
<Pressable style={[styles.boxContainer]} onPress={handleOnPress}>
{boxArray.map(boxValue)}
</Pressable>
<TextInputField
placeholder=""
value={input}
onChangeText={handleTextChange}
maxLength={inputLength}
ref={inputRef}
onBlur={handleOnBlur}
keyboardType="number-pad"
style={styles.textInputHidden}
autoFocus
autoComplete="sms-otp"
textContentType="oneTimeCode"
/>
</View>
I also tried this https://snack.expo.dev/#putuyoga/textinput-paste-event-listener and https://www.npmjs.com/package/react-otp-input and https://www.npmjs.com/package/#twotalltotems/react-native-otp-input
But none of these supports otp pasting.
1.Here is my custom text input custom component i define props ref which i want to use in
parent component
export const InputField = ({
placeholder,
onChangeText,
placeholderTextColor,
showSecureIcon,
isSecure,
onPressIcon,
keyboardType,
returnKeyType,
maxLength,
secureIconColor,
handleUseCallBack,
ref,
value
}) => {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder={placeholder}
onChangeText={onChangeText}
placeholderTextColor={placeholderTextColor}
autoCapitalize="none"
secureTextEntry={isSecure}
keyboardType={keyboardType}
returnKeyType={returnKeyType}
maxLength={maxLength}
value={value}
ref={ref}
/>
<View style={styles.iconContainer}>
{showSecureIcon ?
<TouchableOpacity
onPress={onPressIcon}
>
<Ionicons
name={isSecure ? "eye-off-sharp" : "eye-sharp"}
color={secureIconColor}
size={constants.vw(25)}
/>
</TouchableOpacity>
:
null
}
</View>
</View>
)
}
2-Now the part where i want to change my ref
in this field i create the text inputs field of password and confirm where i want to change
my focus
const passwordRef = useRef(null);
const confirmPasswordRef =
useRef(null);
const onSubmitEditing=()=>{
confirmPasswordRef.current.focus();
}
<View style={{ marginTop: constants.vh(66) }}>
<Components.InputField
placeholder={constants.ConstStrings.setANewPassword}
ref={passwordRef}
onSubmitEditing={()=>onSubmitEditing()}
onChangeText={(text) => setState({
...state,
password: text
})}
/>
</View>
<View style={{ marginTop: constants.vh(20) }}>
<Components.InputField
ref={confirmPasswordRef}
placeholder={constants.ConstStrings.confirmPassword}
onChangeText={(text) => setState({
...state,
confirm_password: text
})}
/>
</View>
This part is the end part qwertyuiopsdf;';dsyuiopoiuteweryuiopuytreep[gfjklvcvbnm,mvcxzxcewqwe[poiuyd
The problem with your code is that you've created a custom input component, but haven't given to it the instructions on how to handle different methods.
So, in your case, the generic Input component knows what method is focus, but your custom one doesn't.
What you should do:
Make your input component a forwardRef one so that you can pass a ref to it and then be able to do actions on it.
Use useImperativeHandle so that you can call internal methods of your ref.
Create a focus fn which in your custom input will basically call the focus method of your ref.
You cannot pass the ref in props as you are doing, that just doesn't work in React.
I suppose all of your components are functional, in that case:
export const InputField = React.forwardRef({
placeholder,
...
}, ref) => { // pass a ref to here, this way you will let React know to associate the ref from external component to an internal ref
const textInput = useRef(null); // Create a ref to pass to your input
useImperativeHandle(ref, () => ({ // To be able to call `focus` from outside using ref
focus,
});
const focus = textInput.current.focus();
return (
<View style={styles.container}>
<TextInput
ref={textInput}
style={styles.input}
...
/>
...
</View>
)
}
And then in your component you just have to pass a fresh ref created by useRef and then you'll be able to call focus on in.
Tell me whether that solves it for you!
see image
In react native text input placeholder, is there any way to give multiple colors to place holder text.
email[black color] asterisk [red color]
I have tried placeholdertextcolor property of text input. But it will allow only one color for whole placeholder text.
The image in the link is my required textinput UI.
You can make your own placeholder component wrapped inside the TextInput component. It will look something similar to this
<TextInput
value={value}
isFocused={isFocused}
onFocus={() =>
this.setState({ isFocused: true }, () => onFocus && onFocus())
}
onBlur={() => this.setState({ isFocused: false })}
>
{!isFocused && !value && (
<Text>
Placeholder Text<Text style={{ color: 'red' }}>*</Text>
</Text>
)}
</TextInput>
Make sure to keep track of the focused state of your input component so that you can display placeholder or no.
As mentioned in the previous comment you can add your custom placeholder,
you can also pass it to the state and clear it when press on the text input using onResponderStart ,here is full example:
const example = () => {
const [placeHolderText, setPlaceHolderText] = React.useState('PlaceHolder');
const [placeHolderOtherText, setPlaceHolderOtherText] = React.useState('*');
return (
<View style={{flex: 1, alignContent: 'center', justifyContent: 'center'}}>
<TextInput
//remove placeholder on touching
onResponderStart={() => {
setPlaceHolderOtherText('');
setPlaceHolderText('');
}}>
<Text>
{placeHolderText}
<Text style={{color: 'red'}}>{placeHolderOtherText}</Text>
</Text>
</TextInput>
</View>
);
};
Some odd behaviour on a TextInput on a Modal in React Native Paper. When I type a character, it is input into the text box, but then the cursor flashes back (as if it is deleted) and then it reappears again. This all happens very quickly and the character is retained, but it all looks a bit janky. Gif below to illustrate:
The code is fairly simple for the modal:
import { Portal, Modal, Button, Title, Text, TextInput } from 'react-native-paper';
const [nameNew, setNameNew] = useState('')
const [emailNew, setEmailNew] = useState('')
const renderModalAddPerson = () => {
return (
<Portal>
<Modal visible={visibleModalAddPerson} onDismiss={closeModalAddPerson} contentContainerStyle={styles.modalContainer}>
<View>
<Title style={{alignSelf:'center'}}>Title here</Title>
<Text> </Text>
<TextInput
mode="outlined"
label="Name"
style={{alignSelf:'center', width:'95%'}}
value={nameNew}
onChangeText={nameNew => setNameNew(nameNew)}
ref={input1}
returnKeyType='next'
blurOnSubmit={false}
onSubmitEditing={() => input2.current.focus()}
/>
<TextInput
mode="outlined"
label="Email"
style={{alignSelf:'center', width:'95%'}}
value={emailNew}
onChangeText={emailNew => setEmailNew(emailNew)}
ref={input2}
returnKeyType='done'
blurOnSubmit={false}
onSubmitEditing={() => addPerson()}
/>
<Button
uppercase={false}
style={{backgroundColor:'#2c3e50', width: '95%', alignSelf:'center', margin: 10}}
labelStyle={{color:'white'}}
onPress={()=>addPerson()}
>Add person</Button>
</View>
</Modal>
</Portal>
);
};
Issue observed on iOS and not tested on Android
Looks like this is a known bug in React Native. Best solution I have found is to use defaultValue prop instead of value.
The only thing I can see is that your using the same variable name to update your state as the name of the state which could be causing something weird to happen.
<TextInput
mode="outlined"
label="Name"
style={{alignSelf:'center', width:'95%'}}
value={nameNew}
onChangeText={val => setNameNew(val)}
ref={input1}
returnKeyType='next'
blurOnSubmit={false}
onSubmitEditing={() => input2.current.focus()}
/>
Please try the above as I've tested and its working as expected for me.
I want to map key value pairs in react native. The value being editable text entry. The mapped components show up fine, but when I try to edit the TextInput, the keyboard disappears when i type the first letter. Don't know whats causing the problem.
If i just put a TextInput in the parent element, it works absolutely fine but doesn't work when I use the map function.
<View style={styles.main}>
<View>
{this._getDetailElements()}
</View>
</View>
_getDetailElements() function
_getDetailElements = () => {
return Object.keys(this.state.data).map(elem => (
<View key={shortid.generate()} style={styles.element}>
<TextInput
editable={this.state.editable}
onChangeText={text => this.setState({seletedText: text})}
value={this.state.selectedText}
/>
</View>
)
);
}
i think you should just change the value to defaultValue Like this :
<TextInput
editable={this.state.editable}
onChangeText={text => this.setState({seletedText: text})}
defaultValue={this.state.selectedText}
/>
Good luck
It's because your key on the map changes everytime it rerenders.
Just use the index of the map iteration as key
_getDetailElements = () => {
return Object.keys(this.state.data).map((elem, index) => (
<View key={index} style={styles.element}>
<TextInput
editable={this.state.editable}
onChangeText={text => this.setState({seletedText: text})}
value={this.state.selectedText}
/>
</View>
)
);
}