Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a dynamic form with controlled components in ReactJS?

As I am looking at the examples in the reference for controlled form components in react.js official website, I am wondering how is one supposed to implement a form in which you would be able to remove and add input elements dynamically in such a way that they are controlled components? Is this even possible?

In the examples we can see:

class NameForm extends React.Component {   constructor(props) {     super(props);     this.state = {value: ''};      this.handleChange = this.handleChange.bind(this);     this.handleSubmit = this.handleSubmit.bind(this);   }    handleChange(event) {     this.setState({value: event.target.value});   }    handleSubmit(event) {     alert('A name was submitted: ' + this.state.value);     event.preventDefault();   }    render() {     return (       <form onSubmit={this.handleSubmit}>         <label>           Name:           <input type="text" value={this.state.value} onChange={this.handleChange} />         </label>         <input type="submit" value="Submit" />       </form>     );   } } 

Due to the nature of my work, I often find myself having to implement such forms. Moreover, I don't add or remove input elements directly - I am managing custom components, but for the sake of simplicity here I am asking for basic form elements.

like image 376
Martin Shishkov Avatar asked Feb 18 '17 14:02

Martin Shishkov


People also ask

How do I create a dynamic form in react JS?

The values will be input.name and input.Create a function called handleFormChange. Assign this function to the input fields as an onChange event. This onChange event takes two parameters, index and event. Index is the index of the array and event is the data we type in the input field.


1 Answers

How adding/removing input elements dynamically possible?

Yes, it is possible, you can add/remove input elements dynamically, But for that you need to take care of few things:

1- Proper binding of events.

2- Array to store the values of each input element separately.

3- When user fill value in any input element then updating only that specific value in state.

Logic:

Maintain an array inside state, that will store the values. Use #array.map to create ui (input element) for each array values. while creating the fields, use a remove button with each field, and pass the index of field in that function, it will help you to identify which field you wants to delete, do the same thing for onChange also.

Check this example:

class App extends React.Component {    constructor(props) {      super(props);      this.state = { values: [] };      this.handleSubmit = this.handleSubmit.bind(this);    }      createUI(){       return this.state.values.map((el, i) =>            <div key={i}>      	    <input type="text" value={el||''} onChange={this.handleChange.bind(this, i)} />      	    <input type='button' value='remove' onClick={this.removeClick.bind(this, i)}/>           </div>                 )    }      handleChange(i, event) {       let values = [...this.state.values];       values[i] = event.target.value;       this.setState({ values });    }        addClick(){      this.setState(prevState => ({ values: [...prevState.values, '']}))    }        removeClick(i){       let values = [...this.state.values];       values.splice(i,1);       this.setState({ values });    }      handleSubmit(event) {      alert('A name was submitted: ' + this.state.values.join(', '));      event.preventDefault();    }      render() {      return (        <form onSubmit={this.handleSubmit}>            {this.createUI()}                    <input type='button' value='add more' onClick={this.addClick.bind(this)}/>            <input type="submit" value="Submit" />        </form>      );    }  }    ReactDOM.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>    <div id='container'/>

Check the working jsfiddle: https://jsfiddle.net/mayankshukla5031/ezdxg224/

like image 56
Mayank Shukla Avatar answered Sep 21 '22 20:09

Mayank Shukla