PageRenderTime 26ms CodeModel.GetById 16ms app.highlight 8ms RepoModel.GetById 0ms app.codeStats 0ms

/ext-4.1.0_b3/docs/source/RowExpander.html

https://bitbucket.org/srogerf/javascript
HTML | 250 lines | 220 code | 30 blank | 0 comment | 0 complexity | bdcc43cb14efa6c8b4da1bddfc7974dd MD5 | raw file
  1<!DOCTYPE html>
  2<html>
  3<head>
  4  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5  <title>The source code</title>
  6  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8  <style type="text/css">
  9    .highlight { display: block; background-color: #ddd; }
 10  </style>
 11  <script type="text/javascript">
 12    function highlight() {
 13      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
 14    }
 15  </script>
 16</head>
 17<body onload="prettyPrint(); highlight();">
 18  <pre class="prettyprint lang-js">// feature idea to enable Ajax loading and then the content
 19// cache would actually make sense. Should we dictate that they use
 20// data or support raw html as well?
 21
 22<span id='Ext-ux-RowExpander'>/**
 23</span> * @class Ext.ux.RowExpander
 24 * @extends Ext.AbstractPlugin
 25 * Plugin (ptype = 'rowexpander') that adds the ability to have a Column in a grid which enables
 26 * a second row body which expands/contracts.  The expand/contract behavior is configurable to react
 27 * on clicking of the column, double click of the row, and/or hitting enter while a row is selected.
 28 *
 29 * @ptype rowexpander
 30 */
 31Ext.define('Ext.ux.RowExpander', {
 32    extend: 'Ext.AbstractPlugin',
 33
 34    requires: [
 35        'Ext.grid.feature.RowBody',
 36        'Ext.grid.feature.RowWrap'
 37    ],
 38
 39    alias: 'plugin.rowexpander',
 40
 41    rowBodyTpl: null,
 42
 43<span id='Ext-ux-RowExpander-cfg-expandOnEnter'>    /**
 44</span>     * @cfg {Boolean} expandOnEnter
 45     * &lt;tt&gt;true&lt;/tt&gt; to toggle selected row(s) between expanded/collapsed when the enter
 46     * key is pressed (defaults to &lt;tt&gt;true&lt;/tt&gt;).
 47     */
 48    expandOnEnter: true,
 49
 50<span id='Ext-ux-RowExpander-cfg-expandOnDblClick'>    /**
 51</span>     * @cfg {Boolean} expandOnDblClick
 52     * &lt;tt&gt;true&lt;/tt&gt; to toggle a row between expanded/collapsed when double clicked
 53     * (defaults to &lt;tt&gt;true&lt;/tt&gt;).
 54     */
 55    expandOnDblClick: true,
 56
 57<span id='Ext-ux-RowExpander-cfg-selectRowOnExpand'>    /**
 58</span>     * @cfg {Boolean} selectRowOnExpand
 59     * &lt;tt&gt;true&lt;/tt&gt; to select a row when clicking on the expander icon
 60     * (defaults to &lt;tt&gt;false&lt;/tt&gt;).
 61     */
 62    selectRowOnExpand: false,
 63
 64    rowBodyTrSelector: '.x-grid-rowbody-tr',
 65    rowBodyHiddenCls: 'x-grid-row-body-hidden',
 66    rowCollapsedCls: 'x-grid-row-collapsed',
 67
 68
 69
 70    renderer: function(value, metadata, record, rowIdx, colIdx) {
 71        if (colIdx === 0) {
 72            metadata.tdCls = 'x-grid-td-expander';
 73        }
 74        return '&lt;div class=&quot;x-grid-row-expander&quot;&gt;&amp;#160;&lt;/div&gt;';
 75    },
 76
 77<span id='Ext-ux-RowExpander-event-expandbody'>    /**
 78</span>     * @event expandbody
 79     * &lt;b&lt;Fired through the grid's View&lt;/b&gt;
 80     * @param {HTMLElement} rowNode The &amp;lt;tr&gt; element which owns the expanded row.
 81     * @param {Ext.data.Model} record The record providing the data.
 82     * @param {HTMLElement} expandRow The &amp;lt;tr&gt; element containing the expanded data.
 83     */
 84<span id='Ext-ux-RowExpander-event-collapsebody'>    /**
 85</span>     * @event collapsebody
 86     * &lt;b&lt;Fired through the grid's View.&lt;/b&gt;
 87     * @param {HTMLElement} rowNode The &amp;lt;tr&gt; element which owns the expanded row.
 88     * @param {Ext.data.Model} record The record providing the data.
 89     * @param {HTMLElement} expandRow The &amp;lt;tr&gt; element containing the expanded data.
 90     */
 91
 92    constructor: function() {
 93        this.callParent(arguments);
 94        var grid = this.getCmp();
 95        this.recordsExpanded = {};
 96        // &lt;debug&gt;
 97        if (!this.rowBodyTpl) {
 98            Ext.Error.raise(&quot;The 'rowBodyTpl' config is required and is not defined.&quot;);
 99        }
100        // &lt;/debug&gt;
101        // TODO: if XTemplate/Template receives a template as an arg, should
102        // just return it back!
103        var rowBodyTpl = Ext.create('Ext.XTemplate', this.rowBodyTpl),
104            features = [{
105                ftype: 'rowbody',
106                columnId: this.getHeaderId(),
107                recordsExpanded: this.recordsExpanded,
108                rowBodyHiddenCls: this.rowBodyHiddenCls,
109                rowCollapsedCls: this.rowCollapsedCls,
110                getAdditionalData: this.getRowBodyFeatureData,
111                getRowBodyContents: function(data) {
112                    return rowBodyTpl.applyTemplate(data);
113                }
114            },{
115                ftype: 'rowwrap'
116            }];
117
118        if (grid.features) {
119            grid.features = features.concat(grid.features);
120        } else {
121            grid.features = features;
122        }
123
124        // NOTE: features have to be added before init (before Table.initComponent)
125    },
126
127    init: function(grid) {
128        this.callParent(arguments);
129
130        // Columns have to be added in init (after columns has been used to create the
131        // headerCt). Otherwise, shared column configs get corrupted, e.g., if put in the
132        // prototype.
133        grid.headerCt.insert(0, this.getHeaderConfig());
134        grid.on('render', this.bindView, this, {single: true});
135    },
136
137    getHeaderId: function() {
138        if (!this.headerId) {
139            this.headerId = Ext.id();
140        }
141        return this.headerId;
142    },
143
144    getRowBodyFeatureData: function(data, idx, record, orig) {
145        var o = Ext.grid.feature.RowBody.prototype.getAdditionalData.apply(this, arguments),
146            id = this.columnId;
147        o.rowBodyColspan = o.rowBodyColspan - 1;
148        o.rowBody = this.getRowBodyContents(data);
149        o.rowCls = this.recordsExpanded[record.internalId] ? '' : this.rowCollapsedCls;
150        o.rowBodyCls = this.recordsExpanded[record.internalId] ? '' : this.rowBodyHiddenCls;
151        o[id + '-tdAttr'] = ' valign=&quot;top&quot; rowspan=&quot;2&quot; ';
152        if (orig[id+'-tdAttr']) {
153            o[id+'-tdAttr'] += orig[id+'-tdAttr'];
154        }
155        return o;
156    },
157
158    bindView: function() {
159        var view = this.getCmp().getView(),
160            viewEl;
161
162        if (!view.rendered) {
163            view.on('render', this.bindView, this, {single: true});
164        } else {
165            viewEl = view.getEl();
166            if (this.expandOnEnter) {
167                this.keyNav = Ext.create('Ext.KeyNav', viewEl, {
168                    'enter' : this.onEnter,
169                    scope: this
170                });
171            }
172            if (this.expandOnDblClick) {
173                view.on('itemdblclick', this.onDblClick, this);
174            }
175            this.view = view;
176        }
177    },
178
179    onEnter: function(e) {
180        var view = this.view,
181            ds   = view.store,
182            sm   = view.getSelectionModel(),
183            sels = sm.getSelection(),
184            ln   = sels.length,
185            i = 0,
186            rowIdx;
187
188        for (; i &lt; ln; i++) {
189            rowIdx = ds.indexOf(sels[i]);
190            this.toggleRow(rowIdx);
191        }
192    },
193
194    toggleRow: function(rowIdx) {
195        var rowNode = this.view.getNode(rowIdx),
196            row = Ext.get(rowNode),
197            nextBd = Ext.get(row).down(this.rowBodyTrSelector),
198            record = this.view.getRecord(rowNode),
199            grid = this.getCmp();
200
201        if (row.hasCls(this.rowCollapsedCls)) {
202            row.removeCls(this.rowCollapsedCls);
203            nextBd.removeCls(this.rowBodyHiddenCls);
204            this.recordsExpanded[record.internalId] = true;
205            this.view.fireEvent('expandbody', rowNode, record, nextBd.dom);
206        } else {
207            row.addCls(this.rowCollapsedCls);
208            nextBd.addCls(this.rowBodyHiddenCls);
209            this.recordsExpanded[record.internalId] = false;
210            this.view.fireEvent('collapsebody', rowNode, record, nextBd.dom);
211        }
212    },
213
214    onDblClick: function(view, cell, rowIdx, cellIndex, e) {
215
216        this.toggleRow(rowIdx);
217    },
218
219    getHeaderConfig: function() {
220        var me                = this,
221            toggleRow         = Ext.Function.bind(me.toggleRow, me),
222            selectRowOnExpand = me.selectRowOnExpand;
223
224        return {
225            id: this.getHeaderId(),
226            width: 24,
227            sortable: false,
228            resizable: false,
229            draggable: false,
230            hideable: false,
231            menuDisabled: true,
232            cls: Ext.baseCSSPrefix + 'grid-header-special',
233            renderer: function(value, metadata) {
234                metadata.tdCls = Ext.baseCSSPrefix + 'grid-cell-special';
235
236                return '&lt;div class=&quot;' + Ext.baseCSSPrefix + 'grid-row-expander&quot;&gt;&amp;#160;&lt;/div&gt;';
237            },
238            processEvent: function(type, view, cell, recordIndex, cellIndex, e) {
239                if (type == &quot;mousedown&quot; &amp;&amp; e.getTarget('.x-grid-row-expander')) {
240                    var row = e.getTarget('.x-grid-row');
241                    toggleRow(row);
242                    return selectRowOnExpand;
243                }
244            }
245        };
246    }
247});
248</pre>
249</body>
250</html>