PDA

View Full Version : [DONE]JsonReader to allow nested mapping



Animal
15 Mar 2007, 12:52 AM
The JsonReader should be able to use dot notation in the "mapping" property of the ColumnModel to extract data from nested objects in the data object. This is analogous to the DomQuery syntax used in the mapping by the XmlReader.



Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
read : function(response){
var json = response.responseText;
var o = eval("("+json+")");
if(!o) {
throw {message: "JsonReader.read: Json object not found"};
}
return this.readRecords(o);
},

readRecords : function(o){
this.jsonData = o;
var s = this.meta;
var sid = s.id;
var recordType = this.recordType, fields = recordType.prototype.fields;

var totalRecords = 0;
if(s.totalProperty){
var v = parseInt(eval("o." + s.totalProperty), 10);
if(!isNaN(v)){
totalRecords = v;
}
}
var records = [];
var root = s.root ? eval("o." + s.root) : o;
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 = (typeof map == "number") ? n[map] : eval("n." + map); // <-- pull the data out from any nested level
if (v == undefined) v = f.defaultValue;
values[f.name] = f.convert(v);
}
var record = new recordType(values, id);
record.json = n;
records[records.length] = record;
}
return {
records : records,
totalRecords : totalRecords || records.length
};
}
});


Here is an example page including this code which demonstrates:



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>From Markup Grid Example</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<script type="text/javascript" src="../../yui-utilities.js"></script>
<script type="text/javascript" src="../../ext-yui-adapter.js"></script>
<script type="text/javascript" src="../../ext-all-debug.js"></script>
<link rel="stylesheet" type="text/css" href="grid-examples.css" />

<link rel="stylesheet" type="text/css" href="../examples.css" />
<script type="text/javascript">

Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
read : function(response){
var json = response.responseText;
var o = eval("("+json+")");
if(!o) {
throw {message: "JsonReader.read: Json object not found"};
}
return this.readRecords(o);
},

readRecords : function(o){
this.jsonData = o;
var s = this.meta;
var sid = s.id;
var recordType = this.recordType, fields = recordType.prototype.fields;

var totalRecords = 0;
if(s.totalProperty){
var v = parseInt(eval("o." + s.totalProperty), 10);
if(!isNaN(v)){
totalRecords = v;
}
}
var records = [];
var root = s.root ? eval("o." + s.root) : o;
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 = (typeof map == "number") ? n[map] : eval("n." + map); // <-- pull the data out from any nested level
if (v == undefined) v = f.defaultValue;
values[f.name] = f.convert(v);
}
var record = new recordType(values, id);
record.json = n;
records[records.length] = record;
}
return {
records : records,
totalRecords : totalRecords || records.length
};
}
});

function createGrid(data) {
var guests = Ext.data.Record.create([
{name: 'firstName', mapping: 'guestName.first'}, //<-- dot notation in mapping
{name: 'secondName', mapping: 'guestName.second'}, //<-- dot notation in mapping
{name: 'attendingReception', mapping: 'comingToReception'},
{name: 'attendingCeremony', mapping: 'comingToCeremony'}
]);

// create reader that reads into Topic records
var reader = new Ext.data.JsonReader({
root: 'guests',
}, guests);

// create the Data Store
var ds = new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(data),
reader: reader,
remoteSort: true
});
ds.setDefaultSort('guest', 'desc');

var cm = new Ext.grid.ColumnModel([
{
header:'First Name',
dataIndex:'firstName'
},
{
header:'Second Name',
dataIndex:'secondName'
},
{
header:'Attending Ceremony',
dataIndex:'attendingCeremony',
},
{
header:'Attending Reception',
dataIndex:'attendingReception',
}
]);

// create the editor grid
var grid = new Ext.grid.Grid('container', {
ds: ds,
cm: cm,
selModel: new Ext.grid.RowSelectionModel({singleSelect:true}),
enableColLock:true
});

// render it
ds.load();
grid.render();
}
Ext.onReady(function() {
createGrid({"guests":[
{"comingToReception":false,"guestName":{first:"Lily",second:"Tran"},"comingToCeremony":false},
{"comingToReception":false,"guestName":{first:"Alfred",second:"Wong"},"comingToCeremony":false}
]} );
});
</script>
</head>
<body>
<div id="container" style="height:200px;width:500px"></div>
</body>