diff options
| author | Tristan Zur <tzur@web.web.ccwn.org> | 2014-03-27 22:27:47 +0100 |
|---|---|---|
| committer | Tristan Zur <tzur@web.web.ccwn.org> | 2014-03-27 22:27:47 +0100 |
| commit | b62676ca5d3d6f6ba3f019ea3f99722e165a98d8 (patch) | |
| tree | 86722cb80f07d4569f90088eeaea2fc2f6e2ef94 /js/dojo/dojox/grid/enhanced/plugins/exporter | |
Diffstat (limited to 'js/dojo/dojox/grid/enhanced/plugins/exporter')
3 files changed, 517 insertions, 0 deletions
diff --git a/js/dojo/dojox/grid/enhanced/plugins/exporter/CSVWriter.js b/js/dojo/dojox/grid/enhanced/plugins/exporter/CSVWriter.js new file mode 100644 index 0000000..44006e2 --- /dev/null +++ b/js/dojo/dojox/grid/enhanced/plugins/exporter/CSVWriter.js @@ -0,0 +1,88 @@ +//>>built +define("dojox/grid/enhanced/plugins/exporter/CSVWriter", [ + "dojo/_base/declare", + "dojo/_base/array", + "./_ExportWriter", + "../Exporter" +], function(declare, array, _ExportWriter, Exporter){ + +Exporter.registerWriter("csv", "dojox.grid.enhanced.plugins.exporter.CSVWriter"); + +return declare("dojox.grid.enhanced.plugins.exporter.CSVWriter", _ExportWriter, { + // summary: + // Export grid to CSV format. + _separator: ',', + + _newline: "\r\n", + + constructor: function(/* object? */writerArgs){ + // summary: + // CSV default separator is ','. + // But we can also use our own. + // writerArgs: object? + // {separator:'...'} + if(writerArgs){ + this._separator = writerArgs.separator ? writerArgs.separator : this._separator; + this._newline = writerArgs.newline ? writerArgs.newline : this._newline; + } + this._headers = []; + this._dataRows = []; + }, + + _formatCSVCell: function(/* string */cellValue){ + // summary: + // Format cell value to follow CSV standard. + // See: http://en.wikipedia.org/wiki/Comma-separated_values + // tags: + // private + // cellValue: string + // The value in a cell. + // returns: + // The formatted content of a cell + if(cellValue === null || cellValue === undefined){ + return ''; + } + var result = String(cellValue).replace(/"/g, '""'); + if(result.indexOf(this._separator) >= 0 || result.search(/[" \t\r\n]/) >= 0){ + result = '"' + result + '"'; + } + return result; //String + }, + + beforeContentRow: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + var row = [], + func = this._formatCSVCell; + array.forEach(arg_obj.grid.layout.cells, function(cell){ + //We are not interested in indirect selectors and row indexes. + if(!cell.hidden && array.indexOf(arg_obj.spCols,cell.index) < 0){ + //We only need data here, not html + row.push(func(this._getExportDataForCell(arg_obj.rowIndex, arg_obj.row, cell, arg_obj.grid))); + } + }, this); + this._dataRows.push(row); + //We do not need to go into the row. + return false; //Boolean + }, + + handleCell: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + var cell = arg_obj.cell; + if(arg_obj.isHeader && !cell.hidden && array.indexOf(arg_obj.spCols,cell.index) < 0){ + this._headers.push(cell.name || cell.field); + } + }, + + toString: function(){ + // summary: + // Overrided from _ExportWriter + var result = this._headers.join(this._separator); + for(var i = this._dataRows.length - 1; i >= 0; --i){ + this._dataRows[i] = this._dataRows[i].join(this._separator); + } + return result + this._newline + this._dataRows.join(this._newline); //String + } +}); +}); diff --git a/js/dojo/dojox/grid/enhanced/plugins/exporter/TableWriter.js b/js/dojo/dojox/grid/enhanced/plugins/exporter/TableWriter.js new file mode 100644 index 0000000..0ea2c74 --- /dev/null +++ b/js/dojo/dojox/grid/enhanced/plugins/exporter/TableWriter.js @@ -0,0 +1,160 @@ +//>>built +define("dojox/grid/enhanced/plugins/exporter/TableWriter", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/dom-geometry", + "./_ExportWriter", + "../Exporter" +], function(declare, array, domGeometry, _ExportWriter, Exporter){ + +Exporter.registerWriter("table", "dojox.grid.enhanced.plugins.exporter.TableWriter"); + +return declare("dojox.grid.enhanced.plugins.exporter.TableWriter", _ExportWriter, { + // summary: + // Export grid to HTML table format. Primarily used by Printer plugin. + constructor: function(/* object? */writerArgs){ + // summary: + // The generated table only defines the col/rowspan, height and width of + // all the cells in the style attribute, no other attributes + // (like border, cellspacing, etc.) are used. + // Users can define these attributes in the writerArgs object, like: + // {table:"border='border'",thead:"cellspacing='3'"} + this._viewTables = []; + this._tableAttrs = writerArgs || {}; + }, + + _getTableAttrs: function(/* string */tagName){ + // summary: + // Get html attribute string for the given kind of tag. + // tags: + // private + // tagName: string + // An html tag name + // returns: + // The well formatted attributes for the given html table.tag + var attrs = this._tableAttrs[tagName] || ''; + //To ensure the attribute list starts with a space + if(attrs && attrs[0] != ' '){ + attrs = ' ' + attrs; + } + return attrs; //String + }, + + _getRowClass: function(/* object */arg_obj){ + // summary: + // Get CSS class string for a row + // tags: + // private + return arg_obj.isHeader ? " grid_header" : [//String + " grid_row grid_row_", + arg_obj.rowIdx + 1, + arg_obj.rowIdx % 2 ? " grid_even_row" : " grid_odd_row" + ].join(''); + }, + + _getColumnClass: function(/* object */arg_obj){ + // summary: + // Get CSS class string for a column + // tags: + // private + var col_idx = arg_obj.cell.index + arg_obj.colOffset + 1; + return [" grid_column grid_column_", col_idx,//String + col_idx % 2 ? " grid_odd_column" : " grid_even_column"].join(''); + }, + + beforeView: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + var viewIdx = arg_obj.viewIdx, + table = this._viewTables[viewIdx], + height, width = domGeometry.getMarginBox(arg_obj.view.contentNode).w; + if(!table){ + var left = 0; + for(var i = 0; i < viewIdx; ++i){ + left += this._viewTables[i]._width; + } + table = this._viewTables[viewIdx] = ['<div class="grid_view" style="position: absolute; top: 0; ', + domGeometry.isBodyLtr() ? 'left' : 'right', ':', left, + 'px;">']; + } + table._width = width; + if(arg_obj.isHeader){ + height = domGeometry.getContentBox(arg_obj.view.headerContentNode).h; + }else{ + var rowNode = arg_obj.grid.getRowNode(arg_obj.rowIdx); + if(rowNode){ + height = domGeometry.getContentBox(rowNode).h; + }else{ + //This row has not been loaded from store, so we should estimate it's height. + height = arg_obj.grid.scroller.averageRowHeight; + } + } + table.push('<table class="', this._getRowClass(arg_obj), + '" style="table-layout:fixed; height:', height, 'px; width:', width, 'px;" ', + 'border="0" cellspacing="0" cellpadding="0" ', + this._getTableAttrs("table"), + '><tbody ', this._getTableAttrs('tbody'), '>'); + return true; //Boolean + }, + + afterView: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + this._viewTables[arg_obj.viewIdx].push('</tbody></table>'); + }, + + beforeSubrow: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + this._viewTables[arg_obj.viewIdx].push('<tr', this._getTableAttrs('tr'), '>'); + return true; //Boolean + }, + + afterSubrow: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + this._viewTables[arg_obj.viewIdx].push('</tr>'); + }, + + handleCell: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + var cell = arg_obj.cell; + if(cell.hidden || array.indexOf(arg_obj.spCols, cell.index) >= 0){ + //We are not interested in indirect selectors and row indexes. + return; + } + var cellTagName = arg_obj.isHeader ? 'th' : 'td', + attrs = [cell.colSpan ? ' colspan="' + cell.colSpan + '"' : '', + cell.rowSpan ? ' rowspan="' + cell.rowSpan + '"' : '', + ' style="width: ', domGeometry.getContentBox(cell.getHeaderNode()).w, 'px;"', + this._getTableAttrs(cellTagName), + ' class="', this._getColumnClass(arg_obj), '"'].join(''), + table = this._viewTables[arg_obj.viewIdx]; + table.push('<', cellTagName, attrs, '>'); + if(arg_obj.isHeader){ + table.push(cell.name || cell.field); + } else{ + table.push(this._getExportDataForCell(arg_obj.rowIdx, arg_obj.row, cell, arg_obj.grid)); + } + table.push('</', cellTagName, '>'); + }, + + afterContent: function(){ + // summary: + // Overrided from _ExportWriter + array.forEach(this._viewTables, function(table){ + table.push('</div>'); + }); + }, + + toString: function(){ + // summary: + // Overrided from _ExportWriter + var viewsHTML = array.map(this._viewTables, function(table){ //String + return table.join(''); + }).join(''); + return ['<div style="position: relative;">', viewsHTML, '</div>'].join(''); + } +}); +}); diff --git a/js/dojo/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js b/js/dojo/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js new file mode 100644 index 0000000..14bd39f --- /dev/null +++ b/js/dojo/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js @@ -0,0 +1,269 @@ +//>>built +define("dojox/grid/enhanced/plugins/exporter/_ExportWriter", [ + "dojo/_base/declare" +], function(declare){ +//require Exporter here, so the implementations only need to require this file, +//and the users only need to require the implementation file. + +return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, { + // summary: + // This is an abstract class for all kinds of writers used in the Exporter plugin. + // It utilizes the strategy pattern to break the export work into several stages, + // and provide interfaces for all of them. + // Implementations might choose some of the functions in this class to override, + // thus providing their own functionalities. + // The Exporter will go through the grid line by line. So in every line, all the Views + // will be reached, and the header line is only handled once. + // An *argObj* object is passed to most functions of this class. + // It carries context arguments that make sense when they are called. + +/*===== + argObj: { + // grid: EnhancedGrid + // The grid object we are now handling. + grid: null, + + // isHeader: bool + // Indicating which context we're handling, header or content. + isHeader: true, + + // view: _View + // Reference to the current _View object. + view: null, + + // viewIdx: int + // The index of the current _View object in the views array. + // If the grid does not have any rowselector view, it conforms to the index + // in the _ViewManager.views. + viewIdx: -1, + + // subrow: _View.structure.cells[i] + // Reference to the current subrow. + // A subrow describe the innter structure of a row in a view, it's an array of cells + subrow: null, + + // subrowIdx: int + // The index of the current subrow in the subrow array: _View.structure.cells. + subrowIdx: -1, + + // cell: dojox.grid.__CellDef + // Reference to the current cell. + cell: null, + + //cellIdx: int + // The index of the current cell in the current subrow. + // It's different from cell.index, which is the index in the whole line. + cellIdx: -1, + + //row: item + // The current row of data (logically), a.k.a.: current item. + row: null, + + //rowIdx: int + // The index of the current row (item). + rowIdx: -1, + + // spCols: Array<int> + // An array of special column indexes(flat,not regarding structure). + // Special columns are typically attached to grid as a kind of UI facility + // by the grid widget, instead of some real data. + // For example, indirect selectors and row indexers. + // Users can choose to export it or not. + spCols: [], + + // colOffset: int + // If the grid has a _RowSelector view or something else, this view will NOT be + // passed to the user in argObj. So the column index (cell.index) will appear shifted + // (start from 1 instead of 0). This colOffset is provided to remove this shift. + // usage: + // var correctColIndex = argObj.cell.index + argObj.colOffset; + colOffset: 0 + }, +=====*/ + + constructor: function(/* object? */writerArgs){ + // summary: + // Writer initializations goes here. + // writerArgs: object? + // Any implementation of this class might accept a writerArgs object (optional), + // which contains some writer-specific arguments given by the user. + }, + _getExportDataForCell: function(rowIndex, rowItem, cell, grid){ + var data = (cell.get || grid.get).call(cell, rowIndex, rowItem); + if(this.formatter){ + return this.formatter(data, cell, rowIndex, rowItem); + }else{ + return data; + } + }, + beforeHeader: function(/* EnhancedGrid */grid){ + // summary: + // We are going to start the travel in the grid. + // Is there anything we should do now? + // tags: + // protected extension + // return: + // true: go on hanling the header row and then call afterHeader. + // false: skip the header row, won't call afterHeader. + return true; //Boolean + }, + afterHeader: function(){ + // summary: + // The header line has been handled. + // tags: + // protected extension + // returns: + // undefined + }, + beforeContent: function(/* Array */items){ + // summary: + // We are ready to go through all the contents(items). + // tags: + // protected extension + // items: + // All the items fetched from the store + // return: + // true: go on handling the contents and then call afterContent. + // false: skip all the contents, won't call afterContent. + return true; //Boolean + }, + afterContent: function(){ + // summary: + // We have finished the entire grid travel. + // Do some clean up work if you need to. + // tags: + // protected extension + // returns: + // undefined + }, + beforeContentRow: function(/* object */argObj){ + // summary: + // Before handling a line of data (not header). + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // row,rowIdx, + // spCols + // } + // return: + // true: go on handling the current data row and then call afterContentRow. + // false: skip the current data row, won't call afterContentRow. + return true; //Boolean + }, + afterContentRow: function(/* object */argObj){ + // summary: + // After handling a line of data (not header). + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // row,rowIdx, + // spCols + // } + // returns: + // undefined + }, + beforeView: function(/* object */argObj){ + // summary: + // Before handling a view. + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // view,viewIdx, + // spCols(if isHeader==false) + // } + // return: + // true: go on handling the current view and then call afterView. + // false: skip the current view, won't call afterView. + return true; //Boolean + }, + afterView: function(/* object */argObj){ + // summary: + // After handling a view. + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // view,viewIdx, + // spCols(if isHeader==false) + // } + // tags: + // protected extension + // returns: + // undefined + }, + beforeSubrow: function(/* object */argObj){ + // summary: + // Before handling a subrow in a line (defined in the grid structure). + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // row,rowIdx, + // view,viewIdx, + // subrow,subrowIdx, + // spCols(if isHeader==false) + // } + // return: + // true: go on handling the current subrow and then call afterSubrow. + // false: skip the current subrow, won't call afterSubrow. + return true; //Boolean + }, + afterSubrow: function(/* object */argObj){ + // summary: + // Before handling a subrow in a line (defined in the grid structure). + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // row,rowIdx, + // view,viewIdx, + // subrow,subrowIdx, + // spCols(if isHeader==false) + // } + // returns: + // undefined + }, + handleCell: function(/* object */argObj){ + // summary: + // Handle a header cell or data cell. + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // row,rowIdx, + // view,viewIdx, + // subrow,subrowIdx, + // cell,cellIdx, + // spCols(if isHeader==false) + // } + // returns: + // undefined + }, + toString: function(){ + // summary: + // Export to a string. + // tags: + // protected extension + // returns: + // The exported result string. + return ''; //String + } +}); +}); |
