Give me a error Ext.onRead is not a function, any1 helo me?



/*
* Ext - JS Library 1.0 Alpha 3 - Rev 1
* Copyright(c) 2006-2007, Jack Slocum.
*/

Ext.onReady(function(){

function formatBoolean(value){
return value ? 'Yes' : 'No';
};

function formatDate(value){
return value ? value.dateFormat('M d, Y') : '';
};
// shorthand alias
var fm = Ext.form, Ed = Ext.grid.GridEditor;

// the column model has information about grid columns
// dataIndex maps the column to the specific data field in
// the data store (created below)
var cm = new Ext.grid.ColumnModel([{
header: "Common Name",
dataIndex: 'common',
width: 160,
editor: new Ed(new fm.TextField({
allowBlank: false
}))
},{
header: "Light",
dataIndex: 'light',
width: 130,
editor: new Ed(new Ext.form.ComboBox({
typeAhead: true,
triggerAction: 'all',
transform:'light',
lazyRender:true
}))
},{
header: "Price",
dataIndex: 'price',
width: 70,
align: 'right',
renderer: 'usMoney',
editor: new Ed(new fm.NumberField({
allowBlank: false,
allowNegative: false,
maxValue: 10
}))
},{
header: "Available",
dataIndex: 'availDate',
width: 95,
renderer: formatDate,
editor: new Ed(new fm.DateField({
format: 'm/d/y',
minValue: '01/01/06',
disabledDays: [0, 6],
disabledDaysText: 'Plants are not available on the weekends'
}))
},{
header: "Indoor?",
dataIndex: 'indoor',
width: 55,
renderer: formatBoolean,
editor: new Ed(new fm.Checkbox())
}]);

// by default columns are sortable
cm.defaultSortable = true;

// this could be inline, but we want to define the Plant record
// type so we can add records dynamically
var Plant = Ext.data.Record.create([
// the "name" below matches the tag name to read, except "availDate"
// which is mapped to the tag "availability"
{name: 'common', type: 'string'},
{name: 'botanical', type: 'string'},
{name: 'light'},
{name: 'price', type: 'float'}, // automatic date conversions
{name: 'availDate', mapping: 'availability', type: 'date', dateFormat: 'm/d/Y'},
{name: 'indoor', type: 'bool'}
]);

// create the Data Store
var ds = new Ext.data.Store({
// load using HTTP
proxy: new Ext.data.HttpProxy({url: 'plants.xml'}),

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have a "plant" tag
record: 'plant'
}, Plant)
});

// create the editor grid
var grid = new Ext.grid.EditorGrid('editor-grid', {
ds: ds,
cm: cm,
selModel: new Ext.grid.RowSelectionModel(),
enableColLock:false
});

// make the grid resizable, do before render for better performance
var rz = new Ext.Resizable('editor-grid', {
wrap:true,
minWidth: 300,
minHeight:100,
pinned:true,
handles: 's,e,se',
transparent:true
});
rz.on('resize', grid.autoSize, grid);

// render it
grid.render();

var gridHead = grid.getView().getHeaderPanel();
gridHead.show();
var tb = new Ext.Toolbar(gridHead, [{
text: 'Add Plant',
handler : function(){
var p = new Plant({
common: 'New Plant 1',
light: 'Mostly Shade',
price: 0,
availDate: new Date(),
indoor: false
});
ds.insert(0, p);
grid.startEditing(0, 0);
}
}]);
tb.addSeparator();
tb.add({
text: 'Quicksearch:',
tooltip: 'Quickly search through the grid.'
});
var sftb = tb.addDom({
tag: 'input',
id: 'quicksearch',
type: 'text',
size: 30,
value: '',
style: 'background: #F0F0F9;'
});
var searchStore = new Ext.data.SimpleStore({
fields: ['query'],
data: []
});
var searchBox = new fm.ComboBox({
store: searchStore,
displayField: 'query',
typeAhead: false,
mode: 'local',
triggerAction: 'all',
hideTrigger: true
});
searchBox.applyTo('quicksearch');
tb.add({
text: 'X',
tooltip: 'Clear quicksearch',
handler: function() {
if (searchBox.getValue().length!=0) {
searchBox.setValue('');
ds.clearFilter();
}
}
});
var searchRec = Ext.data.Record.create([
{name: 'query', type: 'string'}
]);
var onFilteringBeforeQuery = function(e) {
//grid.getSelectionModel().clearSelections();
if (this.getValue().length==0) {
ds.clearFilter();
} else {
var value = this.getValue().replace(/^\s+|\s+$/g, "");
if (value=="")
return;
ds.filterBy(function(r) {
valueArr = value.split(/\ +/);
for (var i=0; i<valueArr.length; i++) {
re = new RegExp(Ext.escapeRe(valueArr[i]), "i");
if (re.test(r.data['common'])==false
&& re.test(r.data['light'])==false) {
return false;
};
}
return true;
});
}
};
var onQuickSearchBeforeQuery = function(e) {
if (this.getValue().length==0) {
} else {
var value = this.getValue().replace(/^\s+|\s+$/g, "");
if (value=="")
return;
searchStore.clearFilter();
var vr_insert = true;
searchStore.each(function(r) {
if (r.data['query'].indexOf(value)==0) {
// backspace
vr_insert = false;
return false;
} else if (value.indexOf(r.data['query'])==0) {
// forward typing
searchStore.remove(r);
}
});
if (vr_insert==true) {
searchStore.each(function(r) {
if (r.data['query']==value) {
vr_insert = false;
}
});
}
if (vr_insert==true) {
var vr = new searchRec({query: value});
searchStore.insert(0, vr);
}
var ss_max = 4; // max 5 query history, starts counting from 0; 0==1,1==2,2==3,etc
if (searchStore.getCount()>ss_max) {
var ssc = searchStore.getCount();
var overflow = searchStore.getRange(ssc-(ssc-ss_max), ssc);
for (var i=0; i<overflow.length; i++) {
searchStore.remove(overflow[i]);
}
}
}
};
searchBox.on("beforequery", onQuickSearchBeforeQuery);
searchBox.on("beforequery", onFilteringBeforeQuery);
searchBox.on("select", onFilteringBeforeQuery);

// trigger the data store load
ds.load();
});