reactjsformsreact-forms

Form submitting data in separate object


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;

Solution

  • You can use the spread operator ... to place your inputs values into your data object.

    const data = {
      ...inputs,
      selectedImageUrl,
      value,
    };