Ext.js 4 window with form cals servlet which returns JSON but unable to populate gridpanel - model-view-controller

I am using Ext.js 4 with MVC. I have a window which pops up, and asks the user for some criteria. That window calls a servlet, which returns the data as JSON, and should then populate a grid. I can see thru Firefly that the JSON object IS be returned. However, the grid is not being populated. The reason is that a subsequent call to the servlet is beign made. This is because I have the URL specified in two places. I know this is wrong, but if either one is omitted I get error messages.
This is app/controller/PSLocators.js
Ext.define('MyApp.controller.PSLocators', {
extend: 'Ext.app.Controller',
stores: [ 'PSLocators' ],
models: [ 'PSLocator' ],
views : [ 'pslocator.List' ]
});
This is app/model/PSLocator.js
Ext.define('MyApp.model.PSLocator',
{
extend: 'Ext.data.Model',
fields:
[
'id',
'name',
'address',
'city',
'state',
'zip',
]
});
This is app/store/PSLocators.js. This has the first of the urls. This is the one that returns no data. I don't think I should have the proxy{} here, but if I delete the proxy { } I get the error message
uncaught exception: [Exception... "'You are using a ServerProxy but have not supplied it with a url.' when calling method: [nsIDOMEventListener::handleEvent]"
nsresult: "0x8057001c (NS_ERROR_XPC_JS_THREW_JS_OBJECT)"
location: "JS frame :: chrome://firebug/content/net/spy.js :: callPageHandler :: line 812" data: no]"
Ext.define('MyApp.store.PSLocators', {
extend: 'Ext.data.Store',
model: 'MyApp.model.PSLocator',
autoLoad: false, // see also activate() in grid panel
sortOnLoad: false, // sorted by SAS
proxy:
{
type: 'ajax',
url: MyGlobalData.contextPath + '/PSLocator',
reader:
{
type: 'json',
root: 'data', // the name of the array within the JSON dataset
totalProperty: 'results',
successProperty: 'success'
}
}
});
This is the app/view/pslocator/List.js. This has the second of the urls. This url is returning the data correctly as JSON. If I delete the url I get the error message "uncaught exception: No URL specified"
Ext.define('MyApp.view.pslocator.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.pslocatorlist',
store : 'PSLocators',
title : 'Store Locator',
id : 'pslocator.List',
autoScroll: true,
height: 400,
columnLines: true,
initComponent: function()
{
this.columns = [
{header: 'ID' , dataIndex: 'id' , flex: .05 , align: 'center' },
{header: 'Name' , dataIndex: 'name' , flex: .20 , align: 'left' },
{header: 'Address' , dataIndex: 'address' , flex: .20 , align: 'left' },
{header: 'City' , dataIndex: 'city' , flex: .10 , align: 'left' },
{header: 'State' , dataIndex: 'state' , flex: .05 , align: 'center' },
{header: 'Zip' , dataIndex: 'zip' , flex: .05 , align: 'center' }
];
this.callParent(arguments);
},
listeners:
{
activate: function()
{
this.un('activate', arguments.callee);
var win = new Ext.Window(
{
id: 'id-pslocator-window',
title: 'Show locations near which store?',
items: [
{
xtype : 'form',
id : 'id-pslocator-form',
bodyPadding: 5,
width : 500,
height : 125,
autoScroll : false,
// The form will submit an AJAX request to this URL when submitted
url: MyGlobalData.contextPath + '/PSLocator',
layout: 'auto',
defaults:
{
anchor: '100%'
},
items: [
{
xtype : 'textfield',
fieldLabel : 'Store number',
name : 'pStoreNumber',
labelWidth : 200,
width : 300, // includes labelWidth
allowBlank : false,
regex : /^([0-9]+)([ ]*)$/,
regexText : 'Must be a single unsigned integer.',
}
],
// Reset and Submit buttons
buttons: [
{
text: 'Reset',
handler: function()
{
this.up('form').getForm().reset();
}
},
{
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function()
{
var form = this.up('form').getForm();
if (form.isValid())
{
form.submit(
{
success: function(form, action)
{
console.log('In success function');
var myGrid = Ext.getCmp('id-pslocator-panel');
console.log('myGrid = ' + myGrid);
var myStore = myGrid.getStore();
console.log('myStore = ' + myStore);
myStore.load(); /* requires store be defined as above */
myGrid.getView().refresh();
var myPopup = Ext.getCmp('id-pslocator-window');
myPopup.destroy();
} // end success function
}); // end form submit
} // end if is valid
} // end handler
} // end submit
] // end buttons
}] // end items
}); // end win
win.show();
// this.store.load();
}
}
}); // Ext.define
Can someone please help, or point me to a working example (reminder: I am attempting the use the MVC architecture.)

You should store the proxy configuration in the model rather than the store in ExtJS4. Also It looks like you are just wanting to limit the search on your stores to a particular store number. You shouldn't need to submit a POST request via the form to do this. You should add a filter to your store so the server can return the correct data.
DISCLAIMER: I've not tested this code out, but it should be enough to get you going.
app/model/PSLocator.js
Ext.define('MyApp.model.PSLocator',
{
extend: 'Ext.data.Model',
fields:
[
'id',
'name',
'address',
'city',
'state',
'zip',
],
proxy:
{
type: 'ajax',
url: MyGlobalData.contextPath + '/PSLocator',
reader:
{
type: 'json',
root: 'data', // the name of the array within the JSON dataset
totalProperty: 'results',
successProperty: 'success'
}
}
});
app/store/PSLocators.js
Ext.define('MyApp.store.PSLocators', {
extend: 'Ext.data.Store',
model: 'MyApp.model.PSLocator',
autoLoad: false, // see also activate() in grid panel
sortOnLoad: false, // sorted by SAS,
remoteFilter: true // Needed so filter changes will go to the server
});
app/view/pslocator/List.js
Ext.define('MyApp.view.pslocator.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.pslocatorlist',
store : 'PSLocators',
title : 'Store Locator',
id : 'pslocator.List',
autoScroll: true,
height: 400,
columnLines: true,
initComponent: function()
{
this.columns = [
{header: 'ID' , dataIndex: 'id' , flex: .05 , align: 'center' },
{header: 'Name' , dataIndex: 'name' , flex: .20 , align: 'left' },
{header: 'Address' , dataIndex: 'address' , flex: .20 , align: 'left' },
{header: 'City' , dataIndex: 'city' , flex: .10 , align: 'left' },
{header: 'State' , dataIndex: 'state' , flex: .05 , align: 'center' },
{header: 'Zip' , dataIndex: 'zip' , flex: .05 , align: 'center' }
];
this.callParent(arguments);
}
}); // Ext.define
app/view/pslocator/Window.js
Ext.define('MyApp.view.pslocator.Window', {
extend: 'Ext.Window',
alias: 'widget.storeselector',
id: 'id-pslocator-window',
title: 'Show locations near which store?',
items: [
{
xtype : 'form',
id : 'id-pslocator-form',
bodyPadding: 5,
width : 500,
height : 125,
autoScroll : false,
// The form will submit an AJAX request to this URL when submitted
url: MyGlobalData.contextPath + '/PSLocator',
layout: 'auto',
defaults:
{
anchor: '100%'
},
items: [
{
xtype : 'textfield',
fieldLabel : 'Store number',
name : 'pStoreNumber',
labelWidth : 200,
width : 300, // includes labelWidth
allowBlank : false,
regex : /^([0-9]+)([ ]*)$/,
regexText : 'Must be a single unsigned integer.',
}
],
// Reset and Submit buttons
buttons: [
{
text: 'Reset',
handler: function()
{
this.up('form').getForm().reset();
}
},
{
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function()
{
var form = this.up('form').getForm();
if (form.isValid())
{
this.fireEvent('storeselected', form.getValues().pStoreNumber);
this.destroy();
} // end if is valid
} // end handler
} // end submit
] // end buttons
}] // end items
});
app/controller/PSLocators.js
Ext.define('MyApp.controller.PSLocators', {
extend: 'Ext.app.Controller',
stores: [ 'PSLocators' ],
models: [ 'PSLocator' ],
views : [ 'pslocator.List' ],
init: function() {
this.control({
'pslocatorlist': {
activate: this.showStoreSelector
},
'storeselector': {
storeselected: this.updatePSLocatorStore
}
);
},
showStoreSelector: function()
{
var win = Ext.create('MyApp.view.pslocator.Window');
win.show();
},
updatePSLocatorStore: function(storeId) {
this.getPSLocationsStore().filter('id', storeId);
this.getPSLocationsStore().load(); // I can't remember if this step is needed.
}
});
I think thats about as best I can get it from reading over the code. It should give you an idea of how you can use the MVC technique to your advantage and hopefully get you on the right path.

Related

Get a field placed in the header of a grid column. Extjs 6

I'm working on a grid with a remote filter. So, i set a field in a grid column header.
My question is,
How can i get the field value without field-id ??
See the example below
Thank You
You might be able to bind the value config of your textfield (the textfield in your items of the column header) to an attribute in a view model.
Something like :
var vm = Ext.create('Ext.app.ViewModel', {
data: [{
test : ''
}],
alias: 'viewmodel.myviewmodel',
stores: {
simpsonsStore: Ext.create('Ext.data.Store', {
fields:['name', 'email', 'phone'],
data:[
{'name': 'Lisa', "email":"lisa#simpsons.com", "phone":"555-111-1224"},
{'name': 'Bart', "email":"bart#simpsons.com", "phone":"555-222-1234"},
{'name': 'Homer', "email":"homer#simpsons.com", "phone":"555-222-1244"},
{'name': 'Marge', "email":"marge#simpsons.com", "phone":"555-222-1254"}
]
})
}
});
var grid = Ext.create('Ext.panel.Panel', {
height: 400,
width: 400,
renderTo: Ext.getBody(),
viewModel: vm,
layout: 'hbox',
items:[{
xtype: 'button',
bind: {
text: '{test}'
}
},{
xtype: 'grid',
flex: 1,
bind: '{simpsonsStore}',
columns: [{
text: 'Name',
dataIndex: 'name',
items: [{
xtype: 'textfield',
bind: {
value: '{test}'
}
}]
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}]
}]
});
PS : here is the fiddle ;) https://fiddle.sencha.com/#fiddle/15j6 you can type in your header filed, the button text will updated automatically :)

How to sync combobox and textfield value. i.e how to load different values from store on textfield,while I am changing values on combobox

I am new to EXTjs(and to Stackoverflow as well). I was struggling with this issue and at last decided to ask for help.My question is " How to sync combobox and textfield values. i.e how to load different values from 'store' on textfield,while I am changing values on combobox? " My problem is that while I load values on combobox and I select them my textfield stays empty all the time. I tried "Ext.getCmp().setValue();" it works fine with this ,but I think it is not the best option if I'd have 100 textfields. I want combobox and textfield to be synched with store somehow. Any help is appreciated. Situation in pictures are in links below :
pic one
pic two
And my code :
My app.js :
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: 'work',
appFolder: 'app',
controllers: ['Work'],
launch: function() {
Ext.create('Ext.container.Viewport', {
//layout: 'fit',
items: [{
xtype: 'rightpanel' // gets it from view class
}
]
});
}
});
My view RightPanel :
Ext.define('work.view.works.RightPanel', {
extend: 'Ext.panel.Panel',
ALIAS: 'widget.rightpanel',
width: 300,
title: 'Building navigation',
animCollapse: true,
collapsible: true,
split: true,
minSize: 400,
maxSize: 400,
margins: '0 5 0 0',
//activeTab:1, tabPosition:'bottom',
initComponent: function() {
this.items = [{
xtype: 'form',
items: [{
xtype: 'combobox',
fieldLabel: 'BuildingID',
queryMode: 'local',
name: 'Bid',
displayField: 'Bid',
valueField: 'Bid',
id: 'Bid',
MODE: 'remote',
store: 'Work'
}, {
xtype: 'textfield',
fieldLabel: 'Address',
name: 'Address',
displayField: 'Address',
valueField: 'Address',
id: 'Address',
store: 'Work'
}]
}];
this.columns = [{
header: 'ID',
dataIndex: 'Bid',
flex: 1
}, {
header: 'Texts',
dataIndex: 'Address',
flex: 1
}];
this.callParent(arguments);
}
});
My store :
Ext.define('work.store.Work', {
extend: 'Ext.data.Store',
model: 'work.model.Work',
storeId: 'workstore',
id: 'workstore',
autoLoad: true,
proxy: {
type: 'ajax',
limitParam: undefined,
startParam: undefined,
paramName: undefined,
pageParam: undefined,
noCache: false,
api: {
read: 'data/showWork.php' // just a .php file that reads values from database and shows them on combobox
},
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
},
writer: {
type: 'json',
root: 'data',
encode: true
}
}
});
My Model class :
Ext.define('work.model.Work', {
extend: 'Ext.data.Model',
//idProperty: 'WorkID',
fields: [{
name: 'Bid',
type: 'int'
}, 'Address']
});
My Controller :
Ext.define('work.controller.Work', {
extend: 'Ext.app.Controller',
stores: ['Work'],
models: ['Work'],
views: [
'works.RightPanel' // name comes from view class
],
init: function() {
console.log('Done');
this.control({
'viewport > rightpanel': {
render: this.test
},
'rightpanel combobox[id=Bid]': {
select: this.change
}
});
},
change: function(buttons) {
var values = this.getStore('Work').collect('Address', 'Address', false);
var win = buttons.up('rightpanel'); // gets the needed widget
var form = win.down('combobox'); // gets the needed form
var value = form.getValue(); // gets the value
console.log("value " + value);
}
});
You want to watch for a change on the combobox, and then action a change based off its new value.
this.items = [{
xtype: 'form',
items: [{
xtype: 'combobox',
fieldLabel: 'BuildingID',
queryMode: 'local',
name: 'Bid',
displayField: 'Bid',
valueField: 'Bid',
id: 'Bid',
mode: 'remote',
store: 'Work'
listeners::{
change:function(cbx, newVal,oldVal,e){
var record = cbx.getStore().find("Bid",newVal); // theres prolly a better way to find this, such as to find the active record of the cbx
Ext.getCmp('Address').setValue(record.getValue("Address"))
}
}
},{
xtype: 'textfield',
fieldLabel: 'Address',
name: 'Address',
displayField: 'Address',
valueField: 'Address',
id: 'Address',
store: 'Work'
}]

ExtJS - grid empty but store loaded

My grid is not filled, though the store is filled with json data. What is wrong?
I want all data from "csv":[...] to be written to the grid columns.
If I console.log() the store, my json data is located at store.proxy.reader.[jsonData|rawData].data.csv => Array[4]
Json Data:
{"status":{"status":0,"msg":"Ok","protocolversion":"1.1.json"},"data":{"headline":{"headline":"headline"},"csv":[{"key":"0","value":"...lugin\/monitor\/files\/logfilefilter_worker_error.log"},{"key":"1","value":"...les\/logfilefilter-worker01-progress.log.1331769600"},{"key":"2","value":"...\/application\/x\/plugin\/monitor\/files\/Test.log"},{"key":"3","value":"...ind\/plugin\/monitor\/files\/logfile_for_navi_test.log"}]}}
Model:
Ext.define( 'Monitor.model.ComboLogfiles', {
extend: 'Ext.data.Model',
fields: [ {name: 'key'}, {name: 'value'} ]
} );
Store:
Ext.define( 'Monitor.store.ComboLogfiles', {
extend : 'Ext.data.Store',
model : 'Monitor.model.ComboLogfiles',
proxy : {
type : 'ajax',
url : '/devel/phi/dev/04-presentation/http-api/index.php',
extraParams: {
user : 'test',
pass : 'test',
vers : '1.1.json',
module : 'monitor',
func : 'getLogfiles'
},
reader : {
type: 'json',
root: 'csv'
// root: 'data'
}
},
autoLoad: true
} );
Controller
var store = Ext.create('Monitor.store.ComboLogfiles');
oLogfileSelector = Ext.create("Ext.window.Window", {
title: 'Logfiles',
width: '200',
height: '400',
autoScroll: true,
flex: 1,
minimizable: false,
maximizable: false,
style: 'background-color: #fff;',
items: [{
xtype: 'panel',
items: [
Ext.create('Ext.grid.Panel', {
id: 'mygrid',
store: store,
width: 200,
height: 200,
title: 'Logfiles',
columns: [
{
text: 'Key',
width: 50,
sortable: false,
dataIndex: 'key'
}
,{
text: 'File',
width: 100,
sortable: false,
dataIndex: 'value'
}
]
})
]
}]
}).show();
Maybe try like this:
reader: {
type: 'json',
root: 'data.csv',
successProperty:false
}

How to display a checkbox in Ext.grid.GridPanel?

I need to display a checkbox for column "Active" and when I change the selection to be to able to make an ajax request, to update the database.
Some sample code will help me a lot.
Thanks.
Please check this link: Extjs Grid plugins.
You can check sources for second grid.
Also you need listen 'selectionchange' event for selection model of the grid - so you'll have selected rows and then you can submit a request to server or whatever you need.
If you need specific column (not the first one) - you can check this link: Checkbox in the grid
And I think this is same here too: how to add checkbox column to Extjs Grid
This is example from one of my projects:
Ext.define('Magellano.view.news.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.newslist',
store: 'News',
remoteSort: false,
dockedItems: [{
xtype: 'toolbar',
items: [{
text: 'Online',
id: 'online-button',
enableToggle: true,
icon: '/images/light-bulb.png',
pressed: true,
handler: onItemToggle
}, { text: 'Preview',
id: 'preview-button',
enableToggle: true,
pressed: true
}],
initComponent: function() {
this.selModel = Ext.create('Ext.selection.CheckboxModel', {
singleSelect: false,
sortable: false,
checkOnly: true
});
this.columns = [
{ text: '', width: 28, renderer: function(val) { return "<img src='/images/star-empty.png' height='16' width='16'></img>"}},
{ text: 'Date', width: 60, dataIndex: 'newstime', renderer: renderDate},
{ text: 'Agency', width: 60, dataIndex: 'agency', renderer: function(val) { return val;}},
{ text: 'Category', width: 60, dataIndex: 'category', renderer: function(val) { return val;}},
{ text: 'Title', flex: 1, dataIndex: 'title',
renderer: function(val) { return Ext.String.format('<b>{0}</b>', val); }
}
];
this.title = "News from " + Ext.Date.dateFormat(new Date(), "j M Y");
this.callParent(arguments);
}
}
The important part is that in the initComponent you create the selection model:
this.selModel = Ext.create('Ext.selection.CheckboxModel', {
singleSelect: false,
sortable: false,
checkOnly: true
});

Unable to sort data in ExtJS DataGrid when grouped

I'm using ExtJS 3.3.0 with a datagrid that consumes a JSON data store (Ext.data.GroupingStore).
When I'm not grouping by a column, I can sort just fine, however when grouping by a column, the sort algorithm seems to fall apart.
I have another data grid that does server side sorting (and grouping and paging) and this works just fine. Comparing the the code between the two has left me stumped for the difference that's making one work and the other not work.
Many thanks in advance.
CW.App.FileGrid = {
store : null,
initComponent: function(){
this.store = new Ext.data.GroupingStore({
autoLoad:true,
url:'/sites/files.js',
groupField:'modified',
// Sort by whatever field was just grouped by. This makes the data
// make more sense to the user.
groupOnSort:true,
remoteSort:false,
remoteGroup:false,
sortInfo:{
field:'modified',
direction:'DESC'
},
reader: new Ext.data.JsonReader({
idProperty:'filename',
root:'data',
fields: [
'iconCls',
{
name: 'modified',
type: 'date',
dateFormat:'timestamp'
},
'description', 'folder', 'filename',
'filesize', 'ext', 'dateGroup']
})
});
// this.store.setDefaultSort('modified', 'DESC');
Ext.apply(this, {
store: this.store,
loadMask:true,
columns: [
{
xtype:'actioncolumn',
items:[{
getClass:function(v,meta,rec){
return rec.get('iconCls');
}
}],
width:25
},{
id:'filename',
header: "Filename",
sortable: true,
dataIndex: 'filename'
},{
id:'ibmu',
header: "iBMU",
width:50,
sortable:true,
dataIndex: 'folder'
},{
id:'date',
header: "Date",
width: 65,
sortable: true,
dataIndex: 'modified',
renderer: Ext.util.Format.dateRenderer('Y-m-d h:i'),
groupRenderer:function(v,unused,r,rowIdx,colIdx,ds){
return r.data['dateGroup'];
}
},{
id:'type',
header: "Type",
width: 70,
sortable: true,
dataIndex: 'description'
},{
id:'size',
header: "Size",
width: 50,
sortable: true,
dataIndex: 'filesize',
renderer: Ext.util.Format.fileSize
},{
xtype:'actioncolumn',
items:[{
icon: '/img/fam/drive_disk.png',
tooltip: 'Download file',
handler: function(grid, rowIndex, colIndex){
var rec = store.getAt(rowIndex);
location.href = Ext.urlAppend('/ibmus/download/', Ext.urlEncode({
folder: rec.get('folder'),
filename: rec.get('filename')
}));
}
}]
}
],
autoExpandColumn:'filename',
view: new Ext.grid.GroupingView({
emptyText: 'No files found. Please wait up to 24 hours after activating your account for files to appear.',
forceFit:true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Files" : "File"]})'
}),
frame:false,
width: '100%',
height: 250,
collapsible: false,
animCollapse: false
});
CW.App.AlarmGrid.superclass.initComponent.call(this);
}
};

Resources