Ext JS 4: Returning .NET nullable DateTime? from web method as JSON object to ExtJS not displaying in Ext.grid.Panel - json

I'm returning a list of .NET serialized objects (Project objects) from a JSON web service via an Ext JS JSON proxy. I'm not able to get my Ext.grid.Panel to properly display my date formatted fields. Why would that be? Search for "this one" below. All other fields are showing properly in my Ext grid. And when I save the date from my calendar control, it stores the date properly in the database. To rule out other issues, I've hard coded the date for you in my object.
Serialized class:
[Serializable]
public class Project
{
public string project_id;
public string project_number;
public string project_name;
public string description;
public DateTime? date_start;
}
Web method:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false, XmlSerializeString = false)]
public List<Project> GetProjects(string myTest, string bar)
{
Database db = DatabaseFactory.CreateDatabase("HIMC-DEV");
DbCommand cmd = db.GetStoredProcCommand("project_get_list");
db.AddInParameter(cmd, "#user_id", DbType.String, "");
DataSet ds = db.ExecuteDataSet(cmd);
DataTable dt = ds.Tables[0];
List<Project> projectList = new List<Project>();
foreach (DataRow row in dt.Rows)
{
Project p = new Project();
p.project_id = row[0].ToString();
p.project_number = row[1].ToString();
p.project_name = row[2].ToString();
p.description = row[3].ToString();
p.date_start = new DateTime(2012, 1, 12); // <=== this one
projectList.Add(p);
}
return projectList;
}
Ext Model:
Ext.define('Project', {
extend: 'Ext.data.Model',
fields: [
{ name: 'project_id' },
{ name: 'project_name' },
{ name: 'project_number' },
{ name: 'description' },
{ name: 'date_start', type: 'date' }
]
});
JSON proxy:
Ext.define('Ext.ux.AspWebAjaxProxy', {
extend: 'Ext.data.proxy.Ajax',
require: 'Ext.data',
buildRequest: function (operation) {
var params = Ext.applyIf(operation.params || {}, this.extraParams || {}),
request;
params = Ext.applyIf(params, this.getParams(params, operation));
if (operation.id && !params.id) {
params.id = operation.id;
}
params = Ext.JSON.encode(params);
request = Ext.create('Ext.data.Request', {
params: params,
action: operation.action,
records: operation.records,
operation: operation,
url: operation.url
});
request.url = this.buildUrl(request);
operation.request = request;
return request;
}
});
Ext Window with embedded form:
Ext.define('ProjectEdit', {
extend: 'Ext.window.Window',
alias: 'widget.projectedit',
title: 'Edit Project',
layout: 'fit',
autoShow: true,
closable : true,
initComponent: function () {
this.items = [
{
xtype: 'form',
width: 650,
height: 300,
bodyPadding: 20,
items: [
{
xtype: 'textfield',
name: 'project_id',
fieldLabel: 'Project ID'
//disabled: true
},
{
xtype: 'textfield',
name: 'project_number',
fieldLabel: 'Project Number'
},
{
xtype: 'textfield',
name: 'project_name',
fieldLabel: 'Project Name'
},
{
xtype: 'datefield',
format: 'm/d/Y',
allowBlank: true,
name: 'date_start',
fieldLabel: 'Start Date'
},
{
xtype: 'combo',
fieldLabel: 'Manager',
emptyText: 'select keyword',
store: keywordStore,
valueField: 'name',
displayField: 'name',
mode: 'remote',
autoSelect: false,
selectOnFocus: true,
shadow: true,
forceSelection: true,
triggerAction: 'all', // not sure what this is?
hideTrigger: true,
//multiSelect:true,
typeAhead: true,
minChars: 1,
renderTo: document.body
},
{
xtype: 'htmleditor',
name: 'description',
fieldLabel: 'Description',
enableColors: false,
enableAlignments: false,
width: '100%'
}
]
}
];
...
Ext grid:
Ext.define('ProjectGrid', {
extend: 'Ext.grid.Panel',
initComponent: function () {
var me = this;
Ext.applyIf(me, {
store: store,
columns: [
{ text: 'Project ID', dataIndex: 'project_id', sortable: true },
{ text: 'Project Number', dataIndex: 'project_number', sortable: true },
{ text: 'Project Name', dataIndex: 'project_name', sortable: true, width: 300 },
{ text: 'Start Date', dataIndex: 'date_start', sortable: true, width: 300, renderer: Ext.util.Format.dateRenderer('Y-m-d') },
{ text: 'Description', dataIndex: 'description', sortable: true, width: 500 }
],
listeners: {
//itemdblclick: this.editProject
itemdblclick: function(view, record, item, index, e) {
//var w = new ProjectEdit();
var w = Ext.widget('projectedit');
w.show(); // show the window
w.down('form').loadRecord(record); // load the record in the form
w.callback = Ext.bind(this.editProject, this); // bind lets you set the scope of the callback (for the project that was double clicked)
}
}
});
me.callParent(arguments);
},
...
});
JSON request image from Firebug NET tab (open in a new tab to make it larger):

The issue you experience seems to be connected with the date format for this date field.
By default ExtJS expects date to be sent in format that differs from one used by .Net.
Updating your model the following way should help:
{ name: 'date_start', type: 'date', dateFormat: 'MS' }
or
{ name: 'date_start', type: 'date', dateFormat: 'U' }
See ExtJS API for dateFormat and its possible values.

Related

Sending data to API and retrieving them in to a grid

In my project I am using extjs in front-end. yii2 in backend. I created a form to retrieve selected data from database.
As you can see I have two date fields and a dropdown list. And I have a group of checkboxes. This is a screenshot of my database table.
I should select the data I want using checkboxes and get them from database between 'from' to 'to' dates. When I click RUN button those selected data should be loaded to the grid in the below. When I click download button, those selected data should be downloaded to a csv file. But when I click RUN button it sends same API call twice. And one API gets data correctly and other one sends and error saying 'Undefined index: from'. This is the code in my view.
recordData: {
date: null,
from: null,
to: null,
rb1: null,
rb1: null,
rb2: null,
rb3: null,
rb4: null,
time: null,
rb5: null,
rb6: null,
rb7: null,
weight: 0,
status: 1
}
},
initComponent: function () {
var me = this;
me.title = 'Reports',
me.store = Ext.create('store.Reports');
Ext.apply(me, {
items: [{
xtype: 'form',
border: false,
padding: 10,
bodyStyle: { "background-color": "#e4e4e4" },
width: '100%',
store: me.store,
defaults: {
selectOnFocus: true,
labelWidth: 125
},
items: [{
xtype: 'datefield',
fieldLabel: 'From',
padding: '10 0 0 40',
name: 'from',
format: 'Y-m-d',
labelWidth: 150,
value: me.recordData.from,
displayField: 'from',
typeAhead: true,
queryMode: 'local',
emptyText: 'Select...'
}, {
xtype: 'datefield',
fieldLabel: 'To',
padding: '20 0 0 40',
name: 'to',
format: 'Y-m-d',
labelWidth: 150,
value: me.recordData.to,
displayField: 'to',
typeAhead: true,
queryMode: 'local',
emptyText: 'Select...'
}, {
xtype: 'combobox',
fieldLabel: 'Report Type',
padding: '20 0 0 40',
name: 'type',
labelWidth: 150,
store: [
['Order Report', 'Order Report']
],
value: me.recordData.type,
displayField: 'type',
typeAhead: true,
queryMode: 'local',
emptyText: 'Select...'
}, {
width: '100%',
bodyStyle: { "background-color": "#e4e4e4" },
padding: '20 0 0 40',
bodyPadding: 10,
renderTo: Ext.getBody(),
items: [{
xtype: 'checkboxgroup',
fieldLabel: 'Customize Report',
width: 700,
labelWidth: 150,
columns: 3,
vertical: false,
items: [
{ boxLabel: 'Order ID', name: 'rb1', inputValue: '1', itemId: 'check1' },
{ boxLabel: 'Connection Number', name: 'rb2', inputValue: '2', itemId: 'check2' },
{ boxLabel: 'Status', name: 'rb3', inputValue: '3', itemId: 'check3' },
{ boxLabel: 'Action', name: 'rb4', inputValue: '4', itemId: 'check4' },
{ boxLabel: 'LOB', name: 'rb5', inputValue: '5', itemId: 'check5' },
{ boxLabel: 'Channel', name: 'rb6', inputValue: '6', itemId: 'check6' },
{ boxLabel: 'Company Name', name: 'rb7', inputValue: '7', itemId: 'check7' }
]
}]
}, {
buttons: [{
xtype: 'button',
text: 'RUN',
itemId: 'btnRun',
handler: function (button, event) {
//console.log("Working!", form);
var form = button.up('form');
//targetGridpanel = button.up();
//console.log("Working!", targetGridpanel);
//console.log("Working!", form);
if (form.isDirty()) {
var _vals = form.getValues();
if (!form.isValid()) {
console.log("Not Working!");
Ext.Msg.show({
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK,
title: me.action + ' Report',
msg: 'Fill mandatory fields'
});
} else {
//console.log(_vals);
me.store.saveRecord(_vals, function () {
});
//me.store.load();
if (me.down('#check1').isDirty()) {
me.down('#rb1').show(true);
}
if (me.down('#check2').isDirty()) {
me.down('#rb2').show(true);
}
if (me.down('#check3').isDirty()) {
me.down('#rb3').show(true);
}
if (me.down('#check4').isDirty()) {
me.down('#rb4').show(true);
}
if (me.down('#check5').isDirty()) {
me.down('#rb5').show(true);
me.down('#time').show(true);
}
if (me.down('#check6').isDirty()) {
me.down('#rb6').show(true);
}
if (me.down('#check7').isDirty()) {
me.down('#rb7').show(true);
}
}
} else {
console.log("Close!");
}
}
}]
}, {
xtype: 'gridpanel',
store: me.store,
flex: 1,
margin: '20 0 0 0',
//minHeight: 300,
height: 240,
viewConfig: {
stripeRows: true
},
bbar: {
xtype: 'pagingtoolbar',
store: me.store,
displayInfo: true,
plugins: Ext.create('Ext.ux.ProgressBarPager')
},
columns: [{
dataIndex: 'date',
//itemId:'date',
text: 'DATE',
flex: 1,
menuDisabled: false,
}, {
dataIndex: 'rb1',
itemId: 'rb1',
text: 'ORDER ID',
flex: 1,
menuDisabled: false,
hidden: true,
}, {
dataIndex: 'rb2',
itemId: 'rb2',
text: 'CONNECTION NUMBER',
menuDisabled: false,
hidden: true,
flex: 2
}, {
dataIndex: 'rb3',
itemId: 'rb3',
text: 'STATUS',
menuDisabled: false,
hidden: true,
flex: 1
}, {
dataIndex: 'rb5',
itemId: 'rb5',
text: 'LOB',
menuDisabled: false,
hidden: true,
flex: 1
}, {
dataIndex: 'rb4',
itemId: 'rb4',
text: 'ACTION',
menuDisabled: false,
hidden: true,
flex: 1
}, {
dataIndex: 'time',
itemId: 'time',
text: 'ACTION TIME',
menuDisabled: false,
hidden: true,
flex: 1
}, {
dataIndex: 'rb6',
itemId: 'rb6',
text: 'CHANNEL',
menuDisabled: false,
hidden: true,
flex: 1
}, {
dataIndex: 'rb7',
itemId: 'rb7',
text: 'COMPANY NAME',
menuDisabled: false,
hidden: true,
flex: 1.5
}]
}
, {
buttons: [{
xtype: 'button',
text: 'DOWNLOAD',
itemId: 'download',
//actionMethods: {'read': 'POST'},
handler: function (button, event) {
var self = button.up();
var form = self.up('form');
var vals = form.getValues();
//console.log('Download', vals);
if (vals.from && vals.to && vals.type && (vals.rb1 || vals.rb2 || vals.rb3 || vals.rb4 || vals.rb5 || vals.rb6 || vals.rb7)) {
if (button) {
Ext.Msg.show({
icon: Ext.MessageBox.QUESTION,
buttons: Ext.Msg.YESNO,
title: 'Download Report',
msg: 'Do you want to download the <strong>selected</strong> report file?',
fn: function (buttonId, text, opt) {
if ('yes' == buttonId) {
//console.log(buttonId);
var dummyFormId = 'py-form-' + (new Date()).getTime();
//console.log(dummyFormId);
var frm = document.createElement('form');
frm.id = dummyFormId;
frm.name = dummyFormId;
//console.log(frm);
frm.className = 'x-hidden';
document.body.appendChild(frm);
Ext.Ajax.request({
url: utils.createUrl('api', 'report-download'),
form: Ext.fly(dummyFormId),
isUpload: true,
params: {
from: vals.from,
to: vals.to,
type: vals.type,
rb1: vals.rb1,
rb2: vals.rb2,
rb3: vals.rb3,
rb4: vals.rb4,
rb5: vals.rb5,
rb6: vals.rb6,
rb7: vals.rb7
},
callback: function (opts, success, res) {
console.log('Hello');
//Ext.getBody().unmask();
//console.log(params);
try {
if (success) {
var response = Ext.decode(res.responseText);
if (!response.success) {
throw response.data;
}
} else {
throw response.data;
}
} catch (ex) {
Ext.Msg.show({
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK,
title: 'Download Report',
msg: 'No Data Found'
});
}
},
// fn: function () {
// console.log(arguments);
// }
});
}
}
});
}
} else {
Ext.Msg.show({
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK,
title: 'Download Report',
msg: 'Please fill the form first'
});
}
}
}
]
}
]
}],
});
me.callParent(arguments);
I send these data to a store file. This is store file code.
extend: 'Ext.data.Store',
model: 'model.Report',
storeId: 'reportStore',
autoLoad: false,
pageSize: Configs.grid.pageSize,
saveRecord: function(data,fnCallBack) {
var me = this;
//var data = this.data;
//autoLoad: true,
//console.log(data);
Ext.getBody().mask('Please wait...');
Ext.Ajax.request({
url: utils.createUrl('api', 'report-read'),
params: data,
callback: function(opts, success, res) {
Ext.getBody().unmask();
try {
if(success) {
var response = App.decodeHttpResp(res.responseText);
if(response.success) {
Ext.Msg.show({
icon: Ext.MessageBox.INFO,
buttons: Ext.Msg.OK,
title: 'Reports',
msg: 'Report saved successfully'
});
} else {
throw response.error;
}
me.load();
} else {
throw 'Unknown Reason';
}
} catch (ex) {
Ext.Msg.show({
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK,
title: 'Report',
msg: 'Failed to save data<br />' +
'Reason: ' + ex
});
}
}
});
}
This is my front-end model.
extend: 'Ext.data.Model',
fields: [
{ name: 'from', type: 'auto' },
{ name: 'to', type: 'auto' },
{ name: 'rb1', type: 'auto' },
{ name: 'rb2', type: 'auto' },
{ name: 'rb3', type: 'auto' },
{ name: 'rb4', type: 'auto' },
{ name: 'rb5', type: 'auto' },
{ name: 'time', type: 'auto' },
{ name: 'rb6', type: 'auto' },
{ name: 'rb7', type: 'auto' }
],
proxy: {
type: 'ajax',
noCache: false,
actionMethods: {'read': 'POST'},
api: {
read: utils.createUrl('api', 'report-read'),
//create: utils.createUrl('api', 'user-update'),
// update: utils.createUrl('api', 'user-update'),
// destroy: utils.createUrl('api', 'user-delete')
},
reader: {
type: 'json',
root: 'data'
},
listeners: {
exception: function(proxy, response, operation) {
App.showHttpError('Reports', response);
//console.log(this.fields);
}
}
}
Using these files I send data to controller. That's where my API is defined.
This is my controller function.
public function actionReportRead(){
$post = Yii::$app->request->post();
$time = 0;
$_vals = (new Order())->readReports(
#$post['start'],
#$post['limit'],
$post['from'],
$post['to'],
#$post['rb1'],
#$post['rb2'],
#$post['rb3'],
#$post['rb5'],
#$post['rb4'],
#$time,
#$post['rb6'],
#$post['rb7']
);
$this->setOutputData($_vals);
$this->setOutputStatus(true);
}
This is the model for that.
public function readReports($start, $limit,$from,$to, $rb1, $rb2, $rb3, $rb5, $rb4, $time, $rb6, $rb7 )
{
if (!$start) { $start = 0; };
if (!$limit) { $limit = Config::PAGE_SIZE; };
//$q = (new ActiveQuery(self::className()));
$q = self::find();
//$q->where(['between', 'submitted_time', $from, $to ]);
$q->alias('T')->andWhere(['BETWEEN', 'T.submitted_time', $from, $to ]);
$q->limit($limit);
$q->offset($start);
$q->orderBy(['T.order_id' => SORT_ASC]);
$data = [];
$action = null;
foreach ($q->all() as $_o) {
if($_o->status == 2){
$action = 'Data Entry Verified';
$time = $_o->timeDataEntry;
}else if($_o->status == 3){
$action = 'QC Accepted';
$time = $_o->timeQcPass;
}else if($_o->status == 4){
$action = 'Accepted';
$time = $_o->timeVerify;
}else if($_o->status == 1){
$action = 'Verification Pending';
$time = $_o->timeQcReject;
}else if($_o->status == 0){
$action = 'Rejected';
$time = $_o->timeQcReject;
}
$userlist='SELECT name FROM Company WHERE id = '.$_o->company_id;
$rsuserlist = Yii::$app->db->createCommand($userlist)->query();
$row = $rsuserlist->read();
$data[] = (object) array(
'date' =>$_o->submitted_time,
'rb1' =>$_o->order_id,
'rb2' =>$_o->conn,
'rb3' =>$_o->status,
'rb5' =>$_o->conn_type,
'rb4' =>$action,
'time' =>$time,
'rb6' =>$_o->channel,
'rb7' =>$row['name']
);
}
$json=Json::encode($data);
$this->logger->actLog($json);
return $data;
}
As I have found backend is fine. But I am not pretty sure. I new to extjs. So, I tried many ways but nothing worked. Data is not being loaded to grid and API sends me the error, I mentioned before. Please help me to solve this problem. What should I do more.
I found the answer and I am answering my own question.
Here, one API gets all the data correctly. Other one doesn't get 'from' and 'to' values. So I used following code.
me.store.getProxy().extraParams = {
from: vals.from,
to: vals.to
};
Using this I could send all the parameters to other API and eliminate that issue. Now data is fetched to the grid without a problem.

Ext JS Cascading Combobox

I'm trying to create a cascading combobox but I'm failing to populate the second combobox.
At the moment I've something like this:
var comboStore = null;
comboStore = Ext.create('Ext.data.Store', {
fields: ['ID', 'Name', 'isChecked'],
data: field.values
});
console.log(comboStore);
var comboboxField = Ext.create('SGS.view.field.ComboBox', {
listeners: {
select: function (combo, record, index) {
var tablescomboStore = null;
Ext.Ajax.request({
url: 'Services/DBSourceService.ashx',
method: 'GET',
params: {
id: combo.value
},
reader: {
type: 'json',
rootProperty: 'data', successProperty: 'success'
//root: 'items'
},
success : function(response, opts)
{
var tablescomboStore = null;
tablesComboStore = Ext.create('Ext.data.Store', {
response: ['ID', 'Name', 'isChecked'],
data: response.values
});
var tablesComboboxField = Ext.create('SGS.view.field.ComboBox', {
cls: 'ACombo3',
labelSeparator: '',
labelWidth: 110,
width: 400,
fieldLabel: response.name,
name: response.propName,
displayField: 'Name',
valueField: 'ID',
forceSelection: true,
editable: false,
store: tablesComboStore
});
if (tablesComboStore != null) {
var selected = null;
Ext.each(tablesComboStore.data.items, function (item) {
if (item.data.Checked) { selected = item; }
});
if (selected) tablesComboboxField.select(selected);
}
tablesComboboxField.addListener('select', checkDirty);
instance.add(tablesComboboxField);
},
});
}
},
cls: 'ACombo2',
labelSeparator: '',
labelWidth: 110,
width: 400,
fieldLabel: field.name,
name: field.propName,
displayField: 'Name',
valueField: 'ID',
forceSelection: true,
editable: false,
store: comboStore
});
if (comboStore != null) {
var selected = null;
Ext.each(comboStore.data.items, function (item) {
if (item.data.Checked) { selected = item; }
});
if (selected) comboboxField.select(selected);
}
comboboxField.addListener('select', checkDirty);
instance.add(comboboxField);
I first receive a Json which I put in a store to create some form fields, like Name, Value and Combobox. I want to receive a second Json to populate my second combobox after the first combobox selection.
The second combobox is being created, but without no data.
you can't use response directly since it is a string. try to parse it first:
here you go:
var myArr = JSON.parse(response.responseText);
Ext.each(myArr.values, function (value) {
var tablescomboStore = null;
tablesComboStore = Ext.create('Ext.data.Store', {
fields: ['ID', 'Name', 'isChecked'],
data: myArr.values
});
var tablesComboboxField = Ext.create('SGS.view.field.ComboBox', {
cls: 'ACombo3',
labelSeparator: '',
labelWidth: 110,
width: 400,
fieldLabel: value.name,
name: value.propName,
displayField: 'Name',
valueField: 'ID',
forceSelection: true,
editable: false,
store: tablesComboStore
});

Extjs MVC run function after store loads

I've got a grid getting data through a json store. I want to display the total number of rows in the grid. The problem is that the store.count() function is running before the store loads so it is returning 0. How can I get my count function to run only once the store has loaded? I'm working in MVC, here is my app.js which has my counting logic in it.
Thank you for any help
Ext.application({
name: 'AM',
appFolder: 'app',
controllers: [
'Users'
],
launch: function(){
Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));
Ext.create('Ext.container.Viewport', {
resizable: 'true',
forceFit: 'true',
layout: 'fit',
items:[{
xtype: 'userpanel',
}]
});
var port = Ext.ComponentQuery.query('viewport')[0],
panel = port.down('userpanel'),
grid = panel.down('userlist'),
label = panel.down('label');
var count = grid.store.getCount();
var labelText = "Number of people in list: " + count;
label.setText(labelText);
}
});
store code:
Ext.define('AM.store.Users', {
extend: 'Ext.data.Store',
model: 'AM.model.User',
autoLoad: true,
autoSync: true,
purgePageCount: 0,
proxy: {
type: 'rest',
url: 'json.php',
reader: {
type: 'json',
root: 'queue',
successProperty: 'success'
}
},
sortOnLoad: true,
//autoLoad: true,
sorters: [
{
property: 'PreReq',
direction: 'DESC'
},
{
property: 'Major1',
direction: 'ASC'
},
{
property: 'UnitsCompleted',
direction: 'DESC'
}
],
listeners:{
onload: function(){
var port = button.up('viewport'),
grid = port.down('userlist'),
panel = port.down('userpanel'),
label = panel.down('label'),
count = grid.store.getCount(),
labelText = "Number of people in list: " + count;
label.setText(labelText);
},
scope: this
}
});
grid code:
Ext.define('AM.view.user.List' , {
extend: 'Ext.grid.Panel',
alias: 'widget.userlist',
store: 'Users',
height: 'auto',
width: 'auto',
//resizable: 'true',
features:[{
ftype: 'grouping'
}],
autoFill: 'true',
layout: 'fit',
autoScroll: 'true',
initComponent: function() {
function renderTip(value, metaData, record, rowIdx, colIdx, store) {
metaData.tdAttr = 'data-qtip="' + value + '"';
return value;
};
var dateRender = Ext.util.Format.dateRenderer('m/d/Y');
this.columns=[
//code for all my columns
]
];
this.callParent(arguments);
}
});
Try putting a listener on the store then listen for the onload event get the count and update the field that way. Though there are many ways to do this that is just one.
But in the example above you never load the store you just create it, which is why you see zero.
figured it out, needed to add a listener for the "load" event, not "onLoad". Code below...
Ext.define('APP.store.Store', {
extend: 'Ext.data.Store',
model: 'APP.model.Model',
autoLoad: true,
autoSync: true,
purgePageCount: 0,
proxy: {
type: 'rest',
url: 'json.php',
reader: {
type: 'json',
root: 'users',
successProperty: 'success'
}
},
sortOnLoad:true,
sorters: [{
property: 'last',
direction: 'ASC'
}],
listeners: {
load:{
fn:function(){
var label = Ext.ComponentQuery.query('#countlabel')[0];
label.setText(this.count()+ ' Total Participants);
}
}
}
});

Unable to SAVE data using proxy in ExtJS

Proxy update on ExtJS is not loading my update API instead it loads URL which I use to display data on GRID.
<script type="text/javascript">
Ext.onReady(function () {
var CoventryItemListStore = new Ext.data.Store({
storeId: CoventryItemListStore,
autoSave: true,
writer: new Ext.data.JsonWriter(),
reader: new Ext.data.JsonReader({
idProperty: 'id',
root: 'variables'
}, [{
name: 'id'
}, {
name: 'itemid'
}, {
name: 'triggerQuantity'
}, {
name: 'lastUpdatedBy'
}, {
name: 'lastUpdatedOn'
}]),
proxy: new Ext.data.HttpProxy({
method: 'POST',
prettyUrls: false,
url: '/admin/loadCoventryItemApprovalList.epm',
api: {
update: '/admin/updateCoventryItemApprovalList.epm'
}
}),
listners: {
'write': function (store, action, result, res, rs) {
if (action == 'update') {
var newId = res.raw.newId;
var oldId = res.raw.oldId;
if (newId != oldId) {
CoventryItemListStore.reload();
}
}
}
}
});
CoventryItemListStore.load();
var fm = Ext.form;
var CoventryItemListGridUi = Ext.extend(Ext.grid.EditorGridPanel, {
title: 'Coventry Item List',
store: CoventryItemListStore,
width: 980,
height: 650,
renderTo: 'coventryDiv',
defaults: {
width: 280
},
defaultType: 'textfield',
stripeRows: true,
// reader: CoventryItemListReader,
autoExpandColumn: 'coventryListCol',
align: 'center',
clicksToEdit: 1,
initComponent: function () {
this.columns = [{
xtype: 'gridcolumn',
header: 'ID',
sortable: true,
dataIndex: 'id'
}, {
xtype: 'gridcolumn',
header: 'ITEM ID',
sortable: true,
width: 250,
align: 'center',
dataIndex: 'itemid'
}, {
xtype: 'gridcolumn',
header: 'TRIGGER QUANTITY',
sortable: true,
// id: 'ftpCol',
width: 200,
align: 'center',
dataIndex: 'triggerQuantity',
editor: {
xtype: 'numberfield'
}
}, {
xtype: 'gridcolumn',
header: 'LAST UPDATED BY',
sortable: true,
width: 80,
align: 'center',
dataIndex: 'lastUpdatedBy',
id: 'coventryListCol'
}, {
xtype: 'gridcolumn',
header: 'LAST UPDATED ON',
sortable: false,
width: 100,
align: 'center',
dataIndex: 'lastUpdatedOn',
}];
this.listeners = {
'afteredit': function (e) {
params: {
var oldVal = e.originalValue;
var newVal = e.value;
var fieldName = e.field;
var itemID = e.record.get("itemid");
}
alert('Field \'' + fieldName + '\' changed from \'' + oldVal + '\' to \'' + newVal + '\'.(itemID: ' + itemID + ')');
}
}
var itemsPerPage = 100;
this.bbar = new Ext.PagingToolbar({
pageSize: itemsPerPage,
autoLoad: true,
store: CoventryItemListStore,
displayInfo: true,
displayMsg: 'Displaying categories {0} - {1} of {2}',
emptyMsg: "No categories to display"
});
this.tbar = new Ext.Toolbar({
xtype: 'toolbar',
items: [{
xtype: 'textfield',
id: 'searchValue'
}, {
xtype: 'button',
text: 'Search',
style: 'marginLeft: 5px',
enableToggle: true,
handler: function () {
vms.reload({
params: {
searchValue: Ext.getCmp('searchValue').getValue()
}
});
}
}]
});
CoventryItemListGridUi.superclass.initComponent.call(this);
}
});
new CoventryItemListGridUi();
});
</script>
well re posting the answer for better visibility
proxy: new Ext.data.HttpProxy({ method: 'POST', prettyUrls: false, url: '/admin/updateCoventryItemApprovalList.epm', api: { read: '/admin/loadCoventryItemApprovalList.epm' } })

store is undefined

I have this problem on ExtJS. I created a grid that display on a window, it will get json data from an external server side script. It is rougly working but the firebug keeps telling me that store is undefined everything I click on the columns in the grid. Can you please help me solve this. Here is my code:
var fields = [{
name: "Name",
type: "text"
}, {
name: "NSId",
type: "number"
}, {
name: "Id",
type: "number"
}, {
name: "Version",
type: "number"
}];
var columns = [{
header: 'Name',
id: 'Name',
width: 160,
sortable: true,
dataIndex: 'Name'
}, {
header: 'NSId',
id: 'NSId',
width: 45,
sortable: true,
hidden: true,
dataIndex: 'NSId'
}, {
header: 'Id',
id: 'Id',
width: 30,
sortable: true,
hidden: true,
dataIndex: 'Id'
}, {
header: 'Version',
id: 'Version',
width: 50,
sortable: true,
hidden: true,
dataIndex: 'Version'
}];
var searchAndPickUrl = OcsConfig.url.refto;
var pickerUrl = '?picker=' + config.picker;
var createRefTo = searchAndPickUrl + pickerUrl;
var jsonstore = {
xtype: 'jsonstore',
autoDestroy: true,
fields: fields,
root: 'candidates',
idProperty: 'Name',
url: createRefTo,
autoLoad: true
};
var cmpGrid = null;
var clickCell = function (trigger) {
var record = cmpGrid.getSelectionModel().getSelected();
var selValues = record.data['name'] + ',' + record.data['nsid'] + ',' + record.data['id'] + ',' + record.data['version'];
Ext.Msg.alert('Name', selValues);
};
var refToGrid = {
id: Ext.id(),
xtype: 'grid',
store: jsonstore,
columns: columns,
stripeRows: true,
defaults: {
anchor: '100%'
},
autoExpandColumn: 'Name',
height: 350,
width: 600,
title: '',
stateful: true,
stateId: 'grid',
listener: {
rowdblclick: clickCell
}
};
var refToWin = function refToInputVal(trigger) {
var values = config.options || [];
var cmpWin = null;
var genId = Ext.id();
var win = null;
if (cmpWin === null) {
win = {
xtype: 'window',
title: config.caption || '',
modal: true,
items: [{
xtype: 'form',
id: genId,
padding: 5,
defaults: {
anchor: '100%'
},
items: [refToGrid]
}],
bbar: [{
xtype: 'button',
text: 'OK',
handler: function () {
returnValue(trigger, cmpGrid);
cmpWin.hide();
}
}, {
xtype: 'button',
text: 'Cancel',
handler: function () {
cmpWin.hide();
}
}],
Thanks.
Change your store declaration...
var jsonstore = new Ext.data.JsonStore({
autoDestroy: true,
fields: fields,
root: 'candidates',
idProperty: 'Name',
url: createRefTo,
autoLoad: true
});