I have this object:
const itemDataObject = { sort: '', title_item_lateral: '', text_item_lateral: '', image_lateral: [ { title_image_lateral: '', path_image_lateral: '', }, ], document_lateral: '', links: [ { title_link: '', link: '', }, ], };
and i need to fill it in a form.
i use this function:
const handleChange = (i, e) => { let itemData = [...item_lateral]; itemData[i][e.target.name]=e.target.value; setItems(itemData); setNewLateral({...lateral, item_lateral, title_lateral}); handleChangeChat(e); };
and this inside the form:
<div> {item_lateral.map((input, i) => ( <> { !(input.button_pressed === 'image' || input.button_pressed === 'links') && <div className="row align-item_lateral-center" key= {input.button_pressed + i + 1}> <div className="col-2 mt-3"> <h3>{input.button_pressed}</h3> </div> <div className="col-10"> <input placeholder={input.button_pressed} id={i} className='form-control mt-3' name={input.button_pressed} onChange= {e => handleChange(i, e)} type="text" /> </div> </div> } { input.button_pressed === 'image' && <> <div className="row align-item_lateral-center row" key= {input.button_pressed + i + 2}> <div className="col-2"> <h3>Imagen: </h3> </div> <div className='col-10'> <input placeholder='title_image_lateral' id={i} className='form-control mt-3' name='title_image_lateral' onChange= {e => handleChange(i, e)} type="text" /> </div> </div> <div className="row align-item_lateral-center row" key= {input.button_pressed + i + 1}> <div className="col-2"> <h3>Image Path: </h3> </div> <div className='col-10'> <input placeholder='path_image_lateral' id={i} className='form-control mt-3' name='path_image_lateral' onChange= {e => handleChange(i, e)} type="text" /> </div> </div> </> } {input.button_pressed === 'links' && <> <div className="row align-item_lateral-center row" key= {input.button_pressed + i+2}> <div className="col-2"> <h3>Title Link: </h3> </div> <div className="col-8"> <input placeholder='titel_link' id={i} className='form-control mt-3' name='titel_link' onChange= {e => handleChange(i, e)} type="text" /> </div> </div> <div className="row align-item_lateral-center row" key={i}> <div className="col-2"> <h3>Link: </h3> </div> <div className="col-8"> <input placeholder='link' id={i} className='form-control mt-3' name='link' onChange= {e => handleChange(i, e)} type="text" /> </div> </div> </> } </> ))} </div>
The form works onsubmit, and create values in the object with the property name, and the value.
But if the property (p.e: ‘title_image_lateral’), not put the new value in the correct place in the object, instead create a new element in the root of the object: title_image_lateral: (value submited in the form).
I thik that i can change the ‘root’ for the itemData[i][e.target.name]=e.target.value; , but i can not achieve.
Maybe i can create state for this values, and then onsubmit the form, set in the object…but maybe is made a big surround.
Some light for my issue.
Thanks.
Here the entire file:
import { useState } from "react"; import { useDispatch, useSelector } from "react-redux"; const LateralWindow = ({token}) => { const itemDataObject = { sort: '', title_item_lateral: '', text_item_lateral: '', image_lateral: [ { title_image_lateral: '', path_image_lateral: '', }, ], document_lateral: '', links: [ { title_link: '', link: '', }, ], }; const dispatch = useDispatch(); const generalInfo = useSelector(state=> state.faqsGralInfo); const { description, typeResponse, rolViews, workLoadLevel, id, id_intent, corpusArea, corpusName, } = generalInfo; const [ finalResponse, setFinalResponse ] = useState({}); const [ newJsonResponse, setNewJsonResponse ] = useState( {}); const [ title_lateral, setTitleLateral ] = useState(''); const [ item_lateral, setItems ] = useState([]); const [ lateral, setNewLateral] = useState({ title_lateral: title_lateral, item_lateral: [item_lateral] }); let buttonPressed; const [nameValue, setNameValue] = useState(['inicial']); console.log(nameValue); const addFields = (e) => { e.preventDefault(); buttonPressed = e.target.value; setNameValue(buttonPressed); let newItemField; newItemField = { ...itemDataObject, button_pressed: buttonPressed }; setItems([...item_lateral, newItemField]); }; const handleChangeChat = (e) => { setFinalResponse({...finalResponse, [e.target.name]: e.target.value}); setNewJsonResponse({ ...newJsonResponse, accesToken: token, newDataResponse: { description, typeResponse, rolViews, workLoadLevel, id, id_intent, response_json_new:{finalResponse, lateral}, corpusArea, corpusName, lateral_W: generalInfo.lateral_W === 'true' ? 1 : 0 , } }, ); }; const handleChange = (i, e) => { let itemData = [...item_lateral]; itemData[i][e.target.name]=e.target.value; setItems(itemData); setNewLateral({...lateral, item_lateral, title_lateral}); handleChangeChat(e); }; const submitForm = (e) => { e.preventDefault(); }; const sendToCorpus = () => { /* setTimeout(() => { window.location = '/corpus'; }, 3000); */ }; return ( <> <div className="card mb-3"> <div className="card-body"> <h2> Diseño Chat </h2> <form className="row mt-4" onSubmit={submitForm} > <div className="col-md-1 mb-4"> <label htmlFor="inputDescription" className="form-label text-center"> <h5> Título </h5> </label> </div> <div className="col-md-11"> <input type="text" className="form-control" name='title' onChange={handleChangeChat} id="inputDescription" required /> </div> <div className="col-md-1 mb-4"> <label htmlFor="inputResponse" className="form-label text-center" > <h5> Texto </h5> </label> </div> <div className="col-md-11"> <input type="textarea" className="form-control" name='text' onChange={handleChangeChat} id="inputResponse" required /> </div> <div className="col-md-1 mb-4"> <label htmlFor="link" className="form-label text-center" > <h5> Link </h5> </label> </div> <div className="col-md-5"> <input type="link" className="form-control" name="link" onChange={handleChangeChat} id="link" required /> </div> <div className="col-md-1"> <label htmlFor="link_title" className="form-label text-center" > <h5> Title Link </h5> </label> </div> <div className="col-md-5"> <input type="text" className="form-control" name='link_title' onChange={handleChangeChat} id="link_title" required /> </div> <div className="col-md-1 mb-4"> <label htmlFor="image" className="form-label text-center" > <h5> Image </h5> </label> </div> <div className="col-md-5"> <input type="file" className="form-control" name="image" onChange={handleChangeChat} id="image" required /> </div> <div className="col-md-1"> <label htmlFor="image_title" className="form-label text-center" > <h5> Title Image </h5> </label> </div> <div className="col-md-5"> <input type="text" className="form-control" name='image_title' onChange={handleChangeChat} id="image_title" required /> </div> <div className="mt-5" > <h3>DISEÑO VENTANA LATERAL</h3> </div> <h5 className="ms-5 mb-5 mt-5"> Diseña tu respuesta añadidendo subtitulos, texto, imagenes, documentos y enlaces. Puedes seleccionarlos con el orden que mejor se ajuste a tu respuesta. Y puedes poner tantos elementos como quieras. </h5> <div className="container"> <div className="row align-item_lateral-center" > <div className="col-2 mt-3"> <h3>Título Ventana Lateral</h3> </div> <div className="col-10"> <input placeholder= 'Título Ventana Lateral' className='form-control mt-3' value={title_lateral} onChange= {e=> setTitleLateral(e.target.value)} type="text" /> </div> </div> <div> {item_lateral.map((input, i) => ( <> { !(input.button_pressed === 'image' || input.button_pressed === 'links') && <div className="row align-item_lateral-center" key={input.button_pressed + i + 1}> <div className="col-2 mt-3"> <h3>{input.button_pressed}</h3> </div> <div className="col-10"> <input placeholder={input.button_pressed} id={i} className='form-control mt-3' name={input.button_pressed} onChange= {e => handleChange(i, e)} type="text" /> </div> </div> } { input.button_pressed === 'image' && <> <div className="row align-item_lateral-center row" key={input.button_pressed + i + 2}> <div className="col-2"> <h3>Imagen: </h3> </div> <div className='col-10'> <input placeholder='title_image_lateral' id={i} className='form-control mt-3' name='title_image_lateral' onChange= {e => handleChange(i, e)} type="text" /> </div> </div> <div className="row align-item_lateral-center row" key={input.button_pressed + i + 1}> <div className="col-2"> <h3>Image Path: </h3> </div> <div className='col-10'> <input placeholder='path_image_lateral' id={i} className='form-control mt-3' name='path_image_lateral' onChange= {e => handleChange(i, e)} type="text" /> </div> </div> </> } {input.button_pressed === 'links' && <> <div className="row align-item_lateral-center row" key={input.button_pressed + i+2}> <div className="col-2"> <h3>Title Link: </h3> </div> <div className="col-8"> <input placeholder='titel_link' id={i} className='form-control mt-3' name='titel_link' onChange= {e => handleChange(i, e)} type="text" /> </div> </div> <div className="row align-item_lateral-center row" key={i}> <div className="col-2"> <h3>Link: </h3> </div> <div className="col-8"> <input placeholder='link' id={i} className='form-control mt-3' name='link' onChange= {e => handleChange(i, e)} type="text" /> </div> </div> </> } </> ))} </div> <div className="mt-5 text-center"> <button className="btn btn-primary me-4 mb-4" value="text_item_lateral" onClick={addFields}> Add Text </button> <button className="btn btn-primary me-4 mb-4" value="title_item_lateral" 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_lateral" onClick={addFields}> Add document </button> <button className="btn btn-primary me-4 mb-4" value="links" onClick={addFields}> Add Links </button> </div> </div> <div> </div> <div> {(isCreated && isVariationsSave) && <div className="alert alert-success" role='alert'> Respuesta CREADA Correctamente </div> } {isCreated && sendToCorpus()} </div> <button className="btn btn-warning me-5 mb-3" type="submit" >Preview</button> <button className="btn btn-success me-5 mb-3" type="submit">Guardar Respuesta</button> </form> <div className="text-center"> </div> </div> </div> </> ); }; export default LateralWindow;
Advertisement
Answer
Check if this suits your needs:
import { useState } from "react"; import { useSelector } from "react-redux"; const LateralWindow = ({ token }) => { const itemDataObject = { sort: "", title_item_lateral: "", text_item_lateral: "", image_lateral: { title_image_lateral: "", path_image_lateral: "", }, document_lateral: "", links: { title_link: "", link: "", }, }; const generalInfo = useSelector((state) => state.faqsGralInfo); const { description, typeResponse, rolViews, workLoadLevel, id, id_intent, corpusArea, corpusName } = generalInfo; const [finalResponse, setFinalResponse] = useState({}); const [newJsonResponse, setNewJsonResponse] = useState({}); const [title_lateral, setTitleLateral] = useState(""); const [item_lateral, setItems] = useState([]); const [lateral, setNewLateral] = useState({ title_lateral: title_lateral, item_lateral: [item_lateral], }); let buttonPressed; const addFields = (e) => { e.preventDefault(); buttonPressed = e.target.value; let newItemField; newItemField = { ...itemDataObject, button_pressed: buttonPressed }; setItems([...item_lateral, newItemField]); }; const handleChangeChat = (e) => { setFinalResponse({ ...finalResponse, [e.target.name]: e.target.value }); setNewJsonResponse({ ...newJsonResponse, accesToken: token, newDataResponse: { description, typeResponse, rolViews, workLoadLevel, id, id_intent, response_json_new: { finalResponse, lateral }, corpusArea, corpusName, lateral_W: generalInfo.lateral_W === "true" ? 1 : 0, }, }); }; const handleChange = (i, e) => { let itemData = [...item_lateral]; let elementChanged = e.target; let name = elementChanged.name; let value = elementChanged.value; if (name === "title_image_lateral" || name === "path_image_lateral") { itemData[i].image_lateral[name] = value; } else if (name === "title_link" || name === "link") { itemData[i].links[name] = value; } else { itemData[i][name] = value; } setItems(itemData); setNewLateral({ ...lateral, item_lateral, title_lateral }); handleChangeChat(e); }; const submitForm = (e) => { console.log(item_lateral); e.preventDefault(); }; return ( <> <div className="card mb-3"> <div className="card-body"> <h2> Diseño Chat </h2> <form className="row mt-4" onSubmit={submitForm}> <div className="col-md-1 mb-4"> <label htmlFor="inputDescription" className="form-label text-center"> <h5> Título </h5> </label> </div> <div className="col-md-11"> <input type="text" className="form-control" name="title" value="Titulo" onChange={handleChangeChat} id="inputDescription" required /> </div> <div className="col-md-1 mb-4"> <label htmlFor="inputResponse" className="form-label text-center"> <h5> Texto </h5> </label> </div> <div className="col-md-11"> <input type="textarea" className="form-control" name="text" value="Texto" onChange={handleChangeChat} id="inputResponse" required /> </div> <div className="col-md-1 mb-4"> <label htmlFor="link" className="form-label text-center"> <h5> Link </h5> </label> </div> <div className="col-md-5"> <input type="link" className="form-control" name="link" value="link" onChange={handleChangeChat} id="link" required /> </div> <div className="col-md-1"> <label htmlFor="link_title" className="form-label text-center"> <h5> Title Link </h5> </label> </div> <div className="col-md-5"> <input type="text" className="form-control" name="link_title" value="testeLink" onChange={handleChangeChat} id="link_title" required /> </div> <div className="col-md-1 mb-4"> <label htmlFor="image" className="form-label text-center"> <h5> Image </h5> </label> </div> <div className="col-md-5"> <input type="file" className="form-control" name="image" onChange={handleChangeChat} id="image" required /> </div> <div className="col-md-1"> <label htmlFor="image_title" className="form-label text-center"> <h5> Title Image </h5> </label> </div> <div className="col-md-5"> <input type="text" className="form-control" name="image_title" value="title image" onChange={handleChangeChat} id="image_title" required /> </div> <div className="mt-5"> <h3>DISEÑO VENTANA LATERAL</h3> </div> <h5 className="ms-5 mb-5 mt-5"> Diseña tu respuesta añadidendo subtitulos, texto, imagenes, documentos y enlaces. Puedes seleccionarlos con el orden que mejor se ajuste a tu respuesta. Y puedes poner tantos elementos como quieras.{" "} </h5> <div className="container"> <div className="row align-item_lateral-center"> <div className="col-2 mt-3"> <h3>Título Ventana Lateral</h3> </div> <div className="col-10"> <input placeholder="Título Ventana Lateral" className="form-control mt-3" value={title_lateral} onChange={(e) => setTitleLateral(e.target.value)} type="text" /> </div> </div> <div className="mt-5 text-center"> <button className="btn btn-primary me-4 mb-4" value="text_item_lateral" onClick={addFields}> Add Text </button> <button className="btn btn-primary me-4 mb-4" value="title_item_lateral" 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_lateral" onClick={addFields}> Add document </button> <button className="btn btn-primary me-4 mb-4" value="links" onClick={addFields}> Add Links </button> </div> <div> {item_lateral.map((input, i) => { return ( <div key={input.button_pressed + i}> {!(input.button_pressed === "image" || input.button_pressed === "links") && ( <div className="row align-item_lateral-center"> <div className="col-2 mt-3"> <h3>{input.button_pressed}</h3> </div> <div className="col-10"> <input placeholder={input.button_pressed} id={i} className="form-control mt-3" name={input.button_pressed} onChange={(e) => handleChange(i, e)} type="text" /> </div> </div> )} {input.button_pressed === "image" && ( <> <div className="row align-item_lateral-center row"> <div className="col-2"> <h3>Imagen: </h3> </div> <div className="col-10"> <input placeholder="title_image_lateral" id={i} className="form-control mt-3" name="title_image_lateral" onChange={(e) => handleChange(i, e)} type="text" /> </div> </div> <div className="row align-item_lateral-center row"> <div className="col-2"> <h3>Image Path: </h3> </div> <div className="col-10"> <input placeholder="path_image_lateral" id={i} className="form-control mt-3" name="path_image_lateral" onChange={(e) => handleChange(i, e)} type="text" /> </div> </div> </> )} {input.button_pressed === "links" && ( <> <div className="row align-item_lateral-center row"> <div className="col-2"> <h3>Title Link: </h3> </div> <div className="col-8"> <input placeholder="title_link" id={i} className="form-control mt-3" name="title_link" onChange={(e) => handleChange(i, e)} type="text" /> </div> </div> <div className="row align-item_lateral-center row"> <div className="col-2"> <h3>Link: </h3> </div> <div className="col-8"> <input placeholder="link" id={i} className="form-control mt-3" name="link" onChange={(e) => handleChange(i, e)} type="text" /> </div> </div> </> )} </div> ); })} </div> </div> <div></div> <div> {isCreated && isVariationsSave && ( <div className="alert alert-success" role="alert"> Respuesta CREADA Correctamente </div> )} {isCreated && sendToCorpus()} </div> <button className="btn btn-warning me-5 mb-3" type="submit"> Preview </button> <button className="btn btn-success me-5 mb-3" type="submit"> Guardar Respuesta </button> </form> <div className="text-center"></div> </div> </div> </> ); }; export default LateralWindow;