Skip to content

Instantly share code, notes, and snippets.

@coryasilva
Last active February 3, 2016 13:10
Show Gist options
  • Save coryasilva/651fb409a8c59814772b to your computer and use it in GitHub Desktop.
Save coryasilva/651fb409a8c59814772b to your computer and use it in GitHub Desktop.
AngularJs Directive for jSignature
//https://github.com/brinley/jSignature
//<div data-j-signature="form.signature" data-pen-color="#ff00ff" data-line-color="#00ffff" data-readonly="readonly"></div>
app.directive('jSignature', ['$timeout',
function ($timeout) {
return {
restrict: 'EA',
scope: {
model: '=jSignature',
penColor: '@',
lineColor: '@',
readonly: '='
},
link: function (scope, element, attrs, controller) {
// Style undoButton
var undoButton = function () {
var undoButtonStyle = 'position:absolute;display:none;margin:0 !important;top:auto';
var $undoButton = $('<button type="button" class="btn btn-xs btn-default" style="' + undoButtonStyle +
'">Undo Last Stroke</button>').appendTo(this.$controlbarLower);
var buttonWidth = $undoButton.width();
$undoButton.css('left', Math.round(( this.canvas.width - buttonWidth ) / 2));
return $undoButton;
};
// Create Settings Object
var settings = {
UndoButton: undoButton
};
if (scope.lineColor) {
settings['decor-color'] = scope.lineColor;
}
if(scope.penColor) {
settings.color = scope.penColor;
}
// Build jSignature Element
element.jSignature(settings);
// Watch Model
scope.$watch('model', function(newValue, oldValue) {
if (typeof newValue !== 'undefined') {
var value = newValue.split(',');
if (value[1] && value[1].length > 0) {
try {
element.jSignature("setData", "data:" + newValue);
} catch (e) {
console.log('Nim: jSignature - Bad format while trying to setData', e);
}
} else {
element.jSignature('reset');
}
}
});
// Watch readOnly
scope.$watch('readonly', function (newValue, oldValue) {
if(newValue === true) {
element.jSignature('disable');
// Hide undo button
element.find('button').css({'display': 'none'});
} else {
element.jSignature('enable');
var currentModel = scope.model.split(',');
// Show undo button only if there are actions to undo?
if (currentModel[1] && currentModel[1].length > 0) {
element.find('button').css({'display': 'block'});
}
}
});
// Bind to jSignature Event
element.bind('change', function(e){
// $timeout, 100, true because event happens outside angular's digest cycle
// and change is called on setData
$timeout(function () {
// getData returns an array of [mimetype, string of jSignature's custom Base30-compressed format]
var dataPair = element.jSignature("getData","base30");
scope.model = dataPair.join(",");
}, 100, true);
});
}
};
}
]);
@Airswoop1
Copy link

Thanks for this! It was a great help in getting me started but I had some difficulties getting the directive to work.

I'm not sure if it was specific to my angular app but including the 'scope' object was giving me an error on the element.jSignature() initialization. I removed the scope object and then also added $(element) around any reference to the element. I also had to remove the "base30" arg in the call to jSignature("getData"). This allowed me to correctly capture the signature inside of the directive and not get an error. Note that I am using jQuery 1.11.

@coryasilva
Copy link
Author

@Airswoop1 Sorry I just now saw this comment. I am glad you found it helpful!

For the base30 you need to include the plugin from jSignature. Regarding the $(element) that should not matter as long as jQuery is loaded before angular. That said, I am unsure about the scope issue. It does not really hurt to remove it; I just typically use isolated scopes for stuff like this.

@hari8815
Copy link

I have tried your directive jsignature. It throwing following error Error: undefined is not a function (evaluating 'element.jSignature()')

@escapedcat
Copy link

I created a reduced and more basic version of the directive. Maybe this helps.

@LokeshBoran
Copy link

Can you Please post a HTML demo for it with angular validation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment