I’ve been trying to get a signature panel to work in grails. on the client side everything looks like it works, but I have been struggling on how to get the signature saved to the database record.
I’ve tried a couple different versions, the last one I ended up with came closest to describing how to use ImageMagic or the like using php, ruby, or python. However trying to do this in groovy left me lost because I’m still a little green on how to code. Also I’m not sure about using a 3rd party utility when this is going to be running on cloud foundry.
The plugin in called SignaturePanel, looks just like the other ones really…
jes-sherborne/jquery-signature-panel-plugin
Here is the code from my files.
First, create.gsp contains the Javascript code.
<title><g:message code="default.create.label" args="[entityName]" /></title>
<!-- jQuery signature element code begins here -->
<!--[if lt IE 9]><script type="text/javascript" src="${resource(dir: 'js', file: 'excanvas.compiled.js')}"></script><![endif]-->
<script type="text/javascript" src="${resource(dir: 'js', file: 'jquery-1.4.4.min.js')}"></script>
<script type="text/javascript" src="${resource(dir: 'js', file: 'jquery.signature-panel.js')}"></script>
<link rel="stylesheet" href="${resource(dir: 'css', file: 'jquery.signature-panel.css')}" type="text/css"/>
<script type="text/javascript">
function signatureOK(signatureData) {
// Send the signature to the server and generate an image file.
$.ajax({
url:"processSignature",
type:"POST",
data:JSON.stringify(signatureData),
contentType:"application/json; charset=utf-8",
dataType:"text",
success: function(data, textStatus, jqXHR){
$("#latest-signature").attr("src", data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
console.log(errorThrown);
}
});
$("#sig-panel").signaturePanel("clear");
}
function signatureCancel() {
alert("Cancelled.");
}
$(document).ready(function() {
$("#sig-panel").signaturePanel({
okCallback: signatureOK,
cancelCallback: signatureCancel
});
});
</script>
_form.gsp
<!-- Signature Panel Begins Here -->
<label for="sig"><g:message code="salesOrder.sig.label" default="Customer Signature" /></label>
<div class="fieldcontain" ${hasErrors(bean: salesOrderInstance, field: 'sig','error')} id="sig-panel" style="width: 500px; height: 150px; border: 0px none"></div>
<canvas id="latest-signature" style="width: 500px; height: 150px; border: 0px none"></canvas>
<!-- End of Signature Panel -->
Controller
// Capture Customer Signature JSON Data, Processes to Image, and Stream to Database
@Secured(['ROLE_ADMIN','ROLE_SALES'])
def processSignature() {
flash.message = message(code: 'default.created.message', args: [message(code: 'salesOrder.label', default: 'Signature'), ])
// groovy code here
// We need to read the JSON POST data
InputStream body = request.getInputStream();
log.info(body) // nothing happens here
}
Here is one of the Ruby examples I’m trying to figure out how to do in groovy.*(or if there is a better way… on the client side one can just right click and save the image. not really sure why this is so difficult for me)
### Generating image files on the server using Ruby
The Ruby library uses ImageMagick to generate a `Magick::Image` object, which you can use to write image files or stream the data in a variety of formats (PNG, JPEG, etc.). By default, the function will generate an image with the same pixel measurements as were originally captured on the client. You can also specify the size of the generated image, and SignaturePanel will scale the signature appropriately to fit within these bounds.
To generate the image, you will write code like this:
```ruby
require 'signature-panel.rb'
...
post '/process-signature' do
image = SignaturePanel::GenerateImage(request.body.read)
filename = 'latest-signature.png'
image.write(filename)
# If you want to stream your PNG directly to a database instead of saving a file,
# you can get a binary stream like this:
# image.to_blob {self.format = "PNG"}
content_type :text
# Send the name of the newly-generated file to the client
body filename
end
```
So my question once again is, how does one save the signature along with all the rest of the form data in to the database using groovy?
Also from my domain class I should mention
byte[] sig
sig nullable: true, maxSize: 1048567
Once we get this challenge solved, we can put this puppy to bed ; )
I’ve always just saved the JSON data into a text type field (like a CLOB in Oracle) and then used the library functions to show it on the page:
where
signatureDatais the JSON string.So you could change your domain class to include
This also allows you to do something I think is very cool, although whether it’s useful or not depends on your app. You can recreate and animate the actual signing of the signature:
The docs explain the optional
callbackfunction. I’ve never used that though.If you change part of your ajax call, removing the
contentTypeline because you are sending straight text and setting the hidden fieldAnd then add the hidden field in the form as
So now when they enter the signature and hit “OK” the
processSignaturewon’t really do anything – just act as a placeholder. The AJAX call will set the value of the hidden field on the page. Then when they submit the entire form (with other data) the normalsave()method will getsigas just another param and will automatically save it to asigfield in the domain class.You could access the data as a normal string in the
processSignaturemethod asparams.signatureif you needed to: