Here's my react code (I know its dirty because I didn't divide it into components). I want my form to submit data in a single object but it is submitting data in separate objects, is it because I have defined so many states? I am new in this field and trying my best to resolve it on my own.
The result I want to achive is that the backend receives the data in the single object rather than in separate ones.
import { useState } from "react";
import TextMask from "react-text-mask";
import React from "react";
function Signup() {
const [selectedImageUrl, setSelectedImageUrl] = useState(null);
const images = [
{
id: 1,
src: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSmM5NNo6ZYA6k475yQ84aBh0xnJz2gj36kmBrNiZy6_A&s",
alt: "",
},
{
id: 2,
src: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSGuM8tcZCatcXpQjm_GT_Osjg21n34rrqtmUhJT1Tkwg7tETQmgwGo1qIB7JyVLGZh93M&usqp=CAU",
alt: "",
},
{
id: 3,
src: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSLe_VTB7MNJoROH-y8UaJ5HkeTQ4aN2HCgFMnGNRmMrbTbSQ1z671QBx8jWe58DpT9yzw&usqp=CAU",
alt: "",
},
];
const handleClick = (url) => {
setSelectedImageUrl(url);
};
const [value, setValue] = useState("");
const clickHandler = (props) => {
setValue(props);
};
const [inputs, setInputs] = useState({});
const handleChange = (event) => {
const name = event.target.name;
const value = event.target.value;
setInputs((values) => ({ ...values, [name]: value }));
};
const setErrorMessage = (message) => {
console.log(message);
};
const handleSubmit = (event) => {
event.preventDefault();
// console.log(inputs);
// console.log(selectedImageIndex)
// console.log(value)
if (
(!selectedImageUrl && selectedImageUrl < 0) ||
selectedImageUrl == null
) {
setErrorMessage("Please select an image");
// console.log(selectedImageIndex)
} else if (!value) {
setErrorMessage("Please select a size");
} else if (!inputs.username || inputs.username.match(/[^a-zA-Z ]/)) {
setErrorMessage("Please enter a valid first name");
} else {
setErrorMessage("");
// console.log(inputs);
// console.log(selectedImageIndex)
// console.log(value)
const data = {
inputs,
selectedImageUrl,
value,
};
console.log(data);
// console.log(data.Input.cnicNumber)
// console.log(data.Input.number)
setInputs("");
setSelectedImageUrl(null);
setValue();
}
};
return (
<div className="flex justify-center ">
<form
onSubmit={handleSubmit}
className="mt-6 mb-0 space-y-4 rounded-lg p-8 shadow-2xl"
>
<h1 className="text-2xl text-center text-2xl font-bold text-indigo-600 sm:text-3xl">
Registration
</h1>
<div className="form-group mb-6">
<label className="mb-3 block text-base font-medium text-[#07074D]">
{" "}
Select Images
{images.map((image, index) => (
<img
name="image"
className="inline-flex relative max-w-sm transition-all duration-300 cursor-pointer filter grayscale hover:grayscale-0 h-auto max-w-md m-5 p-1 bg-white border rounded max-w-sm"
key={image.id}
src={image.src}
alt={image.alt}
onClick={() => handleClick(image.src)}
style={{
opacity: selectedImageUrl === image.src ? 1 : 1,
cursor: "pointer",
border:
selectedImageUrl === image.src ? "2px solid blue" : "none",
width: selectedImageUrl === image.src ? "15rem" : "9rem",
}}
/>
))}
</label>
</div>
<h2 className="mb-3 block text-base font-medium text-[#07074D]">
Select Apartment Size
</h2>
<div className="justify-items-center">
<select
name="apartmentsize"
onChange={(e) => clickHandler(e.target.value)}
>
<option value="">Select Apartment Size</option>
<option value="25x50">25x50</option>
<option value="45x65">45x65</option>
<option value="60x90">60x90</option>
</select>
</div>
<div className="">
<label className="mb-3 block text-base font-medium text-[#07074D]">
Enter your name:
<input
className="h-10 border mt-1 rounded px-4 w-full bg-gray-50"
type="text"
name="username"
value={inputs.username || ""}
onChange={handleChange}
/>
</label>
<label className="mb-3 block text-base font-medium text-[#07074D]">
Enter your phone number:
<TextMask
className="h-10 border mt-1 rounded px-4 w-full bg-gray-50"
type="text"
name="number"
value={inputs.number || ""}
mask={[ "+", "9", "2", " ", /\d/, /\d/, /\d/, "-", /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, ]}
onChange={handleChange}
/>
</label>
<label className="mb-3 block text-base font-medium text-[#07074D]">
{" "}
Enter Your Cnic
<TextMask
className="h-10 border mt-1 rounded px-4 w-full bg-gray-50"
type="text"
name="cnicNumber"
value={inputs.cnicNumber || ""}
mask={[ /\d/, /\d/, /\d/, /\d/, /\d/, "-", /\d/, /\d/, /\d/, /\d/, /\d/, /\d/, "-", /\d/, /\d/, ]}
onChange={handleChange}
/>
</label>
</div>
<div>
<button
className="shadow bg-purple-500 hover:bg-purple-400 focus:shadow-outline focus:outline-none text-white font-bold py-2 px-4 rounded"
type="Submit"
>
Save changes
</button>
</div>
</form>
</div>
);
}
export default Signup;
You can use the spread operator ...
to place your inputs
values into your data
object.
const data = {
...inputs,
selectedImageUrl,
value,
};