0

I am created a dynamic form in react.js but i can not type anything value in input because onchnage function not working i don't know why i tried a lot of times but i am getting failed and adding form and deleting form is working all right only input value not working here is my code and codesandbox link https://codesandbox.io/s/reactdynamicform-02cho .

import React, { Component } from "react";
import "bootstrap/dist/css/bootstrap.css";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputFields: [
        {
          firstName: "",
          lastName: ""
        }
      ]
    };

  }

  handleAddFields = () => {
    const values = this.state.inputFields;
    values.push({ firstName: "", lastName: "" });
    this.setState({
      values
    });
  };

  handleRemoveFields = index => {
    const values = this.state.inputFields;
    values.splice(index, 1);
    this.setState({
      values
    });
  };

  async onChange(e, index) {
    if (
      ["firstName","lastName"].includes(e.target.name)
    ) {
    let cats = [...this.state.inputFields];
    cats[index][e.target.name] = e.target.value;
    await this.setState({
      cats
    });
  }else{
    this.setState({ [e.target.name]: e.target.value.toUpperCase() });
  }
    console.log(this.state.inputFields);
  }

  handleSubmit = e => {
    e.preventDefault();
    console.log("inputFields", this.state.inputFields);
  };

  render() {
    return (
      <>
        <h1>Dynamic Form Fields in React</h1>
        <form onSubmit={this.handleSubmit.bind(this)}>
          <div className="form-row">
            {this.state.inputFields.map((inputField, index) => (
              <div key={`${inputField}~${index}`}>
                <div className="form-group col-sm-6">
                  <label htmlFor="firstName">First Name</label>
                  <input
                    type="text"
                    className="form-control"
                    id="firstName"
                    name="firstName"
                    value={inputField.firstName}
                    onChange={this.onChange.bind(index)}
                  />
                </div>
                <div className="form-group col-sm-4">
                  <label htmlFor="lastName">Last Name</label>
                  <input
                    type="text"
                    className="form-control"
                    id="lastName"
                    name="lastName"
                    value={inputField.lastName}
                    onChange={this.onChange.bind(index)}
                  />
                </div>
                <div className="form-group col-sm-2">
                  <button
                    className="btn btn-link"
                    type="button"
                    onClick={() => this.handleRemoveFields(index)}
                  >
                    -
                  </button>
                  <button
                    className="btn btn-link"
                    type="button"
                    onClick={() => this.handleAddFields()}
                  >
                    +
                  </button>
                </div>
              </div>
            ))}
          </div>
          <div className="submit-button">
            <button
              className="btn btn-primary mr-2"
              type="submit"
              // onSubmit={this.handleSubmit}
            >
              Save
            </button>
          </div>
          <br />
          <pre>{JSON.stringify(this.state.inputFields, null, 2)}</pre>
        </form>
      </>
    );
  }
}

export default App;

3 Answers 3

1

You approach is not the correct. Use object to contain form values

state = { 
    inputFields: { firstName: '', lastName: '' }
}


onChange = (e) => {
   const { name, value } = e.target;
   
   this.setState(prevState => ({ inputFields: { ...prevState.inputFields, [name]: value } }));
}


// in jsx

<input name="firstName" onChange={this.onChange} />

Sign up to request clarification or add additional context in comments.

Comments

1

try this onChange={(e)=>{this.onChange(e, index)}}

instead of

onChange={this.onChange.bind(index)}

Comments

0

1) Since your inputFields state is an array, you can't just call this.state.inputFields.firstName and even less inputField.firstName.

You have to call this.state.inputsFields[0].firstName.

 

2) If you want the index AND the event, you have to pass the onChange event like this :

<input
  type="text"
  className="form-control"
  id="lastName"
  name="lastName"
  onChange={event => this.handleChange(event, index)}
/>
  handleChange = (event, index) => {
    console.log(event.currentTarget.value, index);
  };
// output : {whatever you type} {index of the form}
// exemple : "hello 1"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.