this.refs.FieldName.focus() is not a function in React Native - react-native

I am using Custom Keyboard. In that I am using CustomTextInput in place of TextInput. All works well but I want to focus input field in function.
<CustomTextInput customKeyboardType="hello"
onFocus={() => this.onFocus('fieldname')}
selectTextOnFocus={ true }
ref="TextInput"
underlineColorAndroid = 'transparent'
onChangeText={(value) => this.setState({fieldname:this.onChange(value)})}
/>
In Function something like below :-
function () {
Keyboard.dismiss();
this.refs.TextInput.focus();
}
But I am getting an error :- this.refs.TextInput.focus is not a function.
Basically my focus() function is not working.
Please help!

I tried this.refs['TextInput'].focus() and it works for me. You can write a function for Textinput's onFocus and within this function dimiss default keyboard, lunch your customized keyboard and focus again on your TextInput. I hope it will help.
This is my code:
<TextInput
style={{ height: 40, width: 200 }}
ref="TextInput"
/>
<TouchableOpacity
onPress={() => { (this.refs['TextInput'] as any).focus() }}>
<Text>Press to focus</Text>
</TouchableOpacity>

Related

How to add an expression and an arrow function to onPress in react native?

I am trying to create a TouchableOpacity that executes another function and an arrow function, but cannot figure out a way to do so. Here is my code:
<SubmitButton
text="NEXT"
style={{ backgroundColor: "#093968" }}
onPress={
(handleSubmit,
() => this.setState({ submitPressed: true }))
}
/>
I understood that the second function is overriding the first, but how do I solve this problem. And I also don't want to add the arrow function to handleSubmit.
You can do:
<SubmitButton
text="NEXT"
style={{ backgroundColor: "#093968" }}
onPress={()=>{
handleSubmit()
this.setState({ submitPressed: true })
}}
/>

React native TextInput Component

I search it every day why it doesn't work properly.When I type anything onto TextInput's placeholder it starts with empty space.I want to start without space.I also tried trim() method.It wasn't helpful.How should I fix my error? Thanks in advance!
<TextInput value={this.state.key} onChangeText={(text) =>{this.setState({key:text.trim()}) ; console.warn('key: '+this.state.key)}}/>
Try this :
<TextInput
value={this.state.key}
keyboardType="default"
onChangeText={key => this.setState({ key })}
/>;
UPDATED ANSWER :
_replaceSpace(str) {
return str.replace(/\u0020/, '\u00a0')
}
<TextInput
style={{ textAlign: "right" }}
value={this._replaceSpace(this.state.text)}
onChangeText={text => this.setState({ text: text })}
/>;

React native textinput multiline is not being pushed up by keyboard

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! :)

Clearing a Textinput using a TouchableOpacity without dismissing the keyboard?

i want to build a super simple chat.
To do that a got an TextInput and a TouchableOpacity to send the message and
clear the Textinput.
Problem: When i send the message the Textinput is cleared BUT when start writing again the old text is copied in the Textinput again (+ the new character).
However if the keyboard is dismissed after sending and clearing everything works
perfectly fine.
Is there any way to clear the TextInput completly with a TouchableOpacity?
Below is the code and a few tries by myself but none of them worked.
Thanks in advance,
Maffinius
<View style={{flexDirection: 'row'}}>
<TextInput
placeholder="Schreibe eine Nachricht"
onChangeText={(text) => this.setState({newMsg : text})}
style={{width: 300}}
ref={'ref1'}
/>
<TouchableOpacity
onPress={this.sendMessage}
>
<Text> --> </Text>
</TouchableOpacity>
</View>
sendMessage = () => {
this.state.MsgData.push({msg: this.state.newMsg, id: this.props.global.userId, timestamp: 8888});
this.refs['ref1'].clear();
this.setState({newMsg: ""});
//this.refs['ref1'].setNativeProps({text: ''})
//Keyboard.dismiss();
}
List item
Use defaultValue prop for setting the value of the state (https://facebook.github.io/react-native/docs/textinput.html#defaultvalue)
<TextInput
placeholder="Schreibe eine Nachricht"
onChangeText={(text) => this.setState({newMsg : text})}
style={{width: 300}}
ref={(input) => this.ref1 = input}
defaultValue={this.state.newMsg}
/>
See this example for full implementation: https://snack.expo.io/SkuH8hKPb

Disabling buttons on react native

I'm making an android app using react native and I've used TouchableOpacity component to create buttons.
I use a text input component to accept text from the user and the button should only be enabled once the text input matches a certain string.
I can think of a way to do this by initially rendering the button without the TouchableOpactiy wrapper and re-rendering with the wrapper once the input string matches.
But I'm guessing there is a much better way to do this. Can anyone help?
TouchableOpacity extends TouchableWithoutFeedback, so you can just use the disabled property :
<TouchableOpacity disabled={true}>
<Text>I'm disabled</Text>
</TouchableOpacity>
React Native TouchableWithoutFeedback #disabled documentation
The new Pressable API has a disabled option too :
<Pressable disabled={true}>
{({ pressed }) => (
<Text>I'm disabled</Text>
)}
</Pressable>
Just do this
<TouchableOpacity activeOpacity={disabled ? 1 : 0.7} onPress={!disabled && onPress}>
<View>
<Text>{text}</Text>
</View>
</TouchableOpacity>
this native-base there is solution:
<Button
block
disabled={!learnedWordsByUser.length}
style={{ marginTop: 10 }}
onPress={learnedWordsByUser.length && () => {
onFlipCardsGenerateNewWords(learnedWordsByUser)
onFlipCardsBtnPress()
}}
>
<Text>Let's Review</Text>
</Button>
So it is very easy to disable any button in react native
<TouchableOpacity disabled={true}>
<Text>
This is disabled button
</Text>
</TouchableOpacity>
disabled is a prop in react native and when you set its value to "true" it will disable your button
Happy Cooding
This seems like the kind of thing that could be solved using a Higher Order Component. I could be wrong though because I'm struggling to understand it 100% myself, but maybe it'll be helpful to you (here's a couple links)...
http://www.bennadel.com/blog/2888-experimenting-with-higher-order-components-in-reactjs.htm
http://jamesknelson.com/structuring-react-applications-higher-order-components/
TouchableOpacity receives activeOpacity. You can do something like this
<TouchableOpacity activeOpacity={enabled ? 0.5 : 1}>
</TouchableOpacity>
So if it's enabled, it will look normal, otherwise, it will look just like touchablewithoutfeedback.
To disable Text you have to set the opacity:0 in Text style like this:
<TouchableOpacity style={{opacity:0}}>
<Text>I'm disabled</Text>
</TouchableOpacity>
You can use the disabled prop in TouchableOpacity when your input does not match the string
<TouchableOpacity disabled = { stringMatched ? false : true }>
<Text>Some Text</Text>
</TouchableOpacity>
where stringMatched is a state.
You can build an CustButton with TouchableWithoutFeedback, and set the effect and logic you want with onPressIn, onPressout or other props.
I was able to fix this by putting a conditional in the style property.
const startQuizDisabled = () => props.deck.cards.length === 0;
<TouchableOpacity
style={startQuizDisabled() ? styles.androidStartQuizDisable : styles.androidStartQuiz}
onPress={startQuiz}
disabled={startQuizDisabled()}
>
<Text
style={styles.androidStartQuizBtn}
>Start Quiz</Text>
</TouchableOpacity>
const styles = StyleSheet.create({
androidStartQuiz: {
marginTop:25,
backgroundColor: "green",
padding: 10,
borderRadius: 5,
borderWidth: 1
},
androidStartQuizDisable: {
marginTop:25,
backgroundColor: "green",
padding: 10,
borderRadius: 5,
borderWidth: 1,
opacity: 0.4
},
androidStartQuizBtn: {
color: "white",
fontSize: 24
}
})
I think the most efficient way is to wrap the touchableOpacity with a view and add the prop pointerEvents with a style condition.
<View style={this.state.disabled && commonStyles.buttonDisabled}
pointerEvents={this.state.disabled ? "none" : "auto"}>
<TouchableOpacity
style={styles.connectButton}>
<Text style={styles.connectButtonText}">CONNECT </Text>
</TouchableOpacity>
</View>
CSS:
buttonDisabled: {
opacity: 0.7
}
Here's my work around for this I hope it helps :
<TouchableOpacity
onPress={() => {
this.onSubmit()
}}
disabled={this.state.validity}
style={this.state.validity ?
SignUpStyleSheet.inputStyle :
[SignUpStyleSheet.inputAndButton, {opacity: 0.5}]}>
<Text style={SignUpStyleSheet.buttonsText}>Sign-Up</Text>
</TouchableOpacity>
in SignUpStyleSheet.inputStyle holds the style for the button when it disabled or not, then in style={this.state.validity ? SignUpStyleSheet.inputStyle : [SignUpStyleSheet.inputAndButton, {opacity: 0.5}]} I add the opacity property if the button is disabled.
You can enable and disable button or by using condition or directly by default it will be disable : true
// in calling function of button
handledisableenable()
{
// set the state for disabling or enabling the button
if(ifSomeConditionReturnsTrue)
{
this.setState({ Isbuttonenable : true })
}
else
{
this.setState({ Isbuttonenable : false})
}
}
<TouchableOpacity onPress ={this.handledisableenable} disabled=
{this.state.Isbuttonenable}>
<Text> Button </Text>
</TouchableOpacity>
Use disabled true property
<TouchableOpacity disabled={true}> </TouchableOpacity>
Here is the simplest solution ever:
You can add onPressOut event to the TouchableOpcaity
and do whatever you want to do.
It will not let user to press again until onPressOut is done