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;
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;
I am a bit of a newbie in React, but I would like to master it. Fetching data was initially challenging, but now I have to post the form data back to the JSON file, could you kindly help me with this one!?
bit of info, I am getting data from data.json via App.js
it has a basic structure ready like such:
"payment": [
{
"nameId": 2,
"amount": 10,
"currency": "",
"id": 1
}]
Additionally can someone suggest a way that I can make the post conditional, which means, the user HAS to select a radio button, and then only the user can click pay!? Thank you in advance.
import React from 'react'
import './card-style.css'
import { useState } from 'react'
import ReactCardFlip from 'react-card-flip'
import { AiOutlineClose } from 'react-icons/ai'
import Axios from 'axios'
const CardUI = ({ charity }) => {
return (
<div className='section-center'>
{charity.map((charityInfo) => {
const { id, name, image } = charityInfo
return <SingleCardUI id={id} name={name} image={image} />
})}
</div>
)
}
function formSubmit() {
return window.alert('Thank you')
}
function SingleCardUI(props) {
const [isFlipped, setIsFlipped] = useState(false)
const handleClick = () => {
setIsFlipped(!isFlipped)
}
return (
<article key={props.id} className='page-item'>
<ReactCardFlip isFlipped={isFlipped} flipDirection='vertical'>
<div className='card text-center shadow'>
<div className='overflow location-front-item'>
<img
src={props.image}
alt={props.name}
className='card-img-top hova location-front-image'
/>
</div>
<div className='card-body text-dark'>
<div className='titletxt'>
<h4 className='card-title'>{props.name}</h4>
</div>
<div className='linkbtn'>
<button
className='btn btn-sm btn-outline-primary front-flip-button'
id
onClick={handleClick}
>
Donate
</button>
</div>
</div>
</div>
{/* ... */}
{/* BACK ITEM */}
{/* ... */}
<div className='card text-center shadow'>
<div className='location-back-item'>
<img
src={props.image}
alt={props.name}
className='card-img-top location-back-image'
style={{ opacity: 0.15 }}
/>
<div className='card-img-overlay'>
{/* ICON */}
<div>
<span
className='btn btn-sm back-flip-button close'
onClick={handleClick}
>
<AiOutlineClose />
</span>
</div>
<div className='container back-init'>
<b>
<p>Select the amount to donate (USD)</p>
</b>
{/* 10 */}
<div
className='form-check form-check-inline'
onSubmit={formSubmit}
>
<input
className='form-check-input'
type='radio'
name='inlineRadioOptions'
id='inlineRadio1'
value='option1'
/>
<label className='form-check-label' htmlFor='inlineRadio1'>
10
</label>
{/* 20 */}
</div>
<div className='form-check form-check-inline'>
<input
className='form-check-input'
type='radio'
name='inlineRadioOptions'
id='inlineRadio2'
value='option2'
/>
<label className='form-check-label' htmlFor='inlineRadio2'>
20
</label>
</div>
{/* 50 */}
<div className='form-check form-check-inline'>
<input
className='form-check-input'
type='radio'
name='inlineRadioOptions'
id='inlineRadio3'
value='option3'
/>
<label className='form-check-label' htmlFor='inlineRadio3'>
50
</label>
</div>
{/* 100 */}
<div className='form-check form-check-inline'>
<input
className='form-check-input'
type='radio'
name='inlineRadioOptions'
id='inlineRadio4'
value='option4'
/>
<label className='form-check-label' htmlFor='inlineRadio4'>
100
</label>
</div>
{/* 200 */}
<div className='form-check form-check-inline'>
<input
className='form-check-input'
type='radio'
name='inlineRadioOptions'
id='inlineRadio5'
value='option5'
/>
<label className='form-check-label' htmlFor='inlineRadio5'>
200
</label>
</div>
{/* 500 */}
<div className='form-check form-check-inline'>
<input
className='form-check-input'
type='radio'
name='inlineRadioOptions'
id='inlineRadio6'
value='option6'
/>
<label className='form-check-label' htmlFor='inlineRadio6'>
500
</label>
</div>
<div className='container-fluid'>
<div className='pay'>
<button
className='btn btn-sm btn-outline-primary back-flip-button'
onClick={handleClick}
type='submit'
>
Pay
</button>
</div>
</div>
</div>
</div>
</div>
<div className='card-body text-dark empty'></div>
</div>
</ReactCardFlip>
</article>
)
}
export default CardUI
You can not access the filesystem in React, because it runs on the browser. You will need to create a server-side API for those operations.
i'm new in coding and i I still have a problem with if else condition, i have 2 authentication and one back end , one for react native and one for react ,
in Login i want to add is_store , i want to tell the system that if the username & password correct and is_sore = true , make him logged in and if the password right and the username right BUT is_store = false don't logged him in
i'm trying to pass is_store to Login component
i tried if condition but it give me wrong alert
Signup component
class RegistationForm extends Component {
state = {
username: "",
phone_number: "",
password: "",
email: "",
is_store: true <--- i want to pass it to Login
};
componentWillUnmount() {
this.props.errors.length && this.props.resetError();
}
changeHandler = e => {
this.setState({ [e.target.name]: e.target.value });
};
submitHandler = async e => {
e.preventDefault();
this.props.signup(this.state, this.props.history);
};
render() {
return (
<div className="container">
<div
style={{ marginTop: "125px" }}
className="card o-hidden border-0 shadow-lg col-12"
>
<div className="card-body p-0">
<div className="row">
<div className="col-lg-5 d-none d-lg-block bg-register-image col-12" />
<div className="col-lg-7 col-12">
<div className="p-5">
<div className="text-center col-12">
<h1 className="h4 text-gray-900 mb-4 col-12">
إنشاء حساب جديد
</h1>
</div>
<div className="text-center col-12">
{!!this.props.errors.length && (
<div className="text-left alert alert-danger">
{this.props.errors.map(error => (
<li key={error}>{error}</li>
))}
</div>
)}
</div>
<form onSubmit={this.submitHandler}>
<div className="form-group row">
<div className="col-sm-6 mb-3 mb-sm-0">
<Input
name="username"
value={this.state.username}
onChange={this.changeHandler}
className="form-control form-control-user"
placeholder=" السجل التجاري"
required
/>
</div>
<div className="col-sm-6 mb-3 mb-sm-0">
<Input
name="phone_number"
value={this.state.phone_number}
type="tel"
onChange={this.changeHandler}
className="form-control form-control-user"
placeholder="Mobile Ex: 966555555555"
required
pattern="[0-9]{12}"
/>
</div>
<br />
<br />
<div className="col-sm-6 mb-3 mb-sm-0">
<Input
name="password"
value={this.state.password}
onChange={this.changeHandler}
type="password"
className="form-control form-control-user"
placeholder="الرقم السري"
required
/>
</div>
<div className="col-sm-6 mb-3 mb-sm-0 ">
<Input
name="email"
value={this.state.email}
onChange={this.changeHandler}
type="email"
className="form-control form-control-user"
placeholder="الإيميل"
required
/>
</div>
<div className="col-12">
<button
style={{ padding: 9, marginTop: 20 }}
type="submit"
className="btn btn-success col-12 "
>
إنشئ حساب
</button>
</div>
</div>
</form>
<div className="text-center">
<Link to="/login" className="small">
املك حساب من قبل: تسجيل الدخول
</Link>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
Login component
class Login extends Component {
state = {
username: "",
password: "",
is_store: false <-- is here the right place?
};
componentWillUnmount() {
this.props.errors.length && this.props.resetError();
}
changeHandler = e => {
this.setState({ [e.target.name]: e.target.value });
};
submitHandler = async e => {
e.preventDefault();
## here is what i'm trying to do with is_store
if (this.state.is_store === true) {
this.props.login(this.state, this.props.history);
} else {
alert("Wrong");
}
};
render() {
return (
<div className="container">
<div className="row justify-content-center" style={{ marginTop: 125 }}>
<div className="col-xl-10 col-lg-12 col-md-9">
<div className="card o-hidden border-0 shadow-lg my-5">
<div className="card-body p-0">
<div className="row">
<div className="col-lg-6 d-none d-lg-block bg-login-image" />
<div className="col-lg-6">
<div className="p-5">
<div className="text-left">
<h1 className="h4 text-gray-900 mb-4">تسجيل الدخول</h1>
{!!this.props.errors.length && (
<div className="alert alert-danger" role="alert">
{this.props.errors.map(error => (
<li key={error}>{error}</li>
))}
</div>
)}
</div>
<form onSubmit={this.submitHandler}>
<div
className="form-group col-12"
style={{ padding: 0 }}
>
<Input
name="username"
className="form-control form-control-user"
onChange={this.changeHandler}
value={this.state.username}
placeholder="رقم السجل التجاري"
/>
</div>
<div
className="form-group col-12"
style={{ padding: 0 }}
>
<Input
type="password"
className="form-control form-control-user"
name="password"
value={this.state.passsword}
onChange={this.changeHandler}
placeholder="الرقم السري"
/>
</div>
<button
style={{ padding: 9 }}
type="submit"
className="btn btn-primary col-12"
>
دخول
</button>
<hr />
</form>
<hr />
<div className="text-center">
<NavLink to={`/signup`}>إنشاء حساب جديد</NavLink>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
this is authentication actions
export const login = (userData, history) => {
return async dispatch => {
try {
let response = await instance.post("user/login/", userData);
let user = response.data;
setAuthToken(user.token);
let decodedUser = jwt_decode(user.token);
dispatch(setCurrentUser(decodedUser));
history.push("/home");
} catch (error) {
console.log("error", error);
dispatch(setErrors(error.response.data));
}
};
};
thank you
In general, You can pass a state to a child component only. You can not pass a state from a child to its parent component.
In order to pass state to a parent component, you need to store that value. You can do it with Redux. Which stores the values and you can get that value in any component.
I have a table that shows a list of projects. When I click on a row to render a Modal, how do I prefill my input fields with data that I clicked on and then edit the fields so the state can be updated with the new data that I provide?
Here's my code breakdown with respective files:
Project.js
const Project = ({ companies, projects }) => {
return(
<div>
<section id={styles.project} className="divider overlay-light" data-bg-img="http://placehold.it/1920x1280">
<div className={`container ${styles.wrapper}`}>
<div className="row">
<div className={`col-md-12 ${styles['proj-header']}`}>
<h2 className="title">Projects</h2>
<button type="button" className={`btn ${styles['btn-project']}`} data-toggle="modal" data-target="#createProject">Create New Project</button>
{
companies.map((company, i) => {
return <CreateProjectModal key={i} company={company} />
})
}
</div>
</div>
<ManageColumns />
<div className="row">
<div className="col-md-12">
<div className={`${styles['table-responsive']} ${styles['dashboard-overview']} tableContainer`}>
<table className={`table table-striped scrollTable`}>
<thead className="fixedHeader">
<tr>
<th>Project Name <i className="fas fa-sort-amount-down"></i></th>
<th>Project Description</th>
<th>Action</th>
</tr>
</thead>
<tbody className="scrollContent">
{
projects.map((project, i) => {
return (
<tr key={i}>
<td>{project.project_name}</td>
<td>{project.description}</td>
<td>
<EditProjectModal projects={projects} />
</td>
</tr>
);
})
}
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
</div>
)
}
export default Project;
CreateProjectModal.js
class CreateProjectModal extends Component {
constructor(props) {
super(props);
this.state = {
project_name: '',
description: ''
}
}
onProjectNameChange(event) { this.setState({ project_name: event.target.value }); }
onDescriptionChange(event) { this.setState({ description: event.target.value }); }
handleSubmit(company) {
fetch(`http://localhost:5000/companys/${company._id['$oid']}/projects`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
project: {
project_name: this.state.project_name,
description: this.state.description
}
})
})
.then(response => response.json())
.then(data => { return data })
.catch(err => console.log(err));
}
render() {
const { company } = this.props;
return(
<div>
<div id="createProject" className="modal fade" tabIndex="-1" role="dialog">
<div className={`modal-dialog modal-lg ${styles['create-proj-modal']}`}>
<div className="modal-content">
<div className={`modal-header ${styles['create-proj-modal-header']}`}>
<button type="button" className={`close ${styles.closeModal}`} data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h3 className="modal-title" id="myModalLabel2">Create New Project</h3>
</div>
<div className={`modal-body ${styles['proj-modal-body']}`}>
<form>
<div className={`form-group ${styles.formGroup} ${styles.projName}`}>
<label htmlFor="project-name" className="col-form-label">Project Name</label>
<input type="text" className="form-control" id="project-name" name="project_name" onChange={(e) => onProjectNameChange(e, this.state)} />
</div>
<div className={`form-group ${styles.formGroup}`}>
<label htmlFor="description" className="col-form-label">Description</label>
<textarea className="form-control" id="description" rows="4" name="description" onChange={(e) => onDescriptionChange(e, this.state)} ></textarea>
</div>
</form>
</div>
<div className={`modal-footer ${styles.modalFooter}`}>
<button type="button" className={`btn btn-primary text-white ${styles.saveBtn}`} onClick={() => handleSubmit(company)}>Save Project</button>
<button type="button" className={`btn btn-default ${styles.cancelBtn}`} data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default CreateProjectModal;
EditProjectModal.js
class EditProjectModal extends Component {
constructor(props) {
super(props);
this.state = {
project_name: '',
description: ''
}
}
onProjectNameChange(event) { this.setState({ project_name: event.target.value }); }
onDescriptionChange(event) { this.setState({ description: event.target.value }); }
handleSubmit(project) {
fetch(`http://localhost:5000/projects/${project._id['$oid']}`, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
project: {
project_name: this.state.project_name,
description: this.state.description
}
})
})
.then(response => response.json())
.then(data => { return data })
.catch(err => console.log(err));
}
render() {
const { project } = this.props;
return(
<div className="btn-group">
<NavLink type="button" to="#" className={`${styles['pencil-link']}`} data-toggle="modal" data-target="#editProject">
<i className={`fas fa-pencil-alt ${styles.pencil}`}></i>
</NavLink>
<div id="editProject" className="modal fade" tabIndex="-1" role="dialog">
<div className={`modal-dialog modal-lg ${styles['create-proj-modal']}`}>
<div className="modal-content">
<div className={`modal-header ${styles['create-proj-modal-header']}`}>
<button type="button" className={`close ${styles.closeModal}`} data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h3 className="modal-title" id="myModalLabel2">Edit Project</h3>
</div>
<div className={`modal-body ${styles['proj-modal-body']}`}>
<form>
<div className={`form-group ${styles.formGroup} ${styles.projName}`}>
<label htmlFor="project-name" className="col-form-label">Project Name</label>
<input type="text" className="form-control" id="project-name" name="project_name" onChange={this.onProjectNameChange.bind(this)} />
</div>
<div className={`form-group ${styles.formGroup}`}>
<label htmlFor="description" className="col-form-label">Description</label>
<textarea className="form-control" id="description" rows="4" name="description" onChange={this.onDescriptionChange.bind(this)}></textarea>
</div>
</form>
</div>
<div className={`modal-footer ${styles.modalFooter} ${styles.editModalFooter}`}>
<button type="button" className={`btn btn-default ${styles.cancelBtn}`} data-dismiss="modal">Cancel</button>
<button type="button" className={`btn btn-primary text-white ${styles.saveBtn}`} onClick={(e) => this.handleSubmit(project)}>Save Changes</button>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default EditProjectModal;
First of all you need to pass the current row project details as a props to the EditProjectModal when you are filling the projects table (I named it theProject):
<tbody className="scrollContent">
{
projects.map((project, i) => {
return (
<tr key={i}>
<td>{project.project_name}</td>
<td>{project.description}</td>
<td>
<EditProjectModal projects={projects} theProject={project} />
</td>
</tr>
);
})
}
</tbody>
Then in the EditProjectModal, You can set it in the state like this:
constructor(props) {
super(props);
this.state = {
project_name: this.props.theProject.project_name,
description: this.props.theProject.description
}
}
}
Then you need to set the value of the inputs in the EditProjectModal with the state like this:
<form>
<div className={`form-group ${styles.formGroup} ${styles.projName}`}>
<label htmlFor="project-name" className="col-form-label">Project Name</label>
<input type="text" className="form-control" id="project-name"
name="project_name"
value={this.state.project_name}
onChange={this.onProjectNameChange.bind(this)} />
</div>
<div className={`form-group ${styles.formGroup}`}>
<label htmlFor="description" className="col-form-label">Description</label>
<textarea className="form-control" id="description"
rows="4" name="description"
value={this.state.description}
onChange={this.onDescriptionChange.bind(this)}></textarea>
</div>
</form>
The edit form can be initialized by passing the row details as props to the EditProjectModal and the props can be assigned as state of EditProjectModal for making the handling easy.Then you can give value to the input and textarea using the value attribute.The value attribute can be given the corresponding state.
class EditProjectModal extends Component {
constructor(props) {
super(props);
this.state = {
project_name: '',
description: ''
}
}
ComponentWillMount() {
this.setState(project_name: this.props.project.project_name,description:this.props.project.description)
}
render() {
....//rest of the code
<form>
<div className={`form-group ${styles.formGroup} ${styles.projName}`}>
<label htmlFor="project-name" className="col-form-label">Project Name</label>
<input type="text" className="form-control" id="project-name" name="project_name" onChange={this.onProjectNameChange.bind(this)} value={this.state.project_name}/>
</div>
<div className={`form-group ${styles.formGroup}`}>
<label htmlFor="description" className="col-form-label">Description</label>
<textarea className="form-control" id="description" rows="4" name="description" onChange={this.onDescriptionChange.bind(this)} value={this.state. description}/>
</div>
</form>
}
You need the pass the project as
<tbody className="scrollContent">
{
projects.map((project, i) => {
return (
<tr key={i}>
<td>{project.project_name}</td>
<td>{project.description}</td>
<td>
<EditProjectModal project={project} />
</td>
</tr>
);
})
}
</tbody>
I'm trying to create an img uploader inside my ReduxForm that will only accept imgs that are .png and no larger than 210x210 and 2mb. Also, the design says to swap the placeholder img with the uploaded file which I'm also struggling with. Here's my code:
renderProfileImgUpload(field) {
const { meta: { touched, error }, label, name, accept, type } = field;
return (
<div>
<div className="login__fieldError">
<small>{touched ? error : ''}</small>
</div>
<label htmlFor="img-upload">
<img src="imgs/profile-select.png" className="img-responsive" alt="" />
</label>
<input type={type} name={name} accept={accept} id="img-upload" />
</div>
)
}
render() {
const { handleSubmit, showNextRegistration, showPreviousRegistration } = this.props;
return (
<div className="widgetFull--white">
<div className="align-middle row registration--fullHeight">
<div className="columns small-3">
<img
src="imgs/account-arrow-left.png"
alt="menu"
className="img-responsive"
onClick={showPreviousRegistration}
/>
</div>
<div className="columns small-6">
<h2 className="registration__header">Edit account</h2>
</div>
<div className="columns small-3">
<h3 className="registration__index">2 of 2</h3>
</div>
<form onSubmit={ handleSubmit(this.onSubmit.bind(this)) }>
<div className="columns small-3">
<Field label="Profile Image" type="file" name="image" accept="image/.png" component={this.renderProfileImgUpload} />
</div>
<div className="columns small-6">
<Field label="Username" type="screenname" name="screenname" component={this.renderUsernameField} />
</div>
<div className="columns small-6">
<Field label="First Name" type="firstName" name="firstName" component={this.renderFirstNameField} />
</div>
<div className="columns small-6">
<Field label="Last Name" type="lastName" name="lastName" component={this.renderLastNameField} />
</div>
<div className="columns small-12">
<button className="button expanded registration__btn" type="button">Next</button>
</div>
</form>
</div>
</div>
)
}
Currently I'm unsure whether it would be better to try and do the validation when uploading the img, or inside the handle submit function. Thanks for your help!