RowExpander.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:8k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.1.0  * Copyright(c) 2006-2009 Ext JS, LLC  * licensing@extjs.com  * http://www.extjs.com/license  */ Ext.ns('Ext.ux.grid');
  2. /**
  3.  * @class Ext.ux.grid.RowExpander
  4.  * @extends Ext.util.Observable
  5.  * Plugin (ptype = 'rowexpander') that adds the ability to have a Column in a grid which enables
  6.  * a second row body which expands/contracts.  The expand/contract behavior is configurable to react
  7.  * on clicking of the column, double click of the row, and/or hitting enter while a row is selected.
  8.  *
  9.  * @ptype rowexpander
  10.  */
  11. Ext.ux.grid.RowExpander = Ext.extend(Ext.util.Observable, {
  12.     /**
  13.      * @cfg {Boolean} expandOnEnter
  14.      * <tt>true</tt> to toggle selected row(s) between expanded/collapsed when the enter
  15.      * key is pressed (defaults to <tt>true</tt>).
  16.      */
  17.     expandOnEnter : true,
  18.     /**
  19.      * @cfg {Boolean} expandOnDblClick
  20.      * <tt>true</tt> to toggle a row between expanded/collapsed when double clicked
  21.      * (defaults to <tt>true</tt>).
  22.      */
  23.     expandOnDblClick : true,
  24.     header : '',
  25.     width : 20,
  26.     sortable : false,
  27.     fixed : true,
  28.     menuDisabled : true,
  29.     dataIndex : '',
  30.     id : 'expander',
  31.     lazyRender : true,
  32.     enableCaching : true,
  33.     constructor: function(config){
  34.         Ext.apply(this, config);
  35.         this.addEvents({
  36.             /**
  37.              * @event beforeexpand
  38.              * Fires before the row expands. Have the listener return false to prevent the row from expanding.
  39.              * @param {Object} this RowExpander object.
  40.              * @param {Object} Ext.data.Record Record for the selected row.
  41.              * @param {Object} body body element for the secondary row.
  42.              * @param {Number} rowIndex The current row index.
  43.              */
  44.             beforeexpand: true,
  45.             /**
  46.              * @event expand
  47.              * Fires after the row expands.
  48.              * @param {Object} this RowExpander object.
  49.              * @param {Object} Ext.data.Record Record for the selected row.
  50.              * @param {Object} body body element for the secondary row.
  51.              * @param {Number} rowIndex The current row index.
  52.              */
  53.             expand: true,
  54.             /**
  55.              * @event beforecollapse
  56.              * Fires before the row collapses. Have the listener return false to prevent the row from collapsing.
  57.              * @param {Object} this RowExpander object.
  58.              * @param {Object} Ext.data.Record Record for the selected row.
  59.              * @param {Object} body body element for the secondary row.
  60.              * @param {Number} rowIndex The current row index.
  61.              */
  62.             beforecollapse: true,
  63.             /**
  64.              * @event collapse
  65.              * Fires after the row collapses.
  66.              * @param {Object} this RowExpander object.
  67.              * @param {Object} Ext.data.Record Record for the selected row.
  68.              * @param {Object} body body element for the secondary row.
  69.              * @param {Number} rowIndex The current row index.
  70.              */
  71.             collapse: true
  72.         });
  73.         Ext.ux.grid.RowExpander.superclass.constructor.call(this);
  74.         if(this.tpl){
  75.             if(typeof this.tpl == 'string'){
  76.                 this.tpl = new Ext.Template(this.tpl);
  77.             }
  78.             this.tpl.compile();
  79.         }
  80.         this.state = {};
  81.         this.bodyContent = {};
  82.     },
  83.     getRowClass : function(record, rowIndex, p, ds){
  84.         p.cols = p.cols-1;
  85.         var content = this.bodyContent[record.id];
  86.         if(!content && !this.lazyRender){
  87.             content = this.getBodyContent(record, rowIndex);
  88.         }
  89.         if(content){
  90.             p.body = content;
  91.         }
  92.         return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';
  93.     },
  94.     init : function(grid){
  95.         this.grid = grid;
  96.         var view = grid.getView();
  97.         view.getRowClass = this.getRowClass.createDelegate(this);
  98.         view.enableRowBody = true;
  99.         grid.on('render', this.onRender, this);
  100.         grid.on('destroy', this.onDestroy, this);
  101.     },
  102.     // @private
  103.     onRender: function() {
  104.         var grid = this.grid;
  105.         var mainBody = grid.getView().mainBody;
  106.         mainBody.on('mousedown', this.onMouseDown, this, {delegate: '.x-grid3-row-expander'});
  107.         if (this.expandOnEnter) {
  108.             this.keyNav = new Ext.KeyNav(this.grid.getGridEl(), {
  109.                 'enter' : this.onEnter,
  110.                 scope: this
  111.             });
  112.         }
  113.         if (this.expandOnDblClick) {
  114.             grid.on('rowdblclick', this.onRowDblClick, this);
  115.         }
  116.     },
  117.     
  118.     // @private    
  119.     onDestroy: function() {
  120.         if(this.keyNav){
  121.             this.keyNav.disable();
  122.             delete this.keyNav;
  123.         }
  124.         /*
  125.          * A majority of the time, the plugin will be destroyed along with the grid,
  126.          * which means the mainBody won't be available. On the off chance that the plugin
  127.          * isn't destroyed with the grid, take care of removing the listener.
  128.          */
  129.         var mainBody = this.grid.getView().mainBody;
  130.         if(mainBody){
  131.             mainBody.un('mousedown', this.onMouseDown, this);
  132.         }
  133.     },
  134.     // @private
  135.     onRowDblClick: function(grid, rowIdx, e) {
  136.         this.toggleRow(rowIdx);
  137.     },
  138.     onEnter: function(e) {
  139.         var g = this.grid;
  140.         var sm = g.getSelectionModel();
  141.         var sels = sm.getSelections();
  142.         for (var i = 0, len = sels.length; i < len; i++) {
  143.             var rowIdx = g.getStore().indexOf(sels[i]);
  144.             this.toggleRow(rowIdx);
  145.         }
  146.     },
  147.     getBodyContent : function(record, index){
  148.         if(!this.enableCaching){
  149.             return this.tpl.apply(record.data);
  150.         }
  151.         var content = this.bodyContent[record.id];
  152.         if(!content){
  153.             content = this.tpl.apply(record.data);
  154.             this.bodyContent[record.id] = content;
  155.         }
  156.         return content;
  157.     },
  158.     onMouseDown : function(e, t){
  159.         e.stopEvent();
  160.         var row = e.getTarget('.x-grid3-row');
  161.         this.toggleRow(row);
  162.     },
  163.     renderer : function(v, p, record){
  164.         p.cellAttr = 'rowspan="2"';
  165.         return '<div class="x-grid3-row-expander">&#160;</div>';
  166.     },
  167.     beforeExpand : function(record, body, rowIndex){
  168.         if(this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false){
  169.             if(this.tpl && this.lazyRender){
  170.                 body.innerHTML = this.getBodyContent(record, rowIndex);
  171.             }
  172.             return true;
  173.         }else{
  174.             return false;
  175.         }
  176.     },
  177.     toggleRow : function(row){
  178.         if(typeof row == 'number'){
  179.             row = this.grid.view.getRow(row);
  180.         }
  181.         this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);
  182.     },
  183.     expandRow : function(row){
  184.         if(typeof row == 'number'){
  185.             row = this.grid.view.getRow(row);
  186.         }
  187.         var record = this.grid.store.getAt(row.rowIndex);
  188.         var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);
  189.         if(this.beforeExpand(record, body, row.rowIndex)){
  190.             this.state[record.id] = true;
  191.             Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');
  192.             this.fireEvent('expand', this, record, body, row.rowIndex);
  193.         }
  194.     },
  195.     collapseRow : function(row){
  196.         if(typeof row == 'number'){
  197.             row = this.grid.view.getRow(row);
  198.         }
  199.         var record = this.grid.store.getAt(row.rowIndex);
  200.         var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);
  201.         if(this.fireEvent('beforecollapse', this, record, body, row.rowIndex) !== false){
  202.             this.state[record.id] = false;
  203.             Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');
  204.             this.fireEvent('collapse', this, record, body, row.rowIndex);
  205.         }
  206.     }
  207. });
  208. Ext.preg('rowexpander', Ext.ux.grid.RowExpander);
  209. //backwards compat
  210. Ext.grid.RowExpander = Ext.ux.grid.RowExpander;