Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose underlying events from signature_pad #36

Closed
toburger opened this issue Dec 15, 2021 · 8 comments
Closed

Expose underlying events from signature_pad #36

toburger opened this issue Dec 15, 2021 · 8 comments
Labels

Comments

@toburger
Copy link

toburger commented Dec 15, 2021

Exposing the underlying events of signature_pad would be very useful as it allows to react to signature inputs instead of polling the data of signature_pad.

This would allow a pattern like:

const [signature, setSignature] = useState("")
...
<SignaturePad ... onEnd={x=> setSignature(x.toDataURL())} />

or add the events to the options, as they are "low level" events, like

<SignaturePad ... options={{
    onEnd(x) { setSignature(x.toDataURL()) }
}} />

This allows the rest of the code to react to the value of signature easily (e.g. disable the save button and display a message if no signation was made...).


Or alternatively expose the whole underying signature_pad object.

@michaeldzjap
Copy link
Owner

You can already get the original signature pad instance through a ref (e.g. see Layout.tsx in the example dir). I think that should allow you to do what you want?

@toburger
Copy link
Author

Ah perfect! The instance field it is.. Thx!

@toburger
Copy link
Author

If someone is having trouble accessing the underlying instance and registering the event with the hooks API here is the working TS code:

  const [signaturePad, setSignaturePad] = React.useState<SignaturePad>();
  const signaturePadRef = React.useCallback((signaturePad: SignaturePad) => {
    setSignaturePad(signaturePad);
  }, []);
  React.useEffect(() => {
    if (signaturePad) {
      signaturePad.instance.onEnd = () => {
        setSignature(signaturePad.instance.toDataURL());
      };
    }
  }, [signaturePad]);

More info of why this is quite tricky can be found here or here.

@JamesRobertWiseman
Copy link

The above .onEnd no longer works as it was replaced by event emitters. See here

The following updated code works:

  const [signaturePad, setSignaturePad] = React.useState<SignaturePad>();

  const signaturePadRef = React.useCallback((signaturePad: SignaturePad) => {
    setSignaturePad(signaturePad);
  }, []);

  React.useEffect(() => {
    if (signaturePad) {
      signaturePad.instance.addEventListener('endStroke', () => {
        setSignature(signaturePad.toDataURL());
      });
    }
  }, [signaturePad]);

@toburger
Copy link
Author

Nice, thanks for the example!
I have to upgrade my code, but I suspect that it is necessary to remove the event listener in order to not reregister the event handler on every mount?

@JamesRobertWiseman
Copy link

You are right. The following will work:

  const [signaturePad, setSignaturePad] = React.useState<SignaturePad>();

  const signaturePadRef = React.useCallback((signaturePad: SignaturePad) => {
    setSignaturePad(signaturePad);
  }, []);

  const onStrokeEnd = () => {
    setSignature(signaturePad.toData());
  }

  React.useEffect(() => {
    if (signaturePad) {
      signaturePad.instance.addEventListener('endStroke', onStrokeEnd)
    }
    //cleanup event listener
    () => signaturePad.instance.removeEventListener('endStroke', onStrokeEnd);
  }, [signaturePad]);

@sankarkumar23
Copy link

sankarkumar23 commented Apr 28, 2022

@JamesRobertWiseman
Have you tested the code?

@JamesRobertWiseman
Copy link

@sankarkumar23 Yes, and it is working fine my end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants