browser staff : inline print content
authorBill Erickson <berick@esilibrary.com>
Wed, 9 Apr 2014 14:20:52 +0000 (10:20 -0400)
committerBill Erickson <berick@esilibrary.com>
Wed, 9 Apr 2014 14:20:52 +0000 (10:20 -0400)
adds support for an inline print container controlled by print css for
printing content from the browser when the external print engine is not
available

Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/css/print.css.tt2 [new file with mode: 0644]
Open-ILS/src/templates/staff/css/style.css.tt2
Open-ILS/src/templates/staff/t_base.tt2
Open-ILS/web/js/ui/default/staff/services/grid.js
Open-ILS/web/js/ui/default/staff/services/printstore.js

diff --git a/Open-ILS/src/templates/staff/css/print.css.tt2 b/Open-ILS/src/templates/staff/css/print.css.tt2
new file mode 100644 (file)
index 0000000..c7feb78
--- /dev/null
@@ -0,0 +1,12 @@
+
+/* hide everything but the print div */
+head { display: none; } /* just to be safe */
+body div:not([id="print-div"]) { display:none }
+
+div { display: none }
+#print-div { display: block }
+#print-div div { display: block }
+
+[%# 
+vim: ft=css 
+%]
index 38dc7e4..5c19ab0 100644 (file)
@@ -86,6 +86,8 @@ table.list tr.selected td {
 .pad-horiz {padding : 0px 10px 0px 10px; }
 .pad-vert {padding : 20px 0px 10px 0px;}
 
+#print-div { display: none; }
+
 
 /* ----------------------------------------------------------------------
  * Grid
index 6c3ac7b..0f54e03 100644 (file)
@@ -10,6 +10,7 @@
     <!-- TODO: remote hosted CSS should be hosted locally instead -->
     <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
     <link rel="stylesheet" href="[% ctx.base_path %]/staff/css/style.css" />
+    <link rel="stylesheet" href="[% ctx.base_path %]/staff/css/print.css" type="text/css" media="print" />
   </head>
   <body>
     [% INCLUDE "staff/t_navbar.tt2" %]
@@ -20,5 +21,6 @@
       # App-specific JS load commands go into an APP_JS block.
       PROCESS APP_JS;
     %]
+    <div id="print-div" eg-print-container></div>
   </body>
 </html>
index 1f4b118..7051ff4 100644 (file)
@@ -440,27 +440,29 @@ angular.module('egGridMod',
 
                 // columns
                 angular.forEach(grid.columnsProvider.columns,
-                    function(col, idx) {
-                        csvStr += grid.csvDatum(col.name);
-                        if (idx < colCount -1) csvStr += ',';
+                    function(col) {
+                        if (!grid.columnsProvider.visible[col.name]) return;
+                        csvStr += grid.csvDatum(col.label);
+                        csvStr += ',';
                     }
                 );
 
-                csvStr += "\n";
+                csvStr = csvStr.replace(/,$/,'\n');
 
                 // items
                 angular.forEach(grid.items, function(item) {
                     angular.forEach(grid.columnsProvider.columns, 
-                        function(col, idx) {
+                        function(col) {
+                            if (!grid.columnsProvider.visible[col.name]) return;
                             // bare value
                             var val = grid.dataProvider.itemFieldValue(item, col);
                             // filtered value (dates, etc.)
                             val = $filter('egGridValueFilter')(val, col);
                             csvStr += grid.csvDatum(val);
-                            if (idx < colCount -1) csvStr += ',';
+                            csvStr += ',';
                         }
                     );
-                    csvStr += "\n";
+                    csvStr = csvStr.replace(/,$/,'\n');
                 });
 
                 return csvStr;
index c924f43..c4a886d 100644 (file)
@@ -40,11 +40,11 @@ angular.module('egCoreMod')
         service.socket = null;
         service.hatchAvailable = false;
         angular.forEach(service.pending, function(msg) {
+            delete service.pending[msg.msgid];
             switch(msg.action) {
                 case 'print':
                     return service.browserPrint(msg.mime, msg.value);
             }
-            delete service.pending[msg.msgid];
         });
     }
 
@@ -66,6 +66,7 @@ angular.module('egCoreMod')
         }
 
         service.socket.onclose = function() {
+            if (service.hatchAvailable === false) return; // already registered
             console.debug("disconnected from Hatch");
             service.socket = null;
             service.hatchAvailable = null; // reset
@@ -101,36 +102,8 @@ angular.module('egCoreMod')
     }
 
     service.browserPrint = function(mime, data) {
-        
-        // TODO: cleanup / angularize
-
-        console.log(data);
-        var w = window.open(
-            'data:text/plain;charset=utf-8,' + encodeURIComponent(data));
-
-        w.addEventListener('DOMContentLoaded', function(e) {
-            w.print();
-            $timeout(
-                function(){
-                    console.log(w.matchMedia('print'));
-                    w.close()
-                },
-                // TODO:
-                // http://stackoverflow.com/questions/18325025/how-to-detect-window-print-finish
-                3000
-            );
-        }, false);
-
-        return;
-
-        switch (mime) {
-            case 'text/csv':
-            case 'text/plain':
-                $window.print(data);
-                break;
-            case 'text/html':
-                // TODO: generate the document and print it
-        }
+        // let our local print container handle printing
+        service.onBrowserPrint(mime, data);
     }
 
     service.print = function(mime, data) {
@@ -149,4 +122,41 @@ angular.module('egCoreMod')
     }
 
     return service;
-}]);
+}])
+
+/**
+ * Container for inserting print data into the browser page.
+ * On insert, $window.print() is called to print the data.
+ * The div housing eg-print-container must apply the correct
+ * print media CSS to ensure this content (and not the rest
+ * of the page) is printed.
+ */
+.directive('egPrintContainer', function() {
+    return {
+        restrict : 'AE',
+        template : '<div>{{printContent}}</div>',
+        controller : ['$scope', '$window', 'egPrintStore', 
+            function($scope, $window, egPrintStore) {
+                egPrintStore.onBrowserPrint = function(mime, data) {
+                    console.log('printing ' + data.length + ' of ' + mime);
+                    switch(mime) {
+                        case 'text/csv':
+                        case 'text/plain':
+                            $scope.printContent = data;
+                            break;
+                        case 'text/html':
+                            console.error('print text/html not yet supported');
+                            break;
+                    }
+
+                    // force the template to absorb the data before printing
+                    $scope.$apply();
+                    $window.print();
+                    $scope.printContent = '';
+                }
+            }
+        ]
+    }
+});
+
+