2 * egPrint : manage print templates, process templates, print content
4 * TODO: create configurable links between print template and context.
6 angular.module('egCoreMod')
9 ['$q','$window','$timeout','$http','egHatch','egAuth','egIDL','egOrg','egEnv',
10 function($q , $window , $timeout , $http , egHatch , egAuth , egIDL , egOrg , egEnv) {
14 service.template_base_path = 'share/print_templates/t_';
17 * context : 'default', 'receipt','label', etc.
18 * scope : data loaded into the template environment
19 * template : template name (e.g. 'checkout', 'transit_slip'
20 * content : content to print. If 'template' is set, content is
21 * derived from the template.
22 * content_type : 'text/html', 'text/plain', 'text/csv'
23 * show_dialog : boolean, if true, print dialog is shown. This setting
24 * only affects remote printers, since browser printers
25 * do not allow such control
27 service.print = function(args) {
28 if (!args) return $q.when();
31 // fetch the template, then proceed to printing
33 return service.getPrintTemplate(args.template)
34 .then(function(content) {
35 args.content = content;
36 if (!args.content_type) args.content_type = 'html';
37 return service.print_content(args);
42 return service.print_content(args);
45 // add commonly used attributes to the print scope
46 service.fleshPrintScope = function(scope) {
47 if (!scope) scope = {};
48 scope.today = new Date().toISOString();
49 scope.staff = egIDL.toHash(egAuth.user());
50 scope.current_location =
51 egIDL.toHash(egOrg.get(egAuth.user().ws_ou()));
54 // Template has been fetched (or no template needed)
55 // Process the template and send the result off to the printer.
56 service.print_content = function(args) {
57 service.fleshPrintScope(args.scope);
60 if (args.content_type == 'text/html') {
62 // all HTML content is assumed to require compilation,
63 // regardless of the print destination
64 promise = service.ingest_print_content(
65 args.content_type, args.content, args.scope);
68 // text content does not require compilation for remote printing
69 promise = $q.when(args.content);
72 // TODO: link print context to template type
73 var context = args.context || 'default';
75 return promise.then(function(html) {
77 return egHatch.remotePrint(context,
78 args.content_type, html, args.show_dialog)['catch'](
81 // remote print not available;
83 if (egHatch.hatchRequired()) {
84 console.error("Unable to print data; "
85 + "hatchRequired=true, but hatch is not connected");
89 if (args.content_type != 'text/html') {
90 // text content does require compilation
91 // (absorption) for browser printing
92 return service.ingest_print_content(
93 args.content_type, args.content, args.scope
94 ).then(function() { $window.print(); service.clear_print_content(); });
96 // HTML content is already ingested and accessible
97 // within the page to the printer.
99 service.clear_print_content();
106 // loads an HTML print template by name from the server
107 // If no template is available in local/hatch storage,
108 // fetch the template as an HTML file from the server.
109 service.getPrintTemplate = function(name) {
110 var deferred = $q.defer();
112 egHatch.getItem('eg.print.template.' + name)
113 .then(function(html) {
116 // we have a locally stored template
117 deferred.resolve(html);
121 var path = service.template_base_path + name;
122 console.debug('fetching template ' + path);
125 .success(function(data) { deferred.resolve(data) })
127 console.error('unable to locate print template: ' + name);
132 return deferred.promise;
135 service.storePrintTemplate = function(name, html) {
136 return egHatch.setItem('eg.print.template.' + name, html);
144 * Container for inserting print data into the browser page.
145 * On insert, $window.print() is called to print the data.
146 * The div housing eg-print-container must apply the correct
147 * print media CSS to ensure this content (and not the rest
148 * of the page) is printed.
151 // FIXME: only apply print CSS when print commands are issued via the
152 // print container, otherwise using the browser's native print page
153 // option will always result in empty pages. Move the print CSS
154 // out of the standalone CSS file and put it into a template file
155 // for this directive.
156 .directive('egPrintContainer', ['$compile', '$http', function($compile, $http) {
159 scope : {}, // isolate our scope
160 link : function(scope, element, attrs) {
164 ['$scope','$q','$window','$timeout','egHatch','egPrint','egEnv',
165 function($scope , $q , $window , $timeout , egHatch , egPrint , egEnv) {
167 egPrint.clear_print_content = function() {
169 $compile($scope.elm.contents())($scope.$new(true));
172 egPrint.ingest_print_content = function(type, content, printScope) {
174 if (type == 'text/csv' || type == 'text/plain') {
175 // preserve newlines, spaces, etc.
176 content = '<pre>' + content + '</pre>';
179 return $http.get(egEnv.basePath + 'css/print.css').then(
181 content = '<style type="text/css" media="print">' +
185 return finish_ingest_print_content(type, content, printScope);
188 return finish_ingest_print_content(type, content, printScope);
194 function finish_ingest_print_content(type, content, printScope) {
195 $scope.elm.html(content);
197 var sub_scope = $scope.$new(true);
198 angular.forEach(printScope, function(val, key) {
199 sub_scope[key] = val;
202 var resp = $compile($scope.elm.contents())(sub_scope);
204 var deferred = $q.defer();
206 // give the $digest a chance to complete then
207 // resolve with the compiled HTML from our
211 resp.contents()[0].parentNode.innerHTML
215 return deferred.promise;