pedro revolorio
pedro revolorio

Reputation: 31

react-signature-canvas clears initial user input

This signature input works but it has a quirk that has stumped us for some time now.. If the user starts signing the signature pad, as soon as they lift their finger or mouse, their input will be erased - but then the signature pad will work as expected and no longer clear the input.

If I remove this section..

    if (!input.value && this.sigRef && this.sigRef.clear) {
      this.clear();
    }

it will no longer erase the first user input - but then if you go and view another form, this previous signature will appear (although it's not actually persisted in the database).

At this time we're requiring our users to "sign" twice in order to avoid seeing a false signature which may be confusing. Anyone know what it could be? Thanks for taking a look!

import React, { Component } from "react";
import { Button, Form } from "semantic-ui-react";
import SignatureCanvas from "react-signature-canvas";

class SignatureInput extends Component {
  sigRef = {};
  fieldRef = {};
  state = {
    trimmedDataUrl: ""
  };
  canvasWidth = 200;
  canvasHeight = 100;

  clear() {
    this.sigRef.clear();
  }

  componentDidMount() {
    const { input, enabled } = this.props;

    this.setState({ trimmedDataURL: input.value.data });
    this.sigRef.fromDataURL(input.value.data);

    if (!enabled) {
      this.sigRef.off();
    }
  }

  render() {
    const { input, placeholder, enabled } = this.props;
    const { trimmedDataUrl } = this.state;

    if (!input.value && this.sigRef && this.sigRef.clear) {
      this.clear();
    }

    return (
      <Form.Field
        className="signature-holder"
        style={{ width: "100%", height: "100%" }}
      >
        <div
          ref={fieldRef => {
            this.fieldRef = fieldRef;
            if (fieldRef != null) {
              this.canvasWidth = fieldRef.getBoundingClientRect().width;
            }
          }}
        >
          <label>{placeholder}</label>
          <input type="hidden" name={input.name} value={trimmedDataUrl} />
          <SignatureCanvas
            onEnd={() => {
              const imageData = this.sigRef
                .getTrimmedCanvas()
                .toDataURL("image/png");
              this.setState({ trimmedDataURL: imageData });
              input.onChange({ name: input.name, data: imageData });
            }}
            ref={ref => {
              this.sigRef = ref;
            }}
            canvasProps={{
              width: this.canvasWidth,
              height: this.canvasHeight,
              className: "signature-canvas"
            }}
          />
          {enabled && (
            <Button
              onClick={() => this.clear()}
              type="button"
              content="Clear"
            />
          )}
        </div>
      </Form.Field>
    );
  }
}

export default SignatureInput;

CSS

.signature-holder {
  position: relative;
  border: 1px solid gray;
  display: block;
  margin: 0;
  -webkit-appearance: none;
  padding: 0.78571429em 1em;
  background: $white;
  border: 1px solid rgba(34, 36, 38, 0.15);
  outline: 0;
  color: rgba(0, 0, 0, 0.87);
  border-radius: 0.28571429rem;
  box-shadow: 0 0 0 0 transparent inset;
  -webkit-transition: color 0.1s ease, border-color 0.1s ease;
  transition: color 0.1s ease, border-color 0.1s ease;
  font-size: 1em;
  line-height: 1.2857;
  resize: vertical;
  label {
    position: absolute;
    top: 5px;
    left: 5px;
    color: lightgray !important;
  }
  button {
    position: absolute;
    bottom: 5px;
    right: 5px;
  }
}

Upvotes: 2

Views: 3788

Answers (1)

pedro revolorio
pedro revolorio

Reputation: 31

Figured it out..

componentWillUnmount() {
    this.setState({ trimmedDataURL: undefined });
    this.sigRef = {};
}

And then removed the portion that checks for an input and clears it..

Upvotes: 1

Related Questions