'react native disable text input until previous input filled in
What im trying to achieve is this, when a user gets to the form; I want the first input to be active, so the user is able to click it and fill it out. And they shouldn't be able to move to the next text field input until the first one has been filled.
I also want the submit button to be deactivated and not to be activated until all the inputs are filled out.
What's the best way of achieving this?
Below code is our form. also added a screenshot of our screen to give you a visual reference.
<Icon name="numeric-2-circle" color="#777777" size={40} />
<Text style={styles.textEnterMsg}>Enter a message</Text>
</View>
<View style={styles.inputMsg}>
<Center>
<Input
variant="outline"
placeholder="Recipient's name"
/>
<Input
variant="outline"
placeholder="Add message"
maxWidth="300px"
/>
</Center>
</View>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Icon name="numeric-3-circle" color="#777777" size={40} />
<Text style={styles.textGiftMsg}>Send gift</Text>
</View>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
}}
>
<RadioButtonRN
style={styles.RN}
box={false}
boxStyle={styles.box}
textStyle={styles.text}
data={data}
selectedBtn={(e) => console.log(e)}
/>
</View>
<Card style={styles.Card}>
<Card.Content>
<Title
style={{
color: "white",
fontSize: "15",
}}
>
Where would you like to send the gift?
</Title>
<Text style={{ color: "white"}}>We’ll text your recipient with your gift and message</Text>
<Center>
<View style={styles.inputContainer}>
<TextInput
placeholder="Recipient's Phone Number"
value={number}
onChangeText={(text) => setNumber(text)}
style={styles.input}
/>
</View>
</Center>
</Card.Content>
</Card>
</ScrollView>
for the submit button:
<TouchableOpacity
style={{
backgroundColor: "#023531",
alignItems: "center",
justifyContent: "center",
}}
onPress={() => {
setModalVisible(false);
navigation.navigate("ShopList");
}}
>
<Text
style={{
color: "white",
fontSize: 18,
}}
>
Send Gift →
</Text>
</TouchableOpacity>
Solution 1:[1]
The Input component of react-native inherits TextInput, but its state is handled internally which makes it perfectly valid to write
<Input
variant="outline"
placeholder="Recipient's name"
/>
However, in your usecase it might be advised to handle this on your own since the states of some of your input fields are dependent on others.
Since, we inherit from TextInput we can handle this as follows.
const [recipientName, setRecipientName] = useState("")
...
<Input
variant="outline"
placeholder="Recipient's name"
value={recipientName}
onChangeText={setRecipientName}
/>
In order for the next field to be disabled until the user inputs something into the recipient field, we can use the state recipientName as follows.
const [message, setMessage] = useState("")
<Input
variant="outline"
placeholder="Add message"
maxWidth="300px"
value={message}
onChangeText={setRecipientName}
editable={recipientName && recipientName.trim().length > 0}
/>
The important piece of code is given by
editable={recipientName && recipientName.trim().length > 0}
We first check if recipientName is undefined (which should actually not happen in our code but let us be defensive here) and then we use trim to prevent that just whitespaces are valid and finally check that its length is greater than zero. If this criteria match, then the Input field becomes editable.
We can do the same for the other fields. It might be a good idea to define a function for this as follows.
const isMessageEditable = useCallback(() => {
return recipientName && recipientName.trim().length > 0
}, [recipientName])
The above would allow us to add additional conditions in an isolated function. Let us imagine that we want the name to be at least 3 characters long, then we could implement this as well. For fields which are dependent by more than one field, this is easier to handle as well.
For disabling the button component, this is pretty much the same pattern, but the prop is called disabled.
<TouchableOpacity
disabled={some conditions here as above}
style={{
backgroundColor: "#023531",
alignItems: "center",
justifyContent: "center",
}}
onPress={() => {
setModalVisible(false);
navigation.navigate("ShopList");
}}>
<Text
style={{
color: "white",
fontSize: 18,
}}>
Send Gift ?
</Text>
</TouchableOpacity>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | David Scholz |
