2 * egPrint : manage print templates, process templates, print content
5 angular.module('egCoreMod')
8 ['$q','$window','$timeout','$http','egHatch','egAuth','egIDL','egOrg','egEnv',
9 function($q , $window , $timeout , $http , egHatch , egAuth , egIDL , egOrg , egEnv) {
13 service.template_base_path = 'share/print_templates/t_';
16 * context : 'default', 'receipt','label', etc.
17 * scope : data loaded into the template environment
18 * template : template name (e.g. 'checkout', 'transit_slip'
19 * content : content to print. If 'template' is set, content is
20 * derived from the template.
21 * content_type : 'text/html', 'text/plain', 'text/csv'
22 * show_dialog : boolean, if true, print dialog is shown. This setting
23 * only affects remote printers, since browser printers
24 * do not allow such control
26 service.print = function(args) {
27 if (!args) return $q.when();
30 // fetch the template, then proceed to printing
32 return service.getPrintTemplate(args.template)
33 .then(function(content) {
34 args.content = content;
35 if (!args.content_type) args.content_type = 'html';
36 service.getPrintTemplateContext(args.template)
37 .then(function(context) {
38 args.context = context;
39 return service.print_content(args);
45 return service.print_content(args);
48 // add commonly used attributes to the print scope
49 service.fleshPrintScope = function(scope) {
50 if (!scope) scope = {};
51 scope.today = new Date().toISOString();
52 scope.staff = egIDL.toHash(egAuth.user());
53 scope.current_location =
54 egIDL.toHash(egOrg.get(egAuth.user().ws_ou()));
57 // Template has been fetched (or no template needed)
58 // Process the template and send the result off to the printer.
59 service.print_content = function(args) {
60 service.fleshPrintScope(args.scope);
63 if (args.content_type == 'text/html') {
65 // all HTML content is assumed to require compilation,
66 // regardless of the print destination
67 promise = service.ingest_print_content(
68 args.content_type, args.content, args.scope);
71 // text content does not require compilation for remote printing
72 promise = $q.when(args.content);
75 var context = args.context || 'default';
77 return promise.then(function(html) {
79 return egHatch.remotePrint(context,
80 args.content_type, html, args.show_dialog)['catch'](
83 // remote print not available;
85 if (egHatch.hatchRequired()) {
86 console.error("Unable to print data; "
87 + "hatchRequired=true, but hatch is not connected");
91 if (args.content_type != 'text/html') {
92 // text content does require compilation
93 // (absorption) for browser printing
94 return service.ingest_print_content(
95 args.content_type, args.content, args.scope
96 ).then(function() { $window.print(); service.clear_print_content(); });
98 // HTML content is already ingested and accessible
99 // within the page to the printer.
101 service.clear_print_content();
108 // loads an HTML print template by name from the server
109 // If no template is available in local/hatch storage,
110 // fetch the template as an HTML file from the server.
111 service.getPrintTemplate = function(name) {
112 var deferred = $q.defer();
114 egHatch.getItem('eg.print.template.' + name)
115 .then(function(html) {
118 // we have a locally stored template
119 deferred.resolve(html);
123 var path = service.template_base_path + name;
124 console.debug('fetching template ' + path);
127 .success(function(data) { deferred.resolve(data) })
129 console.error('unable to locate print template: ' + name);
134 return deferred.promise;
137 service.storePrintTemplate = function(name, html) {
138 return egHatch.setItem('eg.print.template.' + name, html);
141 service.getPrintTemplateContext = function(name) {
142 var deferred = $q.defer();
144 egHatch.getItem('eg.print.template_context.' + name)
146 function(context) { deferred.resolve(context); },
147 function() { deferred.resolve('default'); }
150 return deferred.promise;
152 service.storePrintTemplateContext = function(name, context) {
153 return egHatch.setItem('eg.print.template_context.' + name, context);
161 * Container for inserting print data into the browser page.
162 * On insert, $window.print() is called to print the data.
163 * The div housing eg-print-container must apply the correct
164 * print media CSS to ensure this content (and not the rest
165 * of the page) is printed.
168 // FIXME: only apply print CSS when print commands are issued via the
169 // print container, otherwise using the browser's native print page
170 // option will always result in empty pages. Move the print CSS
171 // out of the standalone CSS file and put it into a template file
172 // for this directive.
173 .directive('egPrintContainer', ['$compile', '$http', function($compile, $http) {
176 scope : {}, // isolate our scope
177 link : function(scope, element, attrs) {
181 ['$scope','$q','$window','$timeout','egHatch','egPrint','egEnv',
182 function($scope , $q , $window , $timeout , egHatch , egPrint , egEnv) {
184 egPrint.clear_print_content = function() {
186 $compile($scope.elm.contents())($scope.$new(true));
189 egPrint.ingest_print_content = function(type, content, printScope) {
191 if (type == 'text/csv' || type == 'text/plain') {
192 // preserve newlines, spaces, etc.
193 content = '<pre>' + content + '</pre>';
196 return $http.get(egEnv.basePath + 'css/print.css').then(
198 content = '<style type="text/css" media="print">' +
202 return finish_ingest_print_content(type, content, printScope);
205 return finish_ingest_print_content(type, content, printScope);
211 function finish_ingest_print_content(type, content, printScope) {
212 $scope.elm.html(content);
214 var sub_scope = $scope.$new(true);
215 angular.forEach(printScope, function(val, key) {
216 sub_scope[key] = val;
219 var resp = $compile($scope.elm.contents())(sub_scope);
221 var deferred = $q.defer();
223 // give the $digest a chance to complete then
224 // resolve with the compiled HTML from our
228 resp.contents()[0].parentNode.innerHTML
232 return deferred.promise;