-
23 Mar 2007 7:23 AM #1
Dynamic grid columns?
Dynamic grid columns?
Hi, two quick questions:
1) Is it possible to set up a grid so that its columns are based on the contents of the records you pass it? In other words, if the records are {X:1,Y:2} the columns will be X and Y.
2) Is it possible to configure the "start" and "limit" parameters to change them to "startIndex" and "endIndex" (or does limit = "length"?)
-
23 Mar 2007 8:04 AM #2
I started using yui-ext recently and I am facing the very same problems.
dynamic grid and paging params names (they are clashing w/ current code I have in place).
and one more question:
How can I force "auto-size" for cell content w/o specifying its 'width'?
" 123 " vs "123"
Thanks!
-
23 Mar 2007 8:48 AM #3
Re: Dynamic grid columns?
Re: Dynamic grid columns?
I don't think so, and for many reasons. One reason is that the data model provides a set of data that you can then provide a view of. The column model is that view. The column model says "With these 12 data elements returned per row, which ones do I want to display in my viewport and which ones are there for support purposes?"
Originally Posted by SteveEisner
There's nothing preventing you from flattening the view to match the data source though. You could just write a mini adapter that goes out and discovers your column model and dynamically creates it for your grid.
-
23 Mar 2007 8:52 AM #4
Well, if you fist find out what the records are going to contain, you can create an appropriate ColumnModel programatically by simply assembling a column config Array.
My wrapper of the Grid sends an encoded query to the server, receives back info about the columns, builds the ColumnModel and Record definition on the fly from this recieved info, creates the Grid and loads it.
I only have one Grid class which will handle all my possible queries.Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
23 Mar 2007 10:13 AM #5
t puede dar una pista
t puede dar una pista
esta grilla se construye onfly vacia y se re-construyen tambien onfly con datos del # de columnas despues de una consulta del numero de elementos
con algunos cambios porque esta funcion yo la utilizo para crear 2 grillas iguales simultaneamente, espero t ayude en algo.Code:grid_editor_modelo_medidas = function(){ var myData; var dataModel; var colModel; var sm; var grid; var contenedor = 'editor-grid-modelo-medidas-confeccion'; var responseText; return { init : function(){ responseText = ''; myData = []; dataModel = new YAHOO.ext.grid.DefaultDataModel(myData); colModel = new YAHOO.ext.grid.DefaultColumnModel([ {header: "id_caracteristica", width: 30, hidden: true}, {header: "id_stcaracteristica", width: 30, hidden: true}, {header: "Subtipo Caracteristica", width: 200}, {header: "Tallas de la Familia", width: 464} ]); //sm = new YAHOO.ext.grid.EditorAndSelectionModel(); grid = new YAHOO.ext.grid.Grid(contenedor,dataModel,colModel/*,sm*/); grid.render(); }, reRenderGrid : function(id_fam_talla){ //tstart = new Date().getTime(); var cb = {success: function(o){ responseText = o.responseText; var vec_tallas = responseText.split(','); var myColumns = new Array(); myColumns[0] = new Objeto('id_caracteristica',30,true); myColumns[1] = new Objeto('id_stcaracteristica',30,true); myColumns[2] = new Objeto('Subtipo Caracteristica',200,false); myColumns[3] = new Objeto('Margen (+/-)',70,false,'NumberEditor'); var c=4; for(var i=0; i<vec_tallas.length; i++){ myColumns[c] = new bjeto(vec_tallas[i],30,false,'NumberEditor'); c++; } grid.destroy(); colModel = new YAHOO.ext.grid.DefaultColumnModel(myColumns); dataModel = new YAHOO.ext.grid.DefaultDataModel(myData); sm = new YAHOO.ext.grid.EditorAndSelectionModel(); grid_editor_modelo_medidas.reFullgrid(); //convierte algunos datos de la grilla a 0 grid = new YAHOO.ext.grid.Grid(contenedor,dataModel,colModel,sm); grid.render(); //var tend = new Date().getTime(); //alert('Rendered in: ' + ((tend-tstart)/1000) + ' seconds'); }, failure: function(o){ alert('Fail...'+o.responseText); } }; YAHOO.util.Connect.asyncRequest('POST','AjaxGetColumns.php',cb,'id_familia_talla='+id_fam_talla); }, addrow : function(valor2,valor3,valor4){ grid.stopEditing(); var row = new Array(); row[0] = valor2; row[1] = valor4; row[2] = valor3; if(responseText!=''){ row[3] = '0'; var vec_col = responseText.split(','); var c=4; for(var i=0; i<vec_col.length; i++){ row[c] = '0'; c++; } }else{ row[3] = '<span style="color:red;">- Debe escoger para crear las columnas y poder adicionar datos a la grilla -</span>'; } dataModel.addRow(row); }, addData : function(id_fam_talla,cadData){ //tstart = new Date().getTime(); grid.stopEditing(); myData = []; if(cadData){ var vec_medidas_mod = cadData.split('#'); for(var i=0; i<vec_medidas_mod.length; i++){ var vec_data_row = vec_medidas_mod[i].split(','); var row1 = new Array(); var c1=0; for(var j=0; j<vec_data_row.length; j++){ row1[c1] = vec_data_row[j]; c1++; } myData[i] = row1; } } var cb = {success: function(o){ responseText = o.responseText; var vec_tallas = responseText.split(','); var myColumns = new Array(); myColumns[0] = new Objeto('id_caracteristica',30,true); myColumns[1] = new Objeto('id_stcaracteristica',30,true); myColumns[2] = new Objeto('Subtipo Caracteristica',200,false); myColumns[3] = new Objeto('Margen (+/-)',70,false,'NumberEditor'); var c=4; for(var i=0; i<vec_tallas.length; i++){ myColumns[c] = new Objeto(vec_tallas[i],30,false,'NumberEditor'); c++; } grid.destroy(false,true); colModel = new YAHOO.ext.grid.DefaultColumnModel(myColumns); dataModel = new YAHOO.ext.grid.DefaultDataModel(myData); sm = new YAHOO.ext.grid.EditorAndSelectionModel(); grid = new YAHOO.ext.grid.Grid(contenedor,dataModel,colModel,sm); grid.render(); //var tend = new Date().getTime(); //alert('Rendered in: ' + ((tend-tstart)/1000) + ' seconds'); }, failure: function(o){ alert('Fail...'+o.responseText); } }; YAHOO.util.Connect.asyncRequest('POST','domain/AjaxGetColumns.php',cb,'id_familia_talla='+id_fam_talla); }, reFullgrid : function(){ grid.stopEditing(); var rows = dataModel.getRowCount(); for(var i=0; i<rows; i++){ var row = dataModel.getRow(i); row[3] = '0'; var vec_col = responseText.split(','); var c=4; for(var j=0; j<vec_col.length; j++){ row[c] = '0'; c++; } } }, savedm : function(){ var rows = dataModel.getRowCount(); var col = colModel.getColumnCount(); var vec_tallas = responseText.split(','); var medidas_modelo = ''; for(var i=0; i<rows; i++){ var row1 = dataModel.getRow(i); var value = ''; value = row1[0]+','+row1[1]+','+row1[2]+','+row1[3]+','; for(var j=4; j<col; j++){ value = value+row1[j]; if(j+1<col) value=value+','; } if(i+1<rows) value = value+'~'; medidas_modelo = medidas_modelo+value; } return medidas_modelo; } }; }(); function Objeto(header, width, hidden, editor) { this.header = header; this.width = width; this.hidden = hidden; if(editor){ if(editor=='NumberEditor'){ this.editor = new YAHOO.ext.grid.NumberEditor({allowBlank: false, blankText: 'Este campo no puede ser vacĂo!', allowNegative: false, allowDecimals: true}); } } } YAHOO.ext.EventManager.onDocumentReady(grid_editor_modelo_medidas.init, grid_editor_modelo_medidas, true);
recomendaciones y sugerencias
ext 0.33
tnks
-
23 Mar 2007 10:46 AM #6
I was looking through the code and it seems like this might also be done generically by:
1) Creating a "DynamicColumnModel" that, after receiving a record, uses that record to respond to column queries [this would be hard to do for rich field types but could pretty easily build an all-string table]
2) Creating a "DynamicRecord" that, in combination with a Reader, is able to store all the columns of the returned JSON.
After that both the grid and the reader would have to be modified slightly to send the recordset to the columnmodel, but other than the difficult work of building those two classes, I think it wouldn't take much modification of the base code. I'll see if I can take this on.
Other than that, dfenwick/Animal I agree your method for loading is a good one as long as you can make a schema query (unfortunately, we don't have a way to do that, because it's calling methods that return arbitrary data)
-
23 Mar 2007 6:22 PM #7
Here's what I came up with:
Dynamic Json Reader: this will read whatever data comes back from the JSON call. It doesn't take a record definition because it builds it on the fly. Unfortunately it only has any record information *after* the JSON call has completed, so you can't simply pass it into a Grid, etc. because it won't be initialized at that time.
DynamicColumnModel: this takes a Store as a parameter, and from that it will build a default ColumnModel where all the fields are included and have width: 300.Code:Ext.data.DynamicJsonReader = function(config){ Ext.data.DynamicJsonReader.superclass.constructor.call(this, config, []); }; Ext.extend(Ext.data.DynamicJsonReader, Ext.data.JsonReader, { getRecordType : function(data) { var i = 0, arr = []; for (var name in data[0]) { arr[i++] = name; } // is there a built-in to do this? this.recordType = Ext.data.Record.create(arr); return this.recordType; }, readRecords : function(o){ // this is just the same as base class, with call to getRecordType injected this.jsonData = o; var s = this.meta; var sid = s.id; var totalRecords = 0; if(s.totalProperty){ var v = parseInt(eval("o." + s.totalProperty), 10); if(!isNaN(v)){ totalRecords = v; } } var root = s.root ? eval("o." + s.root) : o; var recordType = this.getRecordType(root); var fields = recordType.prototype.fields; var records = []; for(var i = 0; i < root.length; i++){ var n = root[i]; var values = {}; var id = (n[sid] !== undefined && n[sid] !== "" ? n[sid] : null); for(var j = 0, jlen = fields.length; j < jlen; j++){ var f = fields.items[j]; var map = f.mapping || f.name; var v = n[map] !== undefined ? n[map] : f.defaultValue; v = f.convert(v); values[f.name] = v; } var record = new recordType(values, id); record.json = n; records[records.length] = record; } return { records : records, totalRecords : totalRecords || records.length }; } });
Code:Ext.grid.DynamicColumnModel = function(store){ var cols = []; var recordType = store.recordType; var fields = recordType.prototype.fields; for (var i = 0; i < fields.keys.length; i++) { var fieldName = fields.keys[i]; var field = recordType.getField(fieldName); cols[i] = {header: field.name, dataIndex: field.name, width:300}; } Ext.grid.DynamicColumnModel.superclass.constructor.call(this, cols); }; Ext.extend(Ext.grid.DynamicColumnModel, Ext.grid.ColumnModel, {});
Here's how I use it -
I haven't really put it through its paces yet but it seems to work for whatever JSON calls I try. If this were more generic I'd want to add some things like:Code:function showGrid(container, url) { // create the Data Store var ds = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({url: url}), reader: new Ext.data.DynamicJsonReader({root: '...my root, yours will be different...'}), remoteSort: true }); ds.on('load', function() { // Reset the Store's recordType ds.recordType = ds.reader.recordType; ds.fields = ds.recordType.prototype.fields; // Create the grid var grid = new Ext.grid.Grid(container, { ds: ds, cm: new Ext.grid.DynamicColumnModel(ds), selModel: new Ext.grid.RowSelectionModel({singleSelect:true}), enableColLock:true }); // render it grid.render(); }); ds.load(); }
* Some way to provide column widths and types for known columns - merge with the unknowns. Maybe a callback function of some sort.
* A better way to declare this type of grid that has to wait until the data has been fetched before rendering.
* A DynamicXmlReader to match the JSON reader
* etc.
Note if Jack reads this: the DynamicJsonReader code could be even smaller if you adopt the change I made to the readRecords() method...
Steve
-
28 Mar 2007 12:02 PM #8
-
28 Mar 2007 6:31 PM #9
dreaming for dynamic grid...
dreaming for dynamic grid...
plz... Steve,
if you can provide some sample or atleast js and html code...it will help a lot for new bees....dreaming for dynamic grid...Mohammed, G
http://www.abdulsalam.info
-
15 Aug 2007 9:05 AM #10
SteveEisner, I love you!
Well, maybe not love, but an extreme amount of respect and appreciation for your DynamicJsonReader extension. It's solved so many of my problems! I've been trying to find a way to get a handle on a number of dynamic paragraph elements that are returned as part of the response to retrieve a news article. Here's a snippet of the JSON:
JSON snippet
My problem was that the number of elements in the paragraph array is variable (as you might expect for a news article) and I couldn't find a way to setup a Record to handle this (I tried stuff with mapping: and convert:), but your DynamicJsonReader solves this problem perfectly.PHP Code:
"tailParagraphs": {
"paragraph": [
"The company also hopes its [...] organizations.",
"Oracle is a proponent of [...] SaaS.",
"Phillips foresees gradations [...] and SaaS.",
"\"We have been doing [...] said Phillips.",
"Conventionally, SaaS [...] multi tenant."
]
},
It even solved the other problem I had http://extjs.com/forum/showthread.php?p=54791#post54791. This concerns the problem the JsonReader has if the root isn't specified as an array when there is only one object, e.g., if there is only one news article. DynamicJsonReader handles this anomoly in the JSON I am having to work with.
So, thank you once again, SteveEisner for sharing your work. I only hope I'll be able to eventually give as much back to these forums one day.
Similar Threads
-
Max columns limitation in grid?
By jarrod in forum Ext 1.x: BugsReplies: 9Last Post: 26 Jun 2010, 4:52 AM -
Dynamic Columns for Grid
By kinky_lizzard in forum Ext 1.x: Help & DiscussionReplies: 7Last Post: 24 May 2010, 11:20 PM -
Grid - Double Header Columns
By FuryVII in forum Ext 2.x: Help & DiscussionReplies: 0Last Post: 23 Feb 2007, 7:21 AM -
Nested Grid Columns
By dlibby00 in forum Community DiscussionReplies: 4Last Post: 29 Jan 2007, 9:53 AM


Reply With Quote