Home > Back-end >  How to append particular input field one by one onClick in React
How to append particular input field one by one onClick in React

Time:10-01

I have a function react component which has an object consisting of different values that renders in react form.

const initialInputValues = {
  domain: '',
  title1: '',
  title2: '',
  title3: '',
  title4: '',
  title5: '',
  title6: '',
  title7: '',
  description1: '',
  description2: '',
};

const [values, setValues] = useState(initialInputValues);

//handling input
const handleInputChange = (e) => {
  const { name, value } = e.target;

  setValues({...values, [name]: value });
}

//handle submit
const handleSubmit = (e) => {
  e.preventDefault();
}

I have a reusable FormGroup component like this

<FormGroup
  label='Domain'
  name='domain'
  type='url'
  value={values.domain}
  onChange={handleInputChange}
/>
<FormGroup
  label='Title 1'
  name='title1'
  value={values.title1}
  onChange={handleInputChange}
/>
<FormGroup
  label='Title 2'
  name='title2'
  value={values.title2}
  onChange={handleInputChange}
/>
<FormGroup
  label='Title 2'
  name='title2'
  value={values.title2}
  onChange={handleInputChange}
/> 
<FormGroup
  label='Title 3'
  name='title3'
  value={values.title3}
  onChange={handleInputChange}
/>

I have a button under this FormGroup Title fields, now I want to append title4, title5, title6, title7 one by one on click of this Add button.

<button
  className='button__addField'
  type='button'
  onClick={handleAddTitle}
>
  Add Title
</button>

Is there any other way except using useRef and hide/show using CSS classes? I have tried that but looks like that is not a feasible solution if in future I want to expand title fields up to 12 or description fields up to 8 etc.

Codesandbox: Edit hungry-lake-8njbo0

export default function App() {
  const initialInputValues = {
    domain: "",
    title1: "",
    title2: "",
    title3: "",
    title4: "",
    title5: "",
    title6: "",
    title7: "",
    description1: "",
    description2: ""
  };

  const [values, setValues] = useState(initialInputValues);
  const [titleNum, setTitleNum] = useState(3)

  const handleInputChange = (e) => {
    const { name, value } = e.target;

    setValues({ ...values, [name]: value });
  };

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

  return (
    <div className="sidebar-area">
      <form className="form-area" onSubmit={handleSubmit}>
        <div className="form__buttons">
          <button className="button__share" value="Share" type="submit">
            Share
          </button>
          <button type="button" className="button__export">
            Export
          </button>
        </div>
        <div className="form__heading">
          <div className="heading__iconTitle">
            <h4 className="heading__title">Campaign Basics</h4>
          </div>
        </div>
        <FormGroup
          label="Domain"
          name="domain"
          type="url"
          value={values.domain}
          onChange={handleInputChange}
        />
        {Array.from({length: titleNum}, (_,i, ind = i   1) => (
          <FormGroup
          label= {`Title ${ind}`}
          name={`title${ind}`}
          value={values[`title${ind}`] || ''}
          onChange={handleInputChange}
        />
        ))}
        <div className="form__addField">
          <div>
            <button 
              className="button__addField" 
              type="button" 
              onClick={() => setTitleNum(prev => prev   1)}
            >
              Add Title
            </button>
          </div>
        </div>
        <div className="form__group__inlineField">
          <FormGroup
            label="Path 1"
            name="path1"
            value={values.path1}
            onChange={handleInputChange}
          />
          <FormGroup
            label="Path 2"
            name="path2"
            value={values.path2}
            onChange={handleInputChange}
          />
        </div>
        <FormGroup
          rows="2"
          label="Description Line 1"
          name="description1"
          value={values.description1}
          onChange={handleInputChange}
        />
        <FormGroup
          rows="2"
          label="Description Line 2"
          name="description2"
          value={values.description2}
          onChange={handleInputChange}
        />
      </form>
    </div>
  );
}

CodePudding user response:

If you are effectively wanting a dynamic list of titles then I'd suggest storing an array of titles in the state and appending to this array when you want to add another title input. You will want to use Edit how-to-append-particular-input-field-one-by-one-onclick-in-react

CodePudding user response:

it can be handle via dynamic state

  • Related