1

I want to do something like this.

  <form onSubmit={submitForm} className=''>        
  <div> 
  // this array is a dynamic set of fields inside the form           
     {items.map((input, i)=> (
       <div className="col-md-1 mb-4">
    <label htmlFor="inputResponse" className="form-label text-center" >
      <h5> Texto </h5>
    </label>              
  </div>
  <div className="row align-items-center row" key={i}>             
    <div className='col-10'>
      <input
        placeholder="desdeComponent"
        id={i}
        className='form-control mt-3'                    
        name={button value} // i would like the value of the button here.
        onChange= {handleChange((e) => e.target.name)}               
        type="text"
        required
      />
    </div>             
    ))
    }
  </div>
  
  <button className="btn btn-success me-4 mt-5"  type='submit'>AddSubmit</button>
</form>

I would have 3 buttons 'Add Text' 'Add Title' 'Add Link' The thing is that I would like to add fields dynamically in my form, every time that the user clicks on the buttons.

I want to reuse the 'input' and pass the button value like param to the name={button value}, and then submit the form with all the fields at the end.

The problem is when I click 'Add Text' the name value is text name='text'. When clicking 'Add Title', I create a new field in the form, but the name of the new field, and the old field, change to the name value to the last button that I clicked.

Is there some way to have this attribute for every field in the same array of fields?

const itemDataObject = {
    title_item_lateral: '' ,
    text_item_lateral: [],
    image_lateral: [
      {
        title_image_lateral: '',
        path_image_lateral: '',
      }
    ],
    document_lateral: [],
    links: [
      {
        title_link:'' ,
        link: ''
      }
    ]
  };

function to add fields:

let buttonPressed;
const addFields = (e) => {
    buttonPressed = e.target.value;
    setNameValue(buttonPressed);
    let newItemField = {itemDataObject};
      setItems([...items, newItemField]);          
    }

Some idea is how can i reuse and send the value to the name in every field. Thanks

p.s: Here is the full code: (buttons and class name are from Bootstrap 5)

import { useState } from "react";

const DemoLateral = () => {  
  
  const itemDataObject = {
    title_item_lateral: '' ,
    text_item_lateral: [],
    image_lateral: [
      {
        title_image_lateral: '',
        path_image_lateral: '',
      }
    ],
    document_lateral: [],
    links: [
      {
        title_link:'' ,
        link: ''
      }
    ]
  }; 
  
  let buttonPressed;
  const [nameValue, setNameValue] = useState(['inicial']);
  const addFields = (e) => {
    buttonPressed = e.target.value;
    setNameValue(buttonPressed);
    console.log(buttonPressed);      
    let newItemField;    
    newItemField = {itemDataObject};
    setItems([...items, newItemField]);    
  };
  
  const [items, setItems] = useState([]); 
  console.log(items);
  
  const handleChange = (name) => {
    console.log(name);
  };
  
  const submitForm = (e) => {
    e.preventDefault();   
  };
  
  return (
    <>      
      <h3 className="ms-5 mb-5"> AÑADIR ITEMS   </h3>
      <div className="container">
        <form onSubmit={submitForm} className=''>        
          <div> 
            {items.map((input, i, e)=> (
              <h2 key={i} name={e.target.value}> Hola {i}</h2>
            ))
            }
          </div>
          
          <button className="btn btn-success me-4 mt-5"  type='submit'>AddSubmit</button>
        </form>
        <div className="mt-5 text-center">          
          {/*  <button className="btn btn-primary me-4"  onClick={addTextItem}>Add Text</button> */}
          <button className="btn btn-primary me-4 mb-4" value='text' onClick={addFields}>Add Text</button>
          <button className="btn btn-primary me-4 mb-4" value='title' onClick={addFields}>Add Subtitle</button>
          <button className="btn btn-primary me-4 mb-4" value='image' onClick={addFields}>Add Image</button>
          <button className="btn btn-primary me-4 mb-4" value='document' onClick={addFields}>Add document</button>
          <button className="btn btn-primary me-4 mb-4" value='links' onClick={addFields}>Add Links</button>
          <button className="btn btn-primary me-4 mb-4" value='items' onClick={addFields}>Add Items</button>
        </div>
      </div>
    </>
  );
};
2
  • Paste all the related code, i tried to run, and it's missing a lot of methods Commented Jul 8, 2022 at 1:00
  • yes, this is the important part of the code that is used for this operation. if you want all, i can add it. Commented Jul 8, 2022 at 6:04

1 Answer 1

1

The problem that i found was that your were using as below, the third argument 'e' is the entire array, not the event, so e.target is undefined. I added the type inside the object here newItemField = { ...itemDataObject, button_pressed: buttonPressed };

<div> 
   {items.map((input, i, e)=> ( 
      <h2 key={i} name={e.target.value}> Hola {i}</h2>
      ))
   }
</div>

Maybe this can give you a start:

import { useState } from 'react';

const DemoLateral = () => {
    const itemDataObject = {
        title_item_lateral: '',
        text_item_lateral: [],
        image_lateral: [
            {
                title_image_lateral: '',
                path_image_lateral: '',
            },
        ],
        document_lateral: [],
        links: [
            {
                title_link: '',
                link: '',
            },
        ],
    };

    let buttonPressed;

    const [nameValue, setNameValue] = useState(['inicial']);

    const addFields = (e) => {
        buttonPressed = e.target.value;
        setNameValue(buttonPressed);
        console.log('setNameValue: ', buttonPressed);
        let newItemField;
        newItemField = { ...itemDataObject, button_pressed: buttonPressed };
        setItems([...items, newItemField]);
        console.log('Items: ', items);
    };

    const [items, setItems] = useState([]);

    const handleChange = (name) => {
        console.log(name);
    };

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

    return (
        <>
            <h3 className="ms-5 mb-5"> AÑADIR ITEMS </h3>
            <div className="container">
                <div className="mt-5 text-center">
                    {/*  <button className="btn btn-primary me-4"  onClick={addTextItem}>Add Text</button> */}
                    <button className="btn btn-primary me-4 mb-4" value="text" onClick={addFields}>
                        Add Text
                    </button>
                    <button className="btn btn-primary me-4 mb-4" value="title" onClick={addFields}>
                        Add Subtitle
                    </button>
                    <button className="btn btn-primary me-4 mb-4" value="image" onClick={addFields}>
                        Add Image
                    </button>
                    <button className="btn btn-primary me-4 mb-4" value="document" onClick={addFields}>
                        Add document
                    </button>
                    <button className="btn btn-primary me-4 mb-4" value="links" onClick={addFields}>
                        Add Links
                    </button>
                    <button className="btn btn-primary me-4 mb-4" value="items" onClick={addFields}>
                        Add Items
                    </button>
                    <button className="btn btn-success me-4 mt-5" value="submit" onClick={addFields}>
                        AddSubmit
                    </button>
                </div>
                <form onSubmit={submitForm} className="">
                    <div>
                        {items.map((input, i) => (
                            <h3 key={i} name={input.button_pressed}>
                                {input.button_pressed} {i}
                            </h3>
                        ))}
                    </div>
                </form>
            </div>
        </>
    );
};

export default DemoLateral;
Sign up to request clarification or add additional context in comments.

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.