293 lines
9.2 KiB
JavaScript
293 lines
9.2 KiB
JavaScript
//>>built
|
|
define("dojox/grid/enhanced/plugins/Printer", [
|
|
"dojo/_base/declare",
|
|
"dojo/_base/html",
|
|
"dojo/_base/Deferred",
|
|
"dojo/_base/lang",
|
|
"dojo/_base/sniff",
|
|
"dojo/_base/xhr",
|
|
"dojo/_base/array",
|
|
"dojo/query",
|
|
"dojo/DeferredList",
|
|
"../_Plugin",
|
|
"../../EnhancedGrid",
|
|
"./exporter/TableWriter"
|
|
], function(declare, html, Deferred, lang, has, xhr, array, query, DeferredList, _Plugin, EnhancedGrid, TableWriter){
|
|
|
|
var Printer = declare("dojox.grid.enhanced.plugins.Printer", _Plugin, {
|
|
// summary:
|
|
// Provide printGrid function to the grid.
|
|
// example:
|
|
// | dojo.require("dojox.grid.enhanced.plugins.Printer");
|
|
// | dijit.byId("grid1").printGrid("my grid", //A title for the grid,optional
|
|
// | ["cssfile1.css","cssfile2.css"],//An array of css files to decorate the printed gird,optional
|
|
// | {table:"border='border'"} //tagName:"attrbuteList" pairs, optional,
|
|
// | //control the html tags in the generated html
|
|
// | );
|
|
|
|
// __printArgs: {
|
|
// title: String
|
|
// A title of the printed page can be specified. Optional.
|
|
// If given, it's shown in an <h1> tag at the top of the page.
|
|
// cssFiles: Array | String
|
|
// CSS file paths. Optional.
|
|
// Every row and column is given CSS classes, including:
|
|
// grid_row_{row-number}, grid_odd_row, grid_even_row, grid_header,
|
|
// grid_col_{col-number}, grid_odd_col, grid_even_col
|
|
// {row_number} and {col-number} are both integers starting from 1.
|
|
// Row classes are for <thead> and <tbody> tags.
|
|
// Column classes are for <th> and <td> tags.
|
|
// Users can use these classes in the CSS files, but cannot define their own.
|
|
// writerArgs: Object (Association Array)
|
|
// Arguments for TableWriter.
|
|
// fetchArgs: object?
|
|
// Any arguments for store.fetch
|
|
// }
|
|
|
|
// name: String
|
|
// Plugin name
|
|
name: "printer",
|
|
|
|
constructor: function(grid){
|
|
// summary:
|
|
// only newed by _Plugin
|
|
// inGrid: EnhancedGrid
|
|
// The grid to plug in to.
|
|
this.grid = grid;
|
|
this._mixinGrid(grid);
|
|
|
|
//For print, we usually need the HTML instead of raw data.
|
|
grid.setExportFormatter(function(data, cell, rowIndex, rowItem){
|
|
return cell.format(rowIndex, rowItem);
|
|
});
|
|
},
|
|
_mixinGrid: function(){
|
|
var g = this.grid;
|
|
g.printGrid = lang.hitch(this, this.printGrid);
|
|
g.printSelected = lang.hitch(this, this.printSelected);
|
|
g.exportToHTML = lang.hitch(this, this.exportToHTML);
|
|
g.exportSelectedToHTML = lang.hitch(this, this.exportSelectedToHTML);
|
|
g.normalizePrintedGrid = lang.hitch(this, this.normalizeRowHeight);
|
|
},
|
|
printGrid: function(args){
|
|
// summary:
|
|
// Print all the data in the grid, using title as a title,
|
|
// decorating generated html by cssFiles,
|
|
// using tagName:"attrbuteList" pairs(writerArgs) to control html tags
|
|
// in the generated html string.
|
|
// tags:
|
|
// public
|
|
// args: __printArgs?
|
|
// Arguments for print.
|
|
this.exportToHTML(args, lang.hitch(this, this._print));
|
|
},
|
|
printSelected: function(args){
|
|
// summary:
|
|
// Print selected data. All other features are the same as printGrid.
|
|
// For meaning of arguments see function *printGrid*
|
|
// tags:
|
|
// public
|
|
// args: __printArgs?
|
|
// Arguments for print.
|
|
this.exportSelectedToHTML(args, lang.hitch(this, this._print));
|
|
},
|
|
exportToHTML: function(args, onExported){
|
|
// summary:
|
|
// Export to HTML string, but do NOT print.
|
|
// Users can use this to implement print preview.
|
|
// For meaning of the 1st-3rd arguments see function *printGrid*.
|
|
// tags:
|
|
// public
|
|
// args: __printArgs?
|
|
// Arguments for print.
|
|
// onExported: function(string)
|
|
// call back function
|
|
args = this._formalizeArgs(args);
|
|
var _this = this;
|
|
this.grid.exportGrid("table", args, function(str){
|
|
_this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str).then(onExported);
|
|
});
|
|
},
|
|
exportSelectedToHTML: function(args, onExported){
|
|
// summary:
|
|
// Export selected rows to HTML string, but do NOT print.
|
|
// Users can use this to implement print preview.
|
|
// For meaning of arguments see function *printGrid*
|
|
// tags:
|
|
// public
|
|
// args: __printArgs?
|
|
// Arguments for print.
|
|
args = this._formalizeArgs(args);
|
|
var _this = this;
|
|
this.grid.exportSelected("table", args.writerArgs, function(str){
|
|
_this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str).then(onExported);
|
|
});
|
|
},
|
|
|
|
_loadCSSFiles: function(cssFiles){
|
|
var dl = array.map(cssFiles, function(cssFile){
|
|
cssFile = lang.trim(cssFile);
|
|
if(cssFile.substring(cssFile.length - 4).toLowerCase() === '.css'){
|
|
return xhr.get({
|
|
url: cssFile
|
|
});
|
|
}else{
|
|
var d = new Deferred();
|
|
d.callback(cssFile);
|
|
return d;
|
|
}
|
|
});
|
|
return DeferredList.prototype.gatherResults(dl);
|
|
},
|
|
_print: function(/* string */htmlStr){
|
|
// summary:
|
|
// Do the print job.
|
|
// tags:
|
|
// private
|
|
// htmlStr: String
|
|
// The html content string to be printed.
|
|
// returns:
|
|
// undefined
|
|
var win, _this = this,
|
|
fillDoc = function(w){
|
|
var doc = w.document;
|
|
doc.open();
|
|
doc.write(htmlStr);
|
|
doc.close();
|
|
_this.normalizeRowHeight(doc);
|
|
};
|
|
if(!window.print){
|
|
//We don't have a print facility.
|
|
return;
|
|
}else if(has("chrome") || has("opera")){
|
|
//referred from dijit._editor.plugins.Print._print()
|
|
//In opera and chrome the iframe.contentWindow.print
|
|
//will also print the outside window. So we must create a
|
|
//stand-alone new window.
|
|
win = window.open("javascript: ''", "",
|
|
"status=0,menubar=0,location=0,toolbar=0,width=1,height=1,resizable=0,scrollbars=0");
|
|
fillDoc(win);
|
|
win.print();
|
|
//Opera will stop at this point, showing the popping-out window.
|
|
//If the user closes the window, the following codes will not execute.
|
|
//If the user returns focus to the main window, the print function
|
|
// is executed, but still a no-op.
|
|
win.close();
|
|
}else{
|
|
//Put private things in deeper namespace to avoid poluting grid namespace.
|
|
var fn = this._printFrame,
|
|
dn = this.grid.domNode;
|
|
if(!fn){
|
|
var frameId = dn.id + "_print_frame";
|
|
if(!(fn = html.byId(frameId))){
|
|
//create an iframe to store the grid data.
|
|
fn = html.create("iframe");
|
|
fn.id = frameId;
|
|
fn.frameBorder = 0;
|
|
html.style(fn, {
|
|
width: "1px",
|
|
height: "1px",
|
|
position: "absolute",
|
|
right: 0,
|
|
bottom: 0,
|
|
border: "none",
|
|
overflow: "hidden"
|
|
});
|
|
if(!has("ie")){
|
|
html.style(fn, "visibility", "hidden");
|
|
}
|
|
dn.appendChild(fn);
|
|
}
|
|
//Reuse this iframe
|
|
this._printFrame = fn;
|
|
}
|
|
win = fn.contentWindow;
|
|
fillDoc(win);
|
|
//IE requires the frame to be focused for print to work, and it's harmless for FF.
|
|
win.focus();
|
|
win.print();
|
|
}
|
|
},
|
|
_wrapHTML: function(/* string */title, /* Array */cssFiles, /* string */body_content){
|
|
// summary:
|
|
// Put title, cssFiles, and body_content together into an HTML string.
|
|
// tags:
|
|
// private
|
|
// title: String
|
|
// A title for the html page.
|
|
// cssFiles: Array
|
|
// css file pathes.
|
|
// body_content: String
|
|
// Content to print, not including <head></head> part and <html> tags
|
|
// returns:
|
|
// the wrapped HTML string ready for print
|
|
return this._loadCSSFiles(cssFiles).then(function(cssStrs){
|
|
var i, sb = ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
|
|
'<html ', html._isBodyLtr() ? '' : 'dir="rtl"', '><head><title>', title,
|
|
'</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>'];
|
|
for(i = 0; i < cssStrs.length; ++i){
|
|
sb.push('<style type="text/css">', cssStrs[i], '</style>');
|
|
}
|
|
sb.push('</head>');
|
|
if(body_content.search(/^\s*<body/i) < 0){
|
|
body_content = '<body>' + body_content + '</body>';
|
|
}
|
|
sb.push(body_content, '</html>');
|
|
return sb.join('');
|
|
});
|
|
},
|
|
normalizeRowHeight: function(doc){
|
|
var views = query(".grid_view", doc.body);
|
|
var headPerView = array.map(views, function(view){
|
|
return query(".grid_header", view)[0];
|
|
});
|
|
var rowsPerView = array.map(views, function(view){
|
|
return query(".grid_row", view);
|
|
});
|
|
var rowCount = rowsPerView[0].length;
|
|
var i, v, h, maxHeight = 0;
|
|
for(v = views.length - 1; v >= 0; --v){
|
|
h = html.contentBox(headPerView[v]).h;
|
|
if(h > maxHeight){
|
|
maxHeight = h;
|
|
}
|
|
}
|
|
for(v = views.length - 1; v >= 0; --v){
|
|
html.style(headPerView[v], "height", maxHeight + "px");
|
|
}
|
|
for(i = 0; i < rowCount; ++i){
|
|
maxHeight = 0;
|
|
for(v = views.length - 1; v >= 0; --v){
|
|
h = html.contentBox(rowsPerView[v][i]).h;
|
|
if(h > maxHeight){
|
|
maxHeight = h;
|
|
}
|
|
}
|
|
for(v = views.length - 1; v >= 0; --v){
|
|
html.style(rowsPerView[v][i], "height", maxHeight + "px");
|
|
}
|
|
}
|
|
var left = 0, ltr = html._isBodyLtr();
|
|
for(v = 0; v < views.length; ++v){
|
|
html.style(views[v], ltr ? "left" : "right", left + "px");
|
|
left += html.marginBox(views[v]).w;
|
|
}
|
|
},
|
|
_formalizeArgs: function(args){
|
|
args = (args && lang.isObject(args)) ? args : {};
|
|
args.title = String(args.title) || "";
|
|
if(!lang.isArray(args.cssFiles)){
|
|
args.cssFiles = [args.cssFiles];
|
|
}
|
|
args.titleInBody = args.title ? ['<h1>', args.title, '</h1>'].join('') : '';
|
|
return args; //Object
|
|
}
|
|
});
|
|
|
|
EnhancedGrid.registerPlugin(Printer/*name:'printer'*/, {
|
|
"dependency": ["exporter"]
|
|
});
|
|
|
|
return Printer;
|
|
});
|