'How to multiple TextInput handle with single handler?
I have create common class for TextInput and use it multiple time but its event handle with same method. i want to handle array data after filled the data in textInput.
Here Added multiple textField and single handleAddMore
. How to identify which textInput called the handleAddMore
.
The textField component added dynamically according to array data. now when user edit the textInput I want to identify the textInput and updated array text on particular index.
let addMoreCompView = this.state.dataAddMore.map((data ,index) =>{
return(
<View style ={[styles.commonMargin ,{flexDirection : 'row',marginTop : 2 , height : 40, backgroundColor : Globle.COLOR.INPUTCOLOR}]}>
<View style = {{height : '100%' , width : '80%' , justifyContent: 'center' ,alignItems: 'flex-start', flexDirection : 'column'}}>
<TextInput style = {{fontFamily: 'Gotham-Light',fontSize : 14 ,color: Globle.COLOR.BACKCOLOR , paddingLeft : 20}}
underlineColorAndroid = "transparent"
placeholder = 'Please enter emailID.'
placeholderTextColor = 'black'
autoCapitalize = "none"
keyboardType = "email-address"
onSubmitEditing ={Keyboard.dismiss}
onChangeText = {this.handleAddMore}
autoCorrect = {false}/>
</View>
<TouchableOpacity onPress = {() => this.removeMoreComponent(data.key)} style = {{height : '90%' , width : '20%' , alignItems: 'flex-end', justifyContent: 'center'}}>
<Image style = {{width : 9 , height : 10 , marginRight : 20}} source = {require('./Images/cancelMore.png')}/>
</TouchableOpacity>
</View>
)
});
Here I want to identify which TextInput
called this method.
Here I want to text and index of textField.
handleAddMore = (text) =>{
// Here I want to text and index of textField.
}
Solution 1:[1]
_handleMultiInput(name) {
return (text) => {
this.setState({ [name]:text })
}
}
<TextInput
placeholder='enter your name.'
onChangeText={_handleMultiInput('myName')}
/>
Solution 2:[2]
You can just pass another parameter to handleAddMore
?
<TextInput
placeholder = 'Please enter emailID.'
onSubmitEditing ={Keyboard.dismiss}
onChangeText = {(text) => { this.handleAddMore(text, 'textInput1'); }}
autoCorrect = {false}
/>
handleAddMore = (text, textInput) => {
}
Update 1
onChangeText receives text
as parameter and onChange receives event
Update 2
I created a small project to show you how it works. You can check the code and implement it to your project as you wish. You not explaining the error exactly makes it harder to find whats wrong with your code exactly. Saying not working is never enough. You can find the project on Here (Expo)
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
info: '',
inputCount: 3,
data: [{ name: 'input1' }, { name: 'input2' }, { name: 'input3' }],
};
this.inputRefs = {};
}
onAddMore() {
const newData = this.state.data;
newData.push({ name: `input${this.state.inputCount + 1}` });
this.setState(prevState => ({
inputCount: prevState.inputCount + 1,
data: newData,
}));
}
_onChangeText(text, inputName) {
console.log('Input Name:', inputName, text);
console.log("Inout's Ref:", this.inputRefs[inputName]);
const info = `${this.state.info}\n\r${inputName} changed text`;
this.setState({
info
});
}
_onChange(event, inputName) {
console.log('Input Name:', inputName);
}
render() {
return (
<View style={styles.container}>
{this.state.data.map(d => (
<View style={styles.inputWrapper} key={d.name}>
<TextInput
style={styles.input}
onChangeText={(text) => { this._onChangeText(text, d.name); }}
onChange={(event) => { this._onChange(event, d.name); }}
ref={ref => {
this.inputRefs[d.name] = ref;
}}
defaultValue={d.name}
/>
</View>
))}
<Button
onPress={this.onAddMore.bind(this)}
title="Add More"
color="#841584"
/>
<TextInput
multiline={true}
editable={false}
style={styles.info}>
{this.state.info}
</TextInput>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Constants.statusBarHeight,
backgroundColor: '#F2F2F2',
},
info: {
flex: 0.5,
},
inputWrapper: {
backgroundColor: 'yellow',
marginTop: 5,
marignBottom: 5,
marginLeft: 5,
marginRight: 5,
},
input: {
height: 55,
paddingLeft: 15,
paddingRight: 5,
paddingTop: 5,
paddingBottom: 5,
},
});
Solution 3:[3]
The code bellow works for react but not for react native: "onChangeText" pass only the text. There's another method called "onChange" that passes the input itself, but on react native it doesn't pass the input (because RN works for both android/iOS/web, and Android/iOS don't have an event.target)
Add name
to TextInputs
<TextInput
name='input1'
placeholder = 'Please enter emailID.'
onSubmitEditing ={Keyboard.dismiss}
onChange = {(e) => this.handleAddMore(e.target.name)}
autoCorrect = {false}
/>
<TextInput
name='input2'
placeholder = 'Please enter emailID.'
onSubmitEditing ={Keyboard.dismiss}
onChange = {(e) => this.handleAddMore(e.target.name)}
autoCorrect = {false}
/>
and define handleAddMore as:
handleAddMore = (name) =>{
//add your code here
}
Solution 4:[4]
Pass name
attribute in textInput. In future if you will need to update current state field you can handle it like this:
class MyComponent extends Component {
state = { val1: '', val2: '' };
handleChange = e => this.setState({ [e.target.name]: e.target.value });
render(){
const { val1, val2 } = this.state;
console.log(val1, val2);
return(
<div>
<TextInput
name="val1"
value={val1}
placeholder = 'Please enter emailID.'
onSubmitEditing ={Keyboard.dismiss}
onChangeText = {this.handleChange}
autoCorrect = {false}/>
<TextInput
name="val2"
value={val2}
placeholder = 'Please enter emailID.'
onSubmitEditing ={Keyboard.dismiss}
onChangeText = {this.handleChange}
autoCorrect = {false}/>
</div>
);
}
}
Solution 5:[5]
Using functional component. I have three inputs amount, date and description to save. Here is how to save them in single object and using same function for all three TextInput.
// useState hook to store object
const [inputValues, setInputValues] = useState({
amount: '',
date: '',
description: '',
});
// will save user input
function inputChangeHandler(inputIdentifier, enteredValue) {
setInputValues(currentInputValues => {
return {
...currentInputValues,
[inputIdentifier]: enteredValue, // dynamically override the desired input
};
});
}
// TextInput Component
<TextInput
onChangeText={inputChangeHandler.bind(this, 'amount')}
value={inputValues.amount}
placeholder={inputValues.title}
/>
<TextInput
onChangeText={inputChangeHandler.bind(this, 'date')}
value={inputValues.date}
placeholder={inputValues.title}
/>
<TextInput
onChangeText={inputChangeHandler.bind(this, 'description')}
value={inputValues.date}
placeholder={inputValues.title}
/>
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 | Thales Carvalho |
Solution 2 | |
Solution 3 | Renato Probst |
Solution 4 | |
Solution 5 | Gurjinder Singh |