4 * Copyright(c) 2006-2007, Ext JS, LLC.
6 * Originally Released Under LGPL - original licence link has changed is not relivant.
9 * <script type="text/javascript">
13 * @class Roo.grid.Grid
14 * @extends Roo.util.Observable
15 * This class represents the primary interface of a component based grid control.
16 * <br><br>Usage:<pre><code>
17 var grid = new Roo.grid.Grid("my-container-id", {
20 selModel: mySelectionModel,
21 autoSizeColumns: true,
22 monitorWindowResize: false,
28 * <b>Common Problems:</b><br/>
29 * - Grid does not resize properly when going smaller: Setting overflow hidden on the container
30 * element will correct this<br/>
31 * - If you get el.style[camel]= NaNpx or -2px or something related, be certain you have given your container element
32 * dimensions. The grid adapts to your container's size, if your container has no size defined then the results
33 * are unpredictable.<br/>
34 * - Do not render the grid into an element with display:none. Try using visibility:hidden. Otherwise there is no way for the
35 * grid to calculate dimensions/offsets.<br/>
37 * @param {String/HTMLElement/Roo.Element} container The element into which this grid will be rendered -
38 * The container MUST have some type of size defined for the grid to fill. The container will be
39 * automatically set to position relative if it isn't already.
40 * @param {Object} config A config object that sets properties on this grid.
42 Roo.grid.Grid = function(container, config){
43 // initialize the container
44 this.container = Roo.get(container);
45 this.container.update("");
46 this.container.setStyle("overflow", "hidden");
47 this.container.addClass('x-grid-container');
49 this.id = this.container.id;
51 Roo.apply(this, config);
52 // check and correct shorthanded configs
54 this.dataSource = this.ds;
58 this.colModel = this.cm;
62 this.selModel = this.sm;
67 this.selModel = Roo.factory(this.selModel, Roo.grid);
68 this.sm = this.selModel;
70 if (typeof(this.colModel.config) == 'undefined') {
71 this.colModel = new Roo.grid.ColumnModel(this.colModel);
72 this.cm = this.colModel;
74 if (this.dataSource) {
75 this.dataSource= Roo.factory(this.dataSource, Roo.data);
76 this.ds = this.dataSource;
83 this.container.setWidth(this.width);
87 this.container.setHeight(this.height);
94 * The raw click event for the entire grid.
95 * @param {Roo.EventObject} e
100 * The raw dblclick event for the entire grid.
101 * @param {Roo.EventObject} e
106 * The raw contextmenu event for the entire grid.
107 * @param {Roo.EventObject} e
109 "contextmenu" : true,
112 * The raw mousedown event for the entire grid.
113 * @param {Roo.EventObject} e
118 * The raw mouseup event for the entire grid.
119 * @param {Roo.EventObject} e
124 * The raw mouseover event for the entire grid.
125 * @param {Roo.EventObject} e
130 * The raw mouseout event for the entire grid.
131 * @param {Roo.EventObject} e
136 * The raw keypress event for the entire grid.
137 * @param {Roo.EventObject} e
142 * The raw keydown event for the entire grid.
143 * @param {Roo.EventObject} e
151 * Fires when a cell is clicked
153 * @param {Number} rowIndex
154 * @param {Number} columnIndex
155 * @param {Roo.EventObject} e
159 * @event celldblclick
160 * Fires when a cell is double clicked
162 * @param {Number} rowIndex
163 * @param {Number} columnIndex
164 * @param {Roo.EventObject} e
166 "celldblclick" : true,
169 * Fires when a row is clicked
171 * @param {Number} rowIndex
172 * @param {Roo.EventObject} e
177 * Fires when a row is double clicked
179 * @param {Number} rowIndex
180 * @param {Roo.EventObject} e
182 "rowdblclick" : true,
185 * Fires when a header is clicked
187 * @param {Number} columnIndex
188 * @param {Roo.EventObject} e
190 "headerclick" : true,
192 * @event headerdblclick
193 * Fires when a header cell is double clicked
195 * @param {Number} columnIndex
196 * @param {Roo.EventObject} e
198 "headerdblclick" : true,
200 * @event rowcontextmenu
201 * Fires when a row is right clicked
203 * @param {Number} rowIndex
204 * @param {Roo.EventObject} e
206 "rowcontextmenu" : true,
208 * @event cellcontextmenu
209 * Fires when a cell is right clicked
211 * @param {Number} rowIndex
212 * @param {Number} cellIndex
213 * @param {Roo.EventObject} e
215 "cellcontextmenu" : true,
217 * @event headercontextmenu
218 * Fires when a header is right clicked
220 * @param {Number} columnIndex
221 * @param {Roo.EventObject} e
223 "headercontextmenu" : true,
226 * Fires when the body element is scrolled
227 * @param {Number} scrollLeft
228 * @param {Number} scrollTop
232 * @event columnresize
233 * Fires when the user resizes a column
234 * @param {Number} columnIndex
235 * @param {Number} newSize
237 "columnresize" : true,
240 * Fires when the user moves a column
241 * @param {Number} oldIndex
242 * @param {Number} newIndex
247 * Fires when row(s) start being dragged
249 * @param {Roo.GridDD} dd The drag drop object
250 * @param {event} e The raw browser event
255 * Fires when a drag operation is complete
257 * @param {Roo.GridDD} dd The drag drop object
258 * @param {event} e The raw browser event
263 * Fires when dragged row(s) are dropped on a valid DD target
265 * @param {Roo.GridDD} dd The drag drop object
266 * @param {String} targetId The target drag drop object
267 * @param {event} e The raw browser event
272 * Fires while row(s) are being dragged. "targetId" is the id of the Yahoo.util.DD object the selected rows are being dragged over.
274 * @param {Roo.GridDD} dd The drag drop object
275 * @param {String} targetId The target drag drop object
276 * @param {event} e The raw browser event
281 * Fires when the dragged row(s) first cross another DD target while being dragged
283 * @param {Roo.GridDD} dd The drag drop object
284 * @param {String} targetId The target drag drop object
285 * @param {event} e The raw browser event
290 * Fires when the dragged row(s) leave another DD target while being dragged
292 * @param {Roo.GridDD} dd The drag drop object
293 * @param {String} targetId The target drag drop object
294 * @param {event} e The raw browser event
299 * Fires when the grid is rendered
305 Roo.grid.Grid.superclass.constructor.call(this);
307 Roo.extend(Roo.grid.Grid, Roo.util.Observable, {
309 * @cfg {Number} minColumnWidth The minimum width a column can be resized to. Default is 25.
314 * @cfg {Boolean} autoSizeColumns True to automatically resize the columns to fit their content
315 * <b>on initial render.</b> It is more efficient to explicitly size the columns
316 * through the ColumnModel's {@link Roo.grid.ColumnModel#width} config option. Default is false.
318 autoSizeColumns : false,
321 * @cfg {Boolean} autoSizeHeaders True to measure headers with column data when auto sizing columns. Default is true.
323 autoSizeHeaders : true,
326 * @cfg {Boolean} monitorWindowResize True to autoSize the grid when the window resizes. Default is true.
328 monitorWindowResize : true,
331 * @cfg {Boolean} maxRowsToMeasure If autoSizeColumns is on, maxRowsToMeasure can be used to limit the number of
332 * rows measured to get a columns size. Default is 0 (all rows).
334 maxRowsToMeasure : 0,
337 * @cfg {Boolean} trackMouseOver True to highlight rows when the mouse is over. Default is true.
339 trackMouseOver : true,
342 * @cfg {Boolean} enableDragDrop True to enable drag and drop of rows. Default is false.
344 enableDragDrop : false,
347 * @cfg {Boolean} enableColumnMove True to enable drag and drop reorder of columns. Default is true.
349 enableColumnMove : true,
352 * @cfg {Boolean} enableColumnHide True to enable hiding of columns with the header context menu. Default is true.
354 enableColumnHide : true,
357 * @cfg {Boolean} enableRowHeightSync True to manually sync row heights across locked and not locked rows. Default is false.
359 enableRowHeightSync : false,
362 * @cfg {Boolean} stripeRows True to stripe the rows. Default is true.
367 * @cfg {Boolean} autoHeight True to fit the height of the grid container to the height of the data. Default is false.
372 * @cfg {String} autoExpandColumn The id (or dataIndex) of a column in this grid that should expand to fill unused space. This id can not be 0. Default is false.
374 autoExpandColumn : false,
377 * @cfg {Number} autoExpandMin The minimum width the autoExpandColumn can have (if enabled).
383 * @cfg {Number} autoExpandMax The maximum width the autoExpandColumn can have (if enabled). Default is 1000.
385 autoExpandMax : 1000,
388 * @cfg {Object} view The {@link Roo.grid.GridView} used by the grid. This can be set before a call to render().
393 * @cfg {Object} loadMask An {@link Roo.LoadMask} config or true to mask the grid while loading. Default is false.
401 * @cfg {Boolean} autoWidth True to set the grid's width to the default total width of the grid's columns instead
402 * of a fixed width. Default is false.
405 * @cfg {Number} maxHeight Sets the maximum height of the grid - ignored if autoHeight is not on.
408 * Called once after all setup has been completed and the grid is ready to be rendered.
409 * @return {Roo.grid.Grid} this
412 var c = this.container;
413 // try to detect autoHeight/width mode
414 if((!c.dom.offsetHeight || c.dom.offsetHeight < 20) || c.getStyle("height") == "auto"){
415 this.autoHeight = true;
417 var view = this.getView();
420 c.on("click", this.onClick, this);
421 c.on("dblclick", this.onDblClick, this);
422 c.on("contextmenu", this.onContextMenu, this);
423 c.on("keydown", this.onKeyDown, this);
425 this.relayEvents(c, ["mousedown","mouseup","mouseover","mouseout","keypress"]);
427 this.getSelectionModel().init(this);
432 this.loadMask = new Roo.LoadMask(this.container,
433 Roo.apply({store:this.dataSource}, this.loadMask));
437 if (this.toolbar && this.toolbar.xtype) {
438 this.toolbar.container = this.getView().getHeaderPanel(true);
439 this.toolbar = new Ext.Toolbar(this.toolbar);
441 if (this.footer && this.footer.xtype) {
442 this.footer.dataSource = this.getDataSource();
443 this.footer.container = this.getView().getFooterPanel(true);
444 this.footer = Roo.factory(this.footer, Roo);
446 this.rendered = true;
447 this.fireEvent('render', this);
452 * Reconfigures the grid to use a different Store and Column Model.
453 * The View will be bound to the new objects and refreshed.
454 * @param {Roo.data.Store} dataSource The new {@link Roo.data.Store} object
455 * @param {Roo.grid.ColumnModel} The new {@link Roo.grid.ColumnModel} object
457 reconfigure : function(dataSource, colModel){
459 this.loadMask.destroy();
460 this.loadMask = new Roo.LoadMask(this.container,
461 Roo.apply({store:dataSource}, this.loadMask));
463 this.view.bind(dataSource, colModel);
464 this.dataSource = dataSource;
465 this.colModel = colModel;
466 this.view.refresh(true);
470 onKeyDown : function(e){
471 this.fireEvent("keydown", e);
476 * @param {Boolean} removeEl True to remove the element
478 destroy : function(removeEl, keepListeners){
480 this.loadMask.destroy();
482 var c = this.container;
483 c.removeAllListeners();
485 this.colModel.purgeListeners();
487 this.purgeListeners();
490 if(removeEl === true){
496 processEvent : function(name, e){
497 this.fireEvent(name, e);
498 var t = e.getTarget();
500 var header = v.findHeaderIndex(t);
501 if(header !== false){
502 this.fireEvent("header" + name, this, header, e);
504 var row = v.findRowIndex(t);
505 var cell = v.findCellIndex(t);
507 this.fireEvent("row" + name, this, row, e);
509 this.fireEvent("cell" + name, this, row, cell, e);
516 onClick : function(e){
517 this.processEvent("click", e);
521 onContextMenu : function(e, t){
522 this.processEvent("contextmenu", e);
526 onDblClick : function(e){
527 this.processEvent("dblclick", e);
531 walkCells : function(row, col, step, fn, scope){
532 var cm = this.colModel, clen = cm.getColumnCount();
533 var ds = this.dataSource, rlen = ds.getCount(), first = true;
545 if(fn.call(scope || this, row, col, cm) === true){
563 if(fn.call(scope || this, row, col, cm) === true){
575 getSelections : function(){
576 return this.selModel.getSelections();
580 * Causes the grid to manually recalculate its dimensions. Generally this is done automatically,
581 * but if manual update is required this method will initiate it.
583 autoSize : function(){
586 if(this.view.adjustForScroll){
587 this.view.adjustForScroll();
593 * Returns the grid's underlying element.
594 * @return {Element} The element
596 getGridEl : function(){
597 return this.container;
600 // private for compatibility, overridden by editor grid
601 stopEditing : function(){},
604 * Returns the grid's SelectionModel.
605 * @return {SelectionModel}
607 getSelectionModel : function(){
609 this.selModel = new Roo.grid.RowSelectionModel();
611 return this.selModel;
615 * Returns the grid's DataSource.
616 * @return {DataSource}
618 getDataSource : function(){
619 return this.dataSource;
623 * Returns the grid's ColumnModel.
624 * @return {ColumnModel}
626 getColumnModel : function(){
627 return this.colModel;
631 * Returns the grid's GridView object.
634 getView : function(){
636 this.view = new Roo.grid.GridView(this.viewConfig);
641 * Called to get grid's drag proxy text, by default returns this.ddText.
644 getDragDropText : function(){
645 var count = this.selModel.getCount();
646 return String.format(this.ddText, count, count == 1 ? '' : 's');
650 * Configures the text is the drag proxy (defaults to "%0 selected row(s)").
651 * %0 is replaced with the number of selected rows.
654 Roo.grid.Grid.prototype.ddText = "{0} selected row{1}";