PDA

View Full Version : Upload metadata into an ArrayReader



McCornic
23 Jun 2009, 7:14 AM
EXTJS 3.0RC2

It will be nice to have the possibility to change the arrayReader metadata on demand.

For that i have to add a new function to the ArrayReader class:


this.gridDSReader = new Ext.data.ArrayReader();

// Creates a reader metadata update function
this.gridDSReader.updateMetadata = function(meta){
delete this.ef;
this.meta = meta;
this.recordType = Ext.data.Record.create(meta.fields);
this.onMetaChange(meta, this.recordType, {metaData:meta});
}

var grid_ds = new Ext.data.Store({
// store configs
autoDestroy: true,
url: base_url + 'query/ajaxgetgridrows',
// reader configs
reader:this.gridDSReader
});

I have to do this because i use two ajax request to load my grid panel.
The first one 'getGridColums', return a set of columns descriptions.
The columns are not the same each time because the grid is full in function of a form.

Exemple of a getGridColumns ajax request return :


{success:true,"columns":[{name:"PLOT_FORM__COUNTRY_CODE",data:"COUNTRY_CODE",format:"PLOT_FORM",label:"Country",inputType:"MULTIPLE",unit:"COUNTRY_CODE",type:"CODE",definition:"The code of the country"},{name:"PLOT_FORM__PLOT_CODE",data:"PLOT_CODE",format:"PLOT_FORM",label:"Plot Code",inputType:"TEXT",unit:"PLOT_CODE",type:"STRING",definition:"The identifier of the plot for the country"}]}


With that information i can build my new columnModel for my grid and a new metadata object for my reader like that :


/**
* Submit the request and get the description of the result columns
*/
submitRequest : function(){
this.centerPanel.activate(this.gridPanel);
//Bdn.util.grid.clearGrid(this.gridPanel);
this.formsPanel.findParentByType('form').getForm().submit({
url: base_url + 'query/ajaxgetgridcolumns',
success : function(form, action)
{
// Creation of the column model and the reader metadata fields
var columns = action.result.columns;
var newCM = new Array();
var newRF = new Array();
var columnConf;
var readerFieldsConf;
for(var i=0; i<columns.length;i++){
columnConf = {
header:columns[i].label,
sortable:true,
dataIndex:columns[i].name,
width:100
};
readerFieldsConf = {
name: columns[i].name
};
switch(columns[i].type){
case 'STRING':
columnConf.xtype='gridcolumn';
readerFieldsConf.type='string';
break;
case 'INT':
readerFieldsConf.type='int';
case 'NUMERIC':
case 'RANGE':
columnConf.xtype='numbercolumn';
readerFieldsConf.type='float';
break;
case 'DATE':
columnConf.xtype='datecolumn';
columnConf.format = 'm/d/Y';
readerFieldsConf.type='date';
readerFieldsConf.dateFormat='d-m-Y H:i:s';
break;
default:
columnConf.xtype='gridcolumn';
readerFieldsConf.type='auto';
break;
}
newCM.push(columnConf);
newRF.push(readerFieldsConf);
}

// Updates of the store reader metadata
this.gridDSReader.updateMetadata({
root: 'rows',
fields: newRF,
totalProperty:'total'
});

// Updates of the column model
//this.gridPanel.reconfigure(this.gridPanel.getStore(),new Ext.grid.ColumnModel(newCM));
this.gridPanel.getColumnModel().setConfig(newCM);
this.gridPanel.getView().updateAllColumnWidths();//Bug Ext 3.0

// Updates the rows
this.gridPanel.getStore().load({
params:{
start: 0,
limit: Genapp.grid.pagesize
},
callback : function(){//asynchrone !!
this.gridPanel.getView().refresh(true);//update the grid
},
scope:this
});
},
scope:this
});
}

The second request 'getGridRows' return the information about the grid rows like that:


{success:true,total:548,rows:[["France","1512"],["France","1516"],["France","1546"],["France","1548"],["France","1550"],["France","1554"],["France","1580"],["France","1581"],["France","1582"],["France","1583"],["France","1587"],["France","1592"],["France","1618"],["France","1623"],["France","1630"],["France","1632"],["France","1656"],["France","1665"],["France","1668"],["France","1670"],["France","1708"],["France","1711"],["France","1751"],["France","1636"],["France","1655"]]}

I know it's possible to update the metadata adding into the getGridRows ajax request
response a metadata object if you are using a jsonReader.
But for me the json return is too verbose when you have a lot of data.
I choose to use an arrayReader because you can tranfert only the data
without the column name and the metadata.

So what i propose is simply to add a function call updateMetadata into the jsonReader
so into the arrayReader because the arrayReader extend the jsonReader.


// Creates a reader metadata update function
this.gridDSReader.updateMetadata = function(meta){
delete this.ef;
this.meta = meta;
this.recordType = Ext.data.Record.create(meta.fields);
this.onMetaChange(meta, this.recordType, {metaData:meta});
}

You can find already this part of script into the readRecords function of the jsonReader:


readRecords : function(o){
/**
* After any data loads, the raw JSON data is available for further custom processing. If no data is
* loaded or there is a load exception this property will be undefined.
* @type Object
*/
this.jsonData = o;
if(o.metaData){
delete this.ef;
this.meta = o.metaData;
this.recordType = Ext.data.Record.create(o.metaData.fields);
this.onMetaChange(this.meta, this.recordType, o);
}
...