I am trying to fetch the user based on their id but can't sometimes I get the user but it is like the state is preserving the values if I try to get another user value but I still saw the previous user data. Hey anyone please help me I am stuck here for hours now.
here is the image of my users list
here is an update
I went to my network tab and saw that
I get the user Based on their users but I see the value in fields until I click on my first user in the shown list which is shown in fields then again If click the next user I still see the first user details so it definitely not API issue in my state problem please help me to fix this.
EditUser.tsx
const UpdateUser = ({ setUsers, id }) => {
const animatedComponents = makeAnimated();
const [rolesData, setRolesData] = useState([]);
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [role, setRole] = useState("");
const [job_preference, setJobPreference] =
useState([]);
const [multiSelect, setMultiSelect] = useState(
[]
);
const fetchDataBasedOnID = async (id) => {
const { data } = await axios.get(
`/api/user/${id}`
);
getDataOfMultiSelect(data);
};
const getDataOfMultiSelect = (data) => {
const result = states.filter((state) =>
data.job_preference.includes(state.value)
);
setMultiSelect(result);
setName(data.name);
setEmail(data.email);
setRole(data.role);
};
const resetFields = () => {
setName("");
setEmail("");
setMultiSelect("");
setRole("");
};
useEffect(() => {
handleRoles();
}, []);
const handleSubmit = async (e) => {
e.preventDefault();
const { data } = await axios.put(
`/api/user/${id}`,
{
name,
email,
role,
job_preference,
}
);
toast.success("User updated successfully");
usersList();
resetFields();
};
return (
<>
{/* Button trigger modal */}
<div>
<button
type='button'
onClick={() => fetchDataBasedOnID(id)}
className='btn btn-warning'
data-bs-toggle='modal'
data-bs-target='#updateModal'>
<BiEdit />
</button>
</div>
{/* Modal */}
<div
className='modal fade'
id='updateModal'
tabIndex='-1'
aria-hidden='true'>
<div className='modal-dialog modal-dialog-centered'>
<div className='modal-content'>
<div className='modal-header'>
<h1
className='modal-title fs-5'
id='exampleModalLabel'>
Update User
</h1>
<button
type='button'
className='btn-close'
data-bs-dismiss='modal'
aria-label='Close'></button>
</div>
<form onSubmit={handleSubmit}>
<div className='modal-body'>
<div className='mb-3'>
<label className='form-label'>
Name
</label>
<input
type='text'
value={name}
onChange={(e) =>
setName(e.target.value)
}
required
className='form-control'
placeholder='John Doe'
/>
</div>
<div className='mb-3'>
<label className='form-label'>
Email address
</label>
<input
type='email'
value={email}
required
onChange={(e) =>
setEmail(e.target.value)
}
className='form-control'
placeholder='name#example.com'
/>
</div>
<div className='mb-3'>
<label className='form-label'>
Role
</label>
<select
className='form-select option'
value={role}
onChange={handleRoleChange}>
<option className='option'>
Select a Role
</option>
{rolesData?.map(
({ _id, role_name }) => (
<option
className='option'
key={_id}
value={role_name}>
{role_name}
</option>
)
)}
</select>
</div>
<div className='mb-3'>
<label className='form-label'>
Job Preference
</label>
<Select
value={multiSelect}
isMulti
components={
animatedComponents
}
isSearchable
placeholder='Choose any 3 states as job location'
options={states}
onChange={
handleMultiSelectChange
}
isOptionDisabled={() =>
multiSelect.length >= 3
}
/>
</div>
</div>
<div className='modal-footer'>
<button
type='button'
className='btn btn-secondary'
data-bs-dismiss='modal'>
Close
</button>
<button
type='submit'
className='btn btn-success'
data-bs-dismiss='modal'>
Save Changes
</button>
</div>
</form>
</div>
</div>
</div>
</>
);
};
export default UpdateUser;
Related
I have a react form whose data must be saved in an array (what i want) values from the form include 3 selectable values, and two input values ( a number input and textarea ) each time a user is done with entering data, they press save button to push that entered data ( converted to an object ) into the array. I expect that each time user clicks save button, they are saving different data from the previous, which is then again pushed into the same array as an object. the array has a fixed length and I expect to not accept anymore data if it reaches a certain length. this works very well each a user saves data in that array only when the values of the two input fields (number input and textarea) the challenge is that each time the user data from any of the 3 selectable (as long as a select field is touched, even if the selected value is the same as the preivous value) values, the array loses the previous data and saves the current as array[0], the select fields are customised components using react-select, I extract data selected using useState, and other input fields are customised components from regular html input fields, I extract data input, using useRef, and forwadRef.
Kindly help and suggest how I can go about this.
export const Input = forwardRef((props, ref) => {
return (
<input
min={1}
required={props.required}
type={props.type}
id={props.id}
name={props.name}
placeholder={props.placeholder}
autoComplete={props.autoComplete}
autoCapitalize="none"
autoCorrect='off'
onChange={props.onChange}
defaultValue={props.defaultValue}
ref={ref}
{...props}
/>
);
});
const MySelect = (props) => {
const MyTheme = (theme) => {
return {
...theme,
colors: {
...theme.colors,
primary25: "#bdbdbd",
color: "#000",
primary: "rgba(0, 0, 0, 0.3)",
},
};
};
return (
<div style={{ width: "80%" }}>
<Select
defaultValue={props.defaultValue}
menuPlacement="auto"
menuPosition="auto"
placeholder={props.placeholder}
value={props.value}
onChange={props.onChange}
options={props.options}
isSearchable
isDisabled={props.isDisabled}
theme={MyTheme}
name={props.name}
id={props.id}
// ref={props.ref}
required = {props.required}
/>
</div>
);
};
export default MySelect;
const TextReminder = (props) => {
const [kickStart, setKickStart] = useState("");
const TimerRef = useRef();
const [units, setUnits] = useState("");
const [tag, setTag] = useState("");
const tagRef = useRef()
const TextRef = useRef();
const maxW = props.maxW
const handleAdd = (e) => {
e.preventDefault();
};
const Reminders = []
const handleSave = (e) => {
e.preventDefault();
const TextInput = TextRef.current.value;
const TimeInput = TimerRef.current.value;
const KickStart = kickStart.value;
const Units = units.value;
const Tag = tag.value;
const Wmax = maxW.current.value
const Reminder = {
Message: TextInput,
Starter: KickStart,
SendTime: TimeInput,
TimeUnits: Units,
Id: Tag
};
if (Reminders.length !== parseInt(Wmax)) {
Reminders.push(Reminder);
console.log(Reminders);
} else {
console.log("can not save any more Reminders");
}
};
const Remove = (e) => {
e.preventDefault();
if (Reminders.length > 0) {
Reminders.pop();
console.log(Reminders);
} else {
alert("Sorry, your sms reminders basket is now empty");
console.log(Reminders);
}
};
const handleSubmit = (e) => {
e.preventDefault();
};
return (
<div>
<form onSubmit={handleSubmit}>
<div className={classes.email}>
<div className={classes.split}>
<div className={classes.left}>
<div className={classes.lefthead}>settings</div>
<div className={classes.selectors}>
<div className={classes.time}>
<div className={classes.heads}>
when{" "}
<span
className={classes.add}
title="Click to start editing your reminders. one at a time"
>
<FButton onClick={handleAdd}>add</FButton>
</span>
</div>
<MySelect
placeholder="Select Time ..."
options={Determinants}
onChange={setKickStart}
/>
</div>
<div className={classes.trigger}>
<div className={classes.heads}>select trigger</div>
<div className={classes.tips}>
<div className={classes.tip1}>
<Input type="number" defaultValue="5" ref={TimerRef} />
</div>
<div className={classes.tip2}>
<MySelect
placeholder="Units ..."
options={RideTriggers.before}
onChange={setUnits}
/>
</div>
</div>
</div>
<div className={classes.tags}>
<div className={classes.heads}>select tag</div>
<MySelect
placeholder="Select Tag ..."
options={Tags}
onChange={setTag}
ref={tagRef}
/>
</div>
</div>
</div>
<div className={classes.right}>
<div className={classes.label}>
<div className={classes.a}>
<label htmlFor="body">Body</label>
</div>
<div className={classes.b}>
<FButton>+ variables</FButton>
</div>
</div>
<div className={classes.textarea}>
<TextArea id="body" className={classes.text} ref={TextRef} />
</div>
<div className={classes.bb}>
<div
className={classes.bbf}
title="Remove the immediate previously saved reminder from your basket"
>
<FButton onClick={Remove}>remove</FButton>
</div>
<div
className={classes.bbf}
title="Add this reminder to your basket in the order of first-saved is first-sent and last-saved is last-sent"
>
<FButton onClick={handleSave}>save</FButton>
</div>
</div>
</div>
</div>
<footer>
<div className={classes.footerbtn}>
<div className={classes.close}>
<FButton type={"submit"}>done</FButton>
</div>
{/* <div className={classes.close}>
<FButton>cancel</FButton>
</div> */}
</div>
</footer>
</div>
</form>
</div>
);
};
export default TextReminder;
I am trying to create a Form validation for 4 inputs, companyName - email - name - phone.
My aim is to validate them using regular expression and won't allow the user to press submit unless the inputs aregood to go.
Problem :
I set the logic testing just two validations so far, the company name and the email.
When I press sometimes submit, it ignores the validation and sometimes not.
Please help me to let them work properly.
import { React, useState, useEffect } from "react";
/*
*****
*****
Import Showcase.scss -
*/
import "./Showcase.scss";
const Showacase = () => {
/*
*****
*****
Logic Goes Here
*/
//State Management
//Company State
const [company, setCompany] = useState();
const [companyValue, setCompanyValue] = useState();
//name State
const [name, setName] = useState();
const [nameValue, setNameValue] = useState();
//Phone State
const [phone, setPhone] = useState();
const [phoneValue, setPhoneValue] = useState();
//Email State
const [email, setEmail] = useState();
const [emailValue, setEmailValue] = useState();
//Hide Inputs
const [input, setInput] = useState(true);
// Message State
const [message, setMessage] = useState(true);
// SubMessage
const [subMessage, setSubMessage] = useState(true);
//InsertLine
const [line, setLine] = useState(false);
//Hide Button
const [btn, setBtn] = useState(true);
/* Validation State */
const [emailValidate, setEmailValidate] = useState(false);
/* Validation State */
const [companyValidate, setCompanyValidate] = useState(false);
// OnSubmit
const onSubmit = (e) => {
e.preventDefault();
};
//onChange Company
const onChangeCompany = (e) => {
setCompany(e.target.value);
};
//OnClick
const onClick = (e) => {
// Company and Name
const reCompanyName = /^[a-zA-Z]{2,12}$/;
// Email Address
const reEmail =
/^([a-zA-Z0-9_\-\.]+)#([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/;
if (!reCompanyName.test(company)) {
setCompanyValidate(true);
return;
}
if (!reEmail.test(email)) {
setEmailValidate(true);
return;
}
//upComing Phone
if (company === "" || phone === "" || email === "" || name === "") {
return;
} else {
/* setting the New Values */
setCompanyValue(company);
setNameValue(name);
setPhoneValue(phone);
setEmailValue(email);
/* Clearing the Inputs */
setCompany("");
setName("");
setPhone("");
setEmail("");
/* Logic of hidding Items */
setInput(false);
setMessage(false);
setSubMessage(false);
setLine(true);
setBtn(false);
/* Reset all options after submission after 5 seconds */
setTimeout(() => {
setInput(!false);
setMessage(!false);
setSubMessage(!false);
setLine(!true);
setBtn(!false);
}, 5000);
}
};
return (
<>
{/* Showcase Main */}
<div className="Showcase">
<div className="Container">
{/* Showcase Main / Applying the flex */}
<div className="Showcase__inside">
{/* Right Side / form and logic */}
<div className="Showcase__inside--left">
<div className="Showcase__inside--left--box">
{/* the Top Message */}
{message ? (
<h1>Find inbound call centers for your company</h1>
) : (
<h1>Thank you for your request!</h1>
)}
{/* the sub Message Message */}
{subMessage ? (
<p>
Use our AI and Big Data driven call center sourcing solution
</p>
) : (
<p className="paragraphAfterSubmission">
You’ve taken the first step. Our experts will get in touch
with you soon.
</p>
)}
{/* Inserting the Line */}
{line ? <hr></hr> : null}
<form onSubmit={onSubmit}>
{/* Company */}
<div className="Showcase__inside--left--box--form">
<label for="company">Company </label>
{input ? (
<div>
<input
required
value={company}
onChange={onChangeCompany}
type="text"
id="company"
placeholder="Company"
name="company"
/>
{companyValidate ? (
<div className="companyValidate">
<small>Please Provide a valid Company Name</small>
</div>
) : (
""
)}
</div>
) : (
<p>{companyValue}</p>
)}
</div>
{/* Name */}
<div className="Showcase__inside--left--box--form">
<label for="Name">Name </label>
{input ? (
<input
required
onChange={(e) => setName(e.target.value)}
value={name}
type="text"
id="Name"
placeholder="Full name"
name="Name"
/>
) : (
<p>{nameValue}</p>
)}
</div>
{/* Phone */}
<div className="Showcase__inside--left--box--form">
<label for="Phone">Phone </label>
{input ? (
<input
required
onChange={(e) => setPhone(e.target.value)}
value={phone}
type="text"
id="Phone"
placeholder="+49"
name="phone"
/>
) : (
<p>{phoneValue}</p>
)}
</div>
{/* Email */}
<div className="Showcase__inside--left--box--form">
<label for="Email">Email </label>
{input ? (
<div>
<input
required
onChange={(e) => setEmail(e.target.value)}
value={email}
type="email"
id="Email"
placeholder="name#mail.com"
name="email"
/>
{emailValidate ? (
<div className="EmailValidate">
<small>Please Provide a valid Email</small>
</div>
) : (
""
)}
</div>
) : (
<p>{emailValue}</p>
)}
</div>
{/* Submit */}
<div className="Showcase__inside--left--box--form">
<div className="Showcase__inside--left--box--form--submit">
{/* OnClick Method */}
{btn ? (
<button onClick={onClick} type="submit">
Get informed
</button>
) : null}
</div>
</div>
</form>
</div>
</div>
{/* Right SIDE %s */}
<div className="Showcase__inside--right">
<div>
<div>
<h1>Welcome to Europe’s largest call center database </h1>
</div>
<div className="Showcase__inside--right--per">
<div className="Showcase__inside--right--per--single">
<small>500+</small>
<h1>Tenders</h1>
</div>
<div className="Showcase__inside--right--per--single">
<small>200+</small>
<h1>Callcenter</h1>
</div>
<div className="Showcase__inside--right--per--single">
<small>375.000</small>
<h1>Agents available</h1>
</div>
<div className="Showcase__inside--right--per--single">
<small>85%</small>
<h1>Faster sourcing</h1>
</div>
</div>
</div>
</div>
{/* Right Ended %s */}
</div>
</div>
</div>
</>
);
};
export default Showacase;
I want to be able to use the value of selectedOption but use only the id values. Essentially, selectedOption.id. Except when I use selectedOption.id I get undefined.
Why is that? What can I do to change that. I attached an image as a reference to what data I am talking about. This handleChange function occurs in the Select component.
My component output:
My code:
import React, { useState } from 'react';
import Select from 'react-select';
export default function CandidateForm({ handleCreate, job_req_titles }) {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [facebook, setFacebook] = useState('');
const [github, setGithub] = useState('');
const [linkedin, setLinkedin] = useState('');
const [jobTitle, setJobTitle] = useState('');
const [company, setCompany] = useState('');
const [appJobReq, setAppJobReq] = useState('');
const prepareCandidateObj = () => {
// Prepare the candidate object
let candidate = {
name,
email,
phone,
facebook,
github,
linkedin,
jobTitle,
company,
appJobReq,
};
console.log(candidate);
// Pass in the postNewCandidate from the parent component
// to be called in this component
handleCreate(candidate);
// alert('Candidate Submitted!');
};
const handleChange = (selectedOption) => {
setAppJobReq(selectedOption);
console.log(`Option selected:`, selectedOption);
};
return (
<div className='container'>
<div className='row'>
<label className='name'>Name</label>
</div>
<div className='row'>
<input
className='name-input'
type='text'
placeholder='Carol Caroller'
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className='row'>
<label className='email'>Email</label>
</div>
<div className='row'>
<input
className='email-input'
placeholder='example#email.com'
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className='row'>
<label className='phone'>Phone</label>
</div>
<div className='row'>
<input
className='phone-input'
placeholder='(201) 534 2233'
value={phone}
onChange={(e) => setPhone(e.target.value)}
/>
</div>
<div className='row'>
<label className='facebook'>Facebook</label>
</div>
<div className='row'>
<input
className='facebook-input'
placeholder='https://www.facebook.com/DilaonRion/'
value={facebook}
onChange={(e) => setFacebook(e.target.value)}
></input>
</div>
<div className='row'>
<label className='linkedin'>Linkedin</label>
</div>
<div className='row'>
<input
className='linkedin-input'
placeholder='https://www.linkedin.com/DillonRion/'
value={linkedin}
onChange={(e) => setLinkedin(e.target.value)}
></input>
</div>
<div className='row'>
<label className='github'>Github</label>
</div>
<div className='row'>
<input
className='github-input'
placeholder='https://www.github.com/DilonRion/'
value={github}
onChange={(e) => setGithub(e.target.value)}
></input>
</div>
<div className='row'>
<label className='job-title'>Job Title</label>
</div>
<div className='row'>
<input
className='job-title-input'
type='text'
placeholder='Frontend Developer'
value={jobTitle}
onChange={(e) => setJobTitle(e.target.value)}
></input>
</div>
<div className='row'>
<label className='current-company'>Current Company Name</label>
</div>
<div className='row'>
<input
className='current-company-input'
type='text'
placeholder='Obrien LLC'
value={company}
onChange={(e) => setCompany(e.target.value)}
></input>
</div>
<div className='row'>
<label className='job-req'>Applicant Job Req</label>
</div>
<div className='row'>
<div className='job-req-input'>
<Select
className='job-req-select'
value={appJobReq}
onChange={handleChange}
options={job_req_titles}
isMulti
classNamePrefix='select'
/>
</div>
</div>
<div className='row'>
<label className='applied'>Applied or Sourced</label>
<select className='applied-input'>
<option disabled defaultValue>
--
</option>
<option value='1'>Applied</option>
<option value='0'>Sourced</option>
</select>
</div>
<button className='create-button' onClick={prepareCandidateObj}>
Create
</button>
</div>
);
}
Since the isMulti prop passed to the Select component, selectedOption will be an array of the selected option(s). You can use the array map method to get an array that contains only the ids of the selected options, assuming that each option has an id:
const handleChange = (selectedOptions) => {
const selectedOptionIds = selectedOptions.map(option => option.id)
console.log("selected option ids:",
};
I Am populating values of my input field from JSON data what am getting from back-end, now there is an edit button on UI by on click on that button I am enabling my input field but not able to type inside as I am setting some value
I want to write inside the input once I have made them editable.
const { register, handleSubmit, errors } = useForm();
const [disabled, setdisabled] = useState(false);
const [editBtn, seteditBtn] = useState(true);
<form onSubmit={handleSubmit(onSubmit)}>
{editBtn === true && (
<div align="right">
<button
className="btn white_color_btn"
type="button"
onClick={edit}
>
Edit
</button>
</div>
)}
{editBtn === false && (
<button className="btn white_color_btn" type="submit">
Save
</button>
)}
<div className="row">
<div className="form-group col-6 col-sm-6 col-md-6 col-lg-4 col-xl-4">
<input
type="text"
disable
id="firstName"
name="firstName"
value={dataItems.firstname}
disabled={disabled ? "" : "disabled"}
ref={register({ required: true })}
/>
{errors.firstname && (
<span className="text-danger">first name required</span>
)}
<br />
<label htmlFor="emp_designation">First name</label>
</div>
<div className="form-group col-6 col-sm-6 col-md-6 col-lg-4 col-xl-4">
<input
type="text"
disabled
id="lastname"
name="lastname"
value={dataItems.lastname}
disabled={disabled ? "" : "disabled"}
ref={register({ required: true })}
/>
{errors.lastname && (
<span className="text-danger">last name required</span>
)}
<br />
<label htmlFor="lastname">Lastname</label>
</div>
</div>
</form>
On click of edit
const edit = () => {
setdisabled(true);
};
Code sandbox
You need to make your input as a controlled component and write onChange handlers which will update the state. This will allow you to edit the input field values. Demo
const [disabled, setdisabled] = useState(false);
const [name, setName] = useState(empData.item.name) // setting default name
const [lastname, setLastname] = useState(empData.item.lastname) // default lastname
const edit = () => {
setdisabled(true);
};
return (<div className="container-fluid">
<div align="right">
<button className="btn" onClick={edit}>
Edit
</button>
</div>
<div className="row">
<div>
<input
type="text"
disable
id="item.value"
value={name}
onChange={(e) => {
setName(e.target.value)
}}
disabled={disabled ? "" : "disabled"}
/>
<br />
<label htmlFor="name">Name</label>
</div>
<div>
<input
type="text"
disabled
id={"lastname"}
value={lastname}
onChange={(e) => {
setLastname(e.target.value)
}}
disabled={disabled ? "" : "disabled"}
/>
<br />
<label htmlFor="lastname">Lastname</label>
</div>
</div>
</div>);
Your input is controlled by the value you are giving to it. ie: Its value is always for example empData.item.name.
And you are not providing a change handler to handle the change.
Try adding something like this:
function myChangeHandler(e){
setEditedValueSomeHow(e.target.value);
}
<input
// ...
onChange={myChangeHandler}
/>
Read more about uncontrolled components
PS: you should have had a warning message in your console like this one:
Edit:
You are using react-hook-form to manage your form but at the same time giving values to your inputs.
Please refer to this link to initialize your form values.
short story:
Remove value form your input.
Pass an object to useForm hook containing initial values.
const { register, handleSubmit, errors } = useForm({
defaultValues: {
firstName: "steve",
lastname: "smith"
}
});
Here is a working fork for your codesandbox
In order to make the input editable, you need to update a local state which controlls the input value. As suggested by you in the comments, you are using graphql to get the data, you can make use of useEffect to set the data in state and then on click of edit, update the localState
export default function App() {
const { register, handleSubmit, errors } = useForm();
const [disabled, setdisabled] = useState(true);
const [editBtn, seteditBtn] = useState(true);
const { loading, data } = useQuery("some qraphql query here"); // getting data from graphql
const [formData, setFormData] = useState({});
useEffect(() => {
setFormData(data);
}, [data]);
const edit = () => {
setdisabled(false);
seteditBtn(false);
};
const onSubmit = () => {
console.log(formData);
// submit data using formData state.
};
const handleChange = e => {
const name = e.target.name;
const value = e.target.value;
console.log(name, value);
setFormData(prev => ({ ...prev, [name]: value }));
};
return (
<div className="container-fluid">
<form onSubmit={handleSubmit(onSubmit)}>
{editBtn === true && (
<div align="right">
<button
className="btn white_color_btn"
type="button"
onClick={edit}
>
Edit
</button>
</div>
)}
{editBtn === false && (
<button className="btn white_color_btn" type="submit">
Save
</button>
)}
<div className="row">
<div className="form-group col-6 col-sm-6 col-md-6 col-lg-4 col-xl-4">
<input
type="text"
id="firstname"
name="firstname"
onChange={handleChange}
value={formData.firstname}
disabled={disabled}
ref={register({ required: true })}
/>
{errors.firstname && (
<span className="text-danger">first name required</span>
)}
<br />
<label htmlFor="emp_designation">First name</label>
</div>
<div className="form-group col-6 col-sm-6 col-md-6 col-lg-4 col-xl-4">
<input
type="text"
id="lastname"
name="lastname"
value={formData.lastname}
onChange={handleChange}
disabled={disabled}
ref={register({ required: true })}
/>
{errors.lastname && (
<span className="text-danger">last name required</span>
)}
<br />
<label htmlFor="lastname">Lastname</label>
</div>
</div>
</form>
</div>
);
}
Working mock demo
I'm trying to populate second drop down based on the selection of first drop down. I have just started with reactJS like a month ago with react hooks and react-redux.
All the answers I found were based on class component and none of them used Redux. I want to solve this with react-hooks and react-redux only. Any help would be really appreciated.
This is the state when the page loads
const AddRequest = ({
addRequest,
getActivities,
activities
}) => {
useEffect(() => {
getActivities();
}, [getActivities]);
const [formData, setFormData] = useState({
activity: "",
subActivity: ""
});
const { activity, subActivity } = formData;
const onChangeHandler = e => {
e.preventDefault();
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const onSubmitHandler = e => {
e.preventDefault();
addRequest(formData, history);
};
let activityOptions = activities.map(activity => (
<option key={activity._id} value={activity.activityName}>
{activity.activityName}
</option>
));
return (
<form className="form-signin" onSubmit={e => onSubmitHandler(e)}>
<div className="form-label-group">
<select
className="form-control"
name="activity"
value={activity}
onChange={e => onChangeHandler(e)}
>
<option>Select Activity</option>
{activityOptions}
</select>
</div>
<div className="form-label-group">
<select
className="form-control"
name="subActivity"
value={subActivity}
defaultValue={{ label: "Select sub Activity", value: 0 }}
onChange={e => onChangeHandler(e)}
>
<option>Select Sub Activity</option>
{activities.subActivities.map((subAct, index) => (
<option key={index} value={subAct}>
{subAct}
</option>
))}
</select>
</div>
<div className="form-label-group">
<input
type="text"
className="form-control"
placeholder="Description (optional)"
value={description}
required
/>
</div>
<hr className="my-4" />
<button
className="btn btn-lg btn-primary btn-block text-uppercase"
type="submit"
>
Submit
</button>
</form>
);
AddRequest.propTypes = {
getActivities: PropTypes.func.isRequired,
addRequest: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
activities: state.activity.activities,
});
export default connect(
mapStateToProps,
{ addRequest, getActivities }
)(withRouter(AddRequest));