skip to Main Content

Within my AddNameModal component, I am attempting to store the data URL obtained from my signature canvas into a state variable called signatureImage

It’s worth noting that AddNameModal is a component nested within another component called ModalWithForm. In ModalWithForm, I’m using the use state hook with [Image, setSignatureImage] and providing React children (specifically, AddNameModal) with the props onChange and signatureData.

Here is the code for ModalWithForm:

const ModalWithForm = ({
       children,
       name,
       onClose,
       title,
    button Text = "Save",
  }) => {
    const [formData, setFormData] = use State({});
    const [signatureImage, setSignatureImage] = useState(null);

  const handleSignatureCapture = (data) => {
    setSignatureImage(data);
  };

  const handleInputChange = (e) => {
    const { name, value } = e.target;
    setFormData({
      ...formData,
      [name]: value,
    });
  };

  const onSignatureCapture = (signatureData) => {
    console.log("Signature Captured:", signatureData);
    setSignatureImage()
  };

  const childrenWithProps = React.Children.map(children, (child) => {
    if (React.isValidElement(child)) {
      return React.cloneElement(child, {
        onChange: handleInputChange,
        signatureData: onSignatureCapture,
      });
    }
    return child;
  });

  const handleSubmit = (e) => {
    e.preventDefault();

    const finalFormData = {
      ...formData,
      signature: signatureImage,
    };
    console.log("Form Data", finalFormData);
  };

  return (
    <div className={`modal modal_type_${name}`}>
      <div className="modal__content">
        <button
          type="button"
          onClick={onClose}
          className="modal__close-button"
        />
        <h3 className="font-['SourceSeriff'] font-bold text-[44px] mt-[26px] text-center pb-[40px]">
          {title}
        </h3>
        <form onSubmit={handleSubmit}>
          {childrenWithProps}
          <div className="flex justify-end">
            <button type="submit" className="modal__submit-button">
              {buttonText}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};

Here is the code for AddNameModal component:

 const AddNameModal = ({ onClose,signatureData, onSignatureCapture }) => {
  console.log(signatureData)

  const sigCanvasRef = React.createRef();

  const handleClear = () => {
    sigCanvasRef.current.clear();
  };

  const handleSaveSignature = (signatureData) => {
    signatureData = sigCanvasRef.current.getTrimmedCanvas().toDataURL("image/png");  
    console.log(signatureData)
    onSignatureCapture
  };

  return (
    <ModalWithForm
      onClose={onClose}
      name="add-name"
      title="Policy Agreement Signature"
    >
      <div className="modal__form-contents">
        <label>
          <p className=" text-2xl font-['SourceSerif'] mb-[10px] font-[700]">
            First Name
          </p>
          <input
            className="border-black border-2 border-solid w-full rounded p-[5px] mb-[10px]"
            type="text"
            name="firstname"
            minLength="4"
            maxLength="15"
            placeholder="first"
            required
          />
          <span className="modal__error"></span>
        </label>
        <label>
          <p className=" text-2xl font-['SourceSerif'] mb-[10px] font-[700]">
            Last Name
          </p>
          <input
            className="border-black border-2 border-solid w-full rounded p-[5px] mb-[10px]"
            type="text"
            name="lastname"
            minLength="4"
            maxLength="15"
            placeholder="last"
            required
          />
          <span className="modal__error"></span>
        </label>
          <div className="mt-[10px] mb-[20px] ">
            <p className={`modal__input-title mb-[15px]`}>Signature</p>
            <div className="w-[100%] h-[200px] border-solid border-2 border-black">
              <SignatureCanvas
                ref={sigCanvasRef}
                penColor="black"
                canvasProps={{
                  className: "signature-canvas",
                }}
              />
            </div>
            <span></span>

            <button
              className="signature__clear-button"
              onClick={handleClear}
              type="button"
            >
              Clear Signature
            </button>
            <button className="signature__save-button" onClick={handleSaveSignature} type="button"> 
              Save Signature
            </button>
          </div>
      </div>
    </ModalWithForm>
  );
};

I tried different approaches this is why the code might be a little jumbled up. I just will like a point in the right direction. What I expect is for me to beable to send the data URl from the signatureCanvas upwards to the parent component and then onSubmit send this data through a Api request.

2

Answers


  1. Usually in React the data flows from top level component to low level component. What you can try to do is declare const [signatureImage, setSignatureImage] = useState(null) state hook at the parent component and then pass it down as props into your children component.

    Login or Signup to reply.
  2. What you would do is you will make a useState for storing the data URl from the signatureCanvas and pass the set function of that useState to the child component i.e(AddNameModal component). Upon getting the signatureData you will use the setFunction you just passed from the parent component to set the state with that signatureData.

    Now you’ll probably be asking how would the parent component come to know when to call the API request once we have that signatureData in our state? For that you will make a useEffect hook with a dependency of state that we made to hold sinatureData and inside the useEffect you will call the function which as you said to send this data through API request.

    when you are done with this, as soon as your child components gets the desired signatureData your Api request will be called with that signatureData.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search