Reputation: 31
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
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