Reputation: 1636
Within a loop, I have:
<div class="barcode" class="thumbnail">
<canvas class="ean" barcode-generator barcode-value="9002236311036"> </canvas>
</div>
Which loops out a load of barcodes. I've statically added the barcode-value, but the intention is for this to be added via {{barcodeNumber}}
I've found a really nice plugin https://github.com/joushx/jQuery.EAN13 which converts a number to a barcode.
Following various tutorials, I've written the following Directive (although I don't quite get the HOW or WHY as yet). I've also included jquery above Angular, and the plugin after Angular.
app.directive('barcodeGenerator', function () {
return {
restrict: 'A',
scope: {
barcodeValue: '='
},
link: function (scope, elem, attrs) {
console.log("Recognized the barcode directive usage");
$('.ean').EAN13(scope.barcodeValue);
}
}
});
The console.log works - but then the bit where I call the plugin doesn't... Chrome debug displays the following error:
TypeError: Object 9002236311036 has no method 'split'
I'm not sure what I'm doing wrong - have read lots of forum posts, but can't quite grok it.
Thanks, Rob
Edit - following on from Francisco's post below - adding toString() has worked. Only thing is, I don't know why / how this is working.
app.directive('barcodeGenerator', function () {
return {
restrict: 'A',
scope: {
barcodeValue: '='
},
link: function (scope, elem, attrs) {
console.log("Recognized the barcode directive usage");
$('.ean').EAN13(scope.barcodeValue.toString());
}
}
});
So I've done a little refactoring:
app.directive('ean', function () {
return {
restrict: 'C',
scope: {
barcodeValue: '='
},
link: function (scope, elem) {
console.log("Recognized the barcode directive usage");
$(elem).EAN13(scope.barcodeValue.toString());
}
}
});
Then in my html, I added:
<div class="barcode" class="thumbnail">
<canvas class="ean" barcode-value="{{barcode}}"> </canvas>
</div>
And this is where it errors... the barcode-value. Before it was hardwired and worked... now I try to put it in the loop, it doesn't.
Edit...
<div class="barcode" class="thumbnail">
<canvas class="ean" barcode-value="barcode"> </canvas>
</div>
Removing the curly brackets worked.... hmm... I need to get a manual...
Upvotes: 1
Views: 3077
Reputation: 1636
Using this library for the barcode: https://github.com/joushx/jQuery.EAN13
app.directive('ean', function () {
return {
restrict: 'C',
scope: {
barcodeValue: '='
},
link: function (scope, elem, attr) {
console.log("Recognized the barcode directive usage");
$(elem).EAN13(scope.barcodeValue.toString());
}
}
});
and
<div class="barcode" class="thumbnail" ng-show="voucher.barcode">
<canvas class="ean" barcode-value="voucher.redemptionCode"> </canvas>
</div>
and if I recall correctly - any number you pump in gets converted to the barcode (although its been over a year since I did this... )
Hope this helps
Upvotes: 0
Reputation: 440
Trying to get something similar to work with no success..the barcode will just not display..do you have all your code on github to use?
Upvotes: 1
Reputation: 1727
The francisco.preller is absolutely right. Just one improvement is required. If you change
link: function (scope, elem, attrs) {
console.log("Recognized the barcode directive usage");
$('.ean').EAN13(scope.barcodeValue.toString());
}
with
link: function (scope, elem, attrs) {
console.log("Recognized the barcode directive usage");
elem.EAN13(scope.barcodeValue.toString());
}
Not only it becomes more angularized, but it also follows the role of the 'elem' parameter, which is already a jQuery object (or jQLite, which is a jQuery subset, if jQuery is not loaded). Any use of direct DOM manipulation is said to be a bad practice by Google, as it could not always be reflected in Angular's digest cycle and will cause unexpected behavior.
Upvotes: 2
Reputation: 6629
Directives are a way to extend HTML. The whole purpose behind doing this is that AngularJS encourages to keep all DOM manipulation outside of controllers so they become testable.
I won't get into detail of how exactly directives work, it's possibly both the most powerful and most confusing aspect of AngularJS.
In short though, referring to what you've done:
app.directive('barcodeGenerator', function () {
return {
// Restrict tells AngularJS how you will be declaring your directive in the markup.
// A = attribute, C = class, E = element and M = comment
restrict: 'A',
// The directive compiler actually happens before the $scope is available in AngularJS, therefore
// You need to pass certain values into your scope. In this instance, you are passing the barcodeValue
// attribute and telling it its equal. In other words where you use scope.barcodeValue.toString() below
// You are able to do this because of the below declaration. There are other symbols you can use to tell
// the compiler to do other things such as interpret the values as a method, but I'll let you investigate
scope: {
barcodeValue: '='
},
// The link function passes the element to the directive and allows you to manipulate the dom
// You could event try to replace $(.ean) with just elem below, since you are passing the scope,
// element and attribute to the function below, then using the jQuery plugin to do the rest.
link: function (scope, elem, attrs) {
console.log("Recognized the barcode directive usage");
$('.ean').EAN13(scope.barcodeValue.toString());
}
};
});
Upvotes: 7