5

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.
 }
Kirit Modi
  • 23,155
  • 15
  • 89
  • 112
  • Please check this ref link: https://stackoverflow.com/questions/29280445/reactjs-setstate-with-a-dynamic-key-name – Jigar Shah Sep 14 '17 at 11:46
  • best thing to use redux-form , http://redux-form.com/6.0.0-alpha.4/docs/faq/reactnative.md/ – Sport Sep 15 '17 at 06:39

5 Answers5

15
_handleMultiInput(name) {
    return (text) => {
        this.setState({ [name]:text })
    }
}

<TextInput
   placeholder='enter your name.'
   onChangeText={_handleMultiInput('myName')}
/>
Thales Carvalho
  • 166
  • 1
  • 3
4

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,
  },
});
bennygenel
  • 23,896
  • 6
  • 65
  • 78
  • @KiritModi _"not working"_ is not enough of information. – bennygenel Sep 15 '17 at 06:46
  • 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. – Kirit Modi Sep 15 '17 at 06:54
  • @KiritModi still doesn't explain _not working_ part. What is not working? What error do you get if you get any? There might be something wrong on your _dynamically adding_ part. Maybe I could help more if you give more information. – bennygenel Sep 15 '17 at 06:58
  • I will update question with GIF so You can easily get. – Kirit Modi Sep 15 '17 at 07:00
  • I want to adding textFiled dynamically, in iOS there are tag so that we can handle it. but in rect not ant tag. – Kirit Modi Sep 15 '17 at 07:24
  • see this code how to add textField on click on AddMore button. – Kirit Modi Sep 15 '17 at 07:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/154520/discussion-between-kirit-modi-and-bennygenel). – Kirit Modi Sep 15 '17 at 09:27
  • Please help me. https://stackoverflow.com/questions/47551462/how-to-drag-and-drop-with-multiple-view-in-react-native – Kirit Modi Nov 29 '17 at 11:19
2

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
}
Renato Probst
  • 5,914
  • 2
  • 42
  • 45
Aanchal1103
  • 917
  • 8
  • 21
1

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>    
  );
 }
}
Artem Mirchenko
  • 2,140
  • 1
  • 9
  • 21
  • @KiritModi, yes, i edit to full component for you. If you need i can write child component - TextInput for you if you develop it for web, nor for ios/android. – Artem Mirchenko Sep 14 '17 at 13:03
0

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}
            />
Gurjinder Singh
  • 9,221
  • 1
  • 66
  • 58