2

When I put my SignaturePad inside of an ant design component library Modal component, it is not able to generate the base64 image.

When the code reaches the trim function in the signaturepad, the signature will be "data:". But if I remove the Modal tags, it will return "data:image/png;base64,iVBORw0KGgoxxxxx...." which is the normal behaviour. Is this due to the signature library not working well in an ant design Modal?

Below is the code:

import { Form, Modal } from 'antd';

const FormComponent = () => {
  const [form] = Form.useForm();

  return (
      <Modal
        title="Signature Form"
        open={true}>
        <div>
          <Form
            form={form}
          >
            <div>
              <SignaturePad
                name="signature"
                title="Signature"
                setFieldValue={(fieldName, value) => {
                  formSign.setFieldsValue({ [fieldName]: value });
                }}
                status={undefined}
                skipValidation={false}
              />
            </div>
          </Form>
        </div>
      </Modal>
  );
);
import React, { useRef, RefObject } from 'react';
import SignaturePad from 'react-signature-canvas';
import { Button, Form } from 'antd';

interface SignaturePadProps {
  name: string;
  title: string;
  setFieldValue: (fieldName: string, value: any) => void;
  status?: 'error' | 'success';
  skipValidation?: boolean;
}

const SignaturePad: React.FC<SignaturePadProps> = ({
  name,
  title,
  setFieldValue,
  status,
  skipValidation,
}) => {
  const ref: RefObject<SignaturePad> = useRef<SignaturePad>(null);
  const isErrorBorder = status === 'error' ? 'signing-error-border' : '';

  const trim = () => {
    if (ref.current) {
      let sign = ref.current.toDataURL('image/png');
      setFieldValue(name, sign);
    }
  };

  const clear = () => {
    if (ref.current) {
      ref.current.clear();
      setFieldValue(name, '');
    }
  };

  return (
    <Form.Item
      {...{
        labelCol: {
          span: 4,
        }
      }}
      label={title}
      name={name}
      rules={[{ required: !skipValidation, message: 'This field is required' }]}
      valuePropName="data-url"
    >
      <section className='sign_form'>
        <SignaturePad
          onEnd={trim}
          canvasProps={{
            className: `sign_canvas ${isErrorBorder}`,
          }}
          ref={ref}
        />
        <Button onClick={clear} className='clear-btn'>
          Clear
        </Button>
      </section>
    </Form.Item>
  );
};

export default SignaturePad;

1 Answer 1

1

Make sure the canvas rendered by <SignaturePad/> component has width and height. It probably the width and height are 0. That's why you can't draw the signature.

e.g.

import './index.css';
import React, { useRef } from 'react';
import SignaturePad from 'react-signature-canvas';
import { Form, Modal } from 'antd';

interface SignaturePadProps {
  name: string;
  title: string;
  setFieldValue: (fieldName: string, value: any) => void;
  skipValidation?: boolean;
}

const SignaturePadComponent: React.FC<SignaturePadProps> = ({
  name,
  title,
  setFieldValue,
  skipValidation,
}) => {
  const ref = useRef<SignaturePad>(null);

  const trim = () => {
    if (ref.current) {
      let sign = ref.current.toDataURL('image/png');
      console.log(sign);
      setFieldValue(name, sign);
    }
  };

  return (
    <Form.Item
      label={title}
      name={name}
      rules={[{ required: !skipValidation, message: 'This field is required' }]}
      valuePropName="data-url"
    >
      <SignaturePad
        onEnd={trim}
        ref={ref}
        canvasProps={{ width: 200, height: 300 }}
      />
    </Form.Item>
  );
};

const FormComponent = () => {
  const [form] = Form.useForm();

  return (
    <Modal
      title="Signature Form"
      open={true}
      styles={{ body: { height: 300 } }}
    >
      <Form form={form}>
        <SignaturePadComponent
          name="signature"
          title="Signature"
          setFieldValue={(fieldName, value) => {
            form.setFieldsValue({ [fieldName]: value });
          }}
          skipValidation={false}
        />
      </Form>
    </Modal>
  );
};

export default FormComponent;

enter image description here

Logs:

data:image/png;base64,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

stackblitz

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.