Home > front end >  How to a make dynamic form in React
How to a make dynamic form in React

Time:10-31

I'm learning React. My target is to make this object:

"Phones": [
  {
    "Type": "Mobile",
    "Phone_Number": "6546543"
  },
  {
    "Type": "Home",
    "Phone_Number": "6546543"
  }
]

I did some research and I followed this YouTube video ReactJS - Dynamically Adding Multiple Input Fields.

These values I'll fetch from a form. Th user can keep on adding as many numbers as he wants. My code is:

  render() {
    return (
      <div>
        <h1>The Form</h1>
        <label>Contact</label>
        {this.state.phones.map((phone, index) => {
          return (
            <div key={index}>
              <input onChange={(e) => this.handleChange(e)} value={phone} />
              <select>
                {this.phoneTypes.map((phoneType, index) => {
                  return (
                    <option key={index} value={phoneType}>
                      {phoneType}
                    </option>
                  );
                })}
              </select>
              <button onClick={(e) => this.handleRemove(e)}>Remove </button>
            </div>
          );
        })}
        <hr />
        <button onClick={(e) => this.addContact(e)}>Add contact</button>
        <hr />
        <button onClick={(e) => this.handleSubmit(e)}>Submit</button>
      </div>
    );
  }

I'm not pasting the entire code here as I've already created a stackblitz. My code is not working as expected. Please pitch in.

CodePudding user response:

You need to pass index in the handleChange function for input field. I guess you missed that part from video.This will make the input field editable.

      <input
        onChange={(e) => this.handleChange(e, index)}
        value={phone}
      />

For the second part to get the expected object array I have updated some code, please check:

import React, { Component } from 'react';

class Questionnaire extends Component {
  state = {
    phones: [{ type: '', number: '' }],
  };

  phoneTypes = ['Mobile', 'Home', 'Office'];

  addContact() {
    this.setState({ phones: [...this.state.phones, { type: '', number: '' }] });
  }

  handleChange(e, index) {
    this.state.phones[index]['number'] = e.target.value;
    this.setState({ phones: this.state.phones });
  }

  handleRemove(index) {
    this.state.phones.splice(index, 1);
    console.log(this.state.phones, '$$$');
    this.setState({ phones: this.state.phones });
  }

  handleSubmit(e) {
    console.log(this.state, '$$$');
  }

  render() {
    return (
      <div>
        <h1>The Form</h1>
        <label>Contact</label>
        {this.state.phones.map((phone, index) => {
          return (
            <div key={index}>
              <input
                onChange={(e) => this.handleChange(e, index)}
                value={phone.number}
                name="number"
              />
              <select>
                {this.phoneTypes.map((phoneType, index) => {
                  return (
                    <option key={index} value={phoneType} name="type">
                      {phoneType}
                    </option>
                  );
                })}
              </select>
              <button onClick={(e) => this.handleRemove(e)}>Remove </button>
            </div>
          );
        })}
        <hr />
        <button onClick={(e) => this.addContact(e)}>Add contact</button>
        <hr />
        <button onClick={(e) => this.handleSubmit(e)}>Submit</button>
      </div>
    );
  }
}

export default Questionnaire;

CodePudding user response:

You can use input objects like formik

import { useState } from 'react';

const Component = () => {
    const [inputs, setInputs] = useState({ // Initial inputs
        email: "",
        phoneNumber: "",
    });

    const handleSubmit = (e) => {
        e.preventDefault();

        // Do
    };

    const handleChange = (e) => {
        setInputs({...inputs, [e.target.id]: e.target.value});
    };

    const addInput = () => {
        const name = window.prompt("Type a name", "");

        setInputs({...inputs, [name]: ""});
    };

    return (
        <form onSubmit={handleSubmit}>
            {object.keys(inputs).map((name, i) => {
                <input type="text" onChange={handleChange} name={name} value={inputs[name]} />
            })}

            <button
                type="button"
                onClick={addInput}
            >
            Add Input
            </button>
        </form>
    );
}
  • Related