How to implement Dynamic Grid in Extjs? - json

I want to implement dynamic grid in Extjs. I have found this How do you create table columns and fields from json? (Dynamic Grid) and the accepted answer looks good.
In my case I have no proxy store but a proxy model:
fields: [ {name: 'id', type: 'int', persist: false},
{name: 'gender', type: 'auto'},
{name: 'name', type: 'auto'},
{name: 'age', type: 'int'}],
identifier: 'sequential', // to generate -1, -2 etc on the client
proxy: {
type: 'rest',
idParam: "id",
url:'http://localhost:3000/posts',
api:
{
read : 'http://localhost:3000/db',
create: 'http://localhost:3000/posts',
update : 'http://localhost:3000/posts' ,
destroy : 'http://localhost:3000/posts'
},
headers: {'Content-Type': "application/json" },
reader: {
type: 'json',
rootProperty:'posts',
totalProperty: 'total'
},
writer: {
type: 'json'
}
My store looks like is:
model: 'ThemeApp.model.peopleModel',
storeId: 'peopleStore',
pageSize: 500,
autoLoad: true,
autoSync: true,
pageSize: 5,
autoLoad: {start: 0, limit: 5},
autoSync: true,
sorters: [{
property : 'age',
direction:'ASC'
}],
groupField: 'gender'
});
In my view I have defined columns:[] But I don't know where to call metachange function.
Can anyone tell me where to use metachange function and should I use metachange function of store or proxy?

Generally you don't want to configure proxy on the model, that is only useful when you want to use standalone Model instances without a store.
Move the proxy config to the Store, and make the server respond to read requests with additional metadata object, which you can then use in the metachange event handler to configure the grid.
Using Reader metadata is the right way to do "dynamic" Grids.

Related

JSON response with various data types

I have a JSON response like this
"{"total":1,"userBeanId":300,"list":[{"errors":[],"success":true,"liferayUserId":31503,"companyId":null,"groupId":null,"locale":null,"status":null,"liferayUserGroupId":null,"idProvider":null,"idClient":null,"userType":4,"userId":200,"email":"xpto#gmail.com","telefone":"999999999","nome":"MYNAME","role":"MY_ROLE","perfil":"Administrator","lastName":null}],"success":true}"
and what I have is a store that reads the list content, like this
"Ext.define('
MYPROJECT.store.Profiles', {
extend: 'Ext.data.Store',
model: 'MYPROJECT.model.Profile',
autoLoad: true,
pageSize: 10,
remoteSort: true,
remoteFilter: true,
proxy: {
type: 'ajax',
api: {
read: '/delegate/rlapi-common/profile/list'
},
enablePaging: true,
reader: {
type: 'json',
root: 'list',
successProperty: 'success'
}
}
});"
and the store "reads" the list successfully. However, I'd like to be able to access the "userBeanId" field as well. Is there any way I can access it by this store (by changing the root to something on an upper-level)? It confuses me as the store "maps" to a model and the userBeanId doesn't fit in the model.
Model:
Ext.define('MYPROJECT.model.Profile', {
extend: 'Ext.data.Model',
fields: [
'userId',
'nome',
'telefone',
'email',
'role',
'perfil'
],
});
You can access store.proxy.reader.rawData to get the most recently loaded JSON. As you suggested, it doesn't make sense being part of the model, but you can read extra meta info via the reader.

extJs - populate grid panel with array of strings

I receive an array of strings from the server.
How can I populate my grid panel if the data is not in key-value format?
Here is the response:
{"result":true,"data":["dep1","dep2","dep3"],"totalCount":3}
Here is my grid panel
xtype: 'gridpanel',
flex: 1,
itemId: 'departmentsGridPanel',
title: '',
store: new Ext.data.ArrayStore({
autoLoad: true,
fields: [
'department'
],
proxy: {
type: 'ajax',
url: 'FilteringDataServlet?filterColumn=avdeling',
reader: {
type: 'json',
root: 'data'
}
}
}),
columns: [{
text: 'Avdeling',
flex: 1,
dataIndex: 'department'
}],
Then you should use Ext.data.reader.Array with mapping parameter.
Employee = Ext.define('Employee', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', mapping: 0}, // "mapping" only needed if an "id" field is present which
{name: 'occupation', mapping: 1} // precludes using the ordinal position as the index.
]
});
I have solved this by adding load listener to my store and modifying the data there
listeners: {
load: function(store, records, success, opts) {
store.each(function(record) {
record.set('department', record.raw);
});
}
}

JSON data not loading - ExtJS

I cannot get any of my json data to load into my combobox. Here's my code:
app/data/mydata.json
{
images: [
{name: 'Image one', url:'/GetImage.php?id=1', size:46.5, lastmod: new Date(2007, 10, 29)},
{name: 'Image Two', url:'/GetImage.php?id=2', size:43.2, lastmod: new Date(2007, 10, 30)}
]
}
inside my app.js
var store4 = new Ext.data.JsonStore({
// store configs
storeId: 'myStore',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'app/data/mydata.json',
reader: {
type: 'json',
root: 'images',
idProperty: 'name'
}
},
});...
my combobox inside app.js
{ xtype: 'combobox', queryMode: 'local', padding: 5, store: store4, displayField: 'name', typeAhead: true, emptyText: 'JSON', id: 'test' },
Any ideas?
Cheers!
That isn't valid JSON:
Labels should be wrapped in quotes, eg "name". You should also use double quotes, not single for quoting strings.
You can't use new Date() in JSON, it's not valid. Have a look at Ext.data.Field and the information around the dateFormat parameter. You send the date back as a string and give it a format so Ext can parse it for you.
Also, you're missing field definitions. You need to create an Ext.data.Model subclass with the fields you're going to use in the store.
Ext.define('Image', {
extend: 'Ext.data.Model',
fields: ['name', 'url', 'size']
});
var store = new Ext.data.Store({
model: 'Image',
// ..
});

How to send model specific attributes to server side in extjs4?

I am working in extjs4 MVC structure and I have been facing problem in extjs4
all the fields are submitting to server side but I want to send only some fileds of model class to server side. How can I get this output?
1) Here is my model class
Ext.define('ab.model.sn.UserModel',{
extend: 'Ext.data.Model',
//idproperty:'userId',//fields property first position pk.
fields: ['userId','firstName','middleName','lastName','languageId','primaryEmail','birthDate','password','securityQuestionId','securityQuestionAnswer','isMale','creationTime','ipAddress','confirmationCode','userStatusId',],
proxy:
{
type:'ajax',
//type:'localstorage',
//id:'users',
api:
{
read:'http://localhost/balaee/Balaee/index.php/SocialNetworking/user/AuthenticateLogin',
create:'http://localhost/balaee/Balaee/index.php/SocialNetworking/user/AuthenticateLogin122',
update:'http://localhost/balaee/Balaee/index.php/SocialNetworking/user/AuthenticateLogin123'
},//end of api
reader:
{
type:'json',
},//end of reader
writer:
{
type:'json',
root:'records',
},//End of writer
}//end of proxy
});
2) Here is my some controller file code
var userObject = Ext.ModelManager.create(
{
firstName:record.get('firstName'),
password:record.get('password'),
},'ab.model.sn.UserModel');
userObject.save({
success: function(record, operation)
{
console.log("registration successssssssssss "+record.get('userId'));
},//End of success function
failure: function(record, operation)
{
console.log("Inside failure functionnnnn");
},//End of failure function
callback: function(record, operation)
{
console.log("Inside callback functionnnnnn");
}//End of callback function
});// End of check save function
3) And data would be going in json format
{"records":{"userId":"","firstName":"ram","middleName":"","lastName":"","languageId":"","primaryEmail":"","birthDate":"","password":"sham","securityQuestionId":"","securityQuestionAnswer":"","isMale":"","creationTime":"","ipAddress":"","confirmationCode":"","userStatusId":"","id":null}}
4) But I want to send only firstName and password.I dont want send all fields. how can I send the data to server side.
I want json in this format
{"records":{"firstName":"ram","password":"sham"}}
please give me some suggestions....
You just need to overwrite the getRecordData function of the writer. Like this.
writer:
{
type:'json',
root:'records',
getRecordData: function (record) { return {"firstName" :record.data.firstName,"password": record.data.password}; },
},
nscrob's answer has less coding so it may be preferred, but there is also a built-in config for this on the model: persist: false. It keeps the model field from being sent to the server side.
IMHO the model configs don't seem to get used as well as they should even in the sencha examples (or maybe because they are not used in the sencha examples). I think it also saves a miniscule amount of resources if you define the data types in the model as opposed to letting the client work it out, for example:
Ext.define('ab.model.sn.UserModel',{
extend: 'Ext.data.Model',
//idproperty:'userId',//fields property first position pk.
// using field type definitions and explicit persistance
fields: [
{name: 'userId', type: 'int', persist: false},
{name: 'firstName', type: 'string'},
{name: 'middleName', type: 'string', persist: false},
{name: 'lastName', type: 'string', persist: false},
{name: 'languageId', type: 'int', persist: false},
{name: 'primaryEmail', type: 'string', persist: false},
{name: 'birthDate', type: 'date', dateFormat: 'c', persist: false},
{name: 'password', type: 'string'},
{name: 'securityQuestionId', type: 'int', persist: false},
{name: 'securityQuestionAnswer', type: 'string',persist: false},
{name: 'isMale', type: 'bool', persist: false},
{name: 'creationTime', type: 'date', dateFormat: 'c', persist: false},
{name: 'ipAddress', type: 'string', persist: false},
{name: 'confirmationCode', type: 'string', persist: false},
{name: 'userStatusId', type: 'int', persist: false}
],
proxy:
{
type:'ajax',
//type:'localstorage',
//id:'users',
api:
{
read:'http://localhost/balaee/Balaee/index.php/SocialNetworking/user/AuthenticateLogin',
create:'http://localhost/balaee/Balaee/index.php/SocialNetworking/user/AuthenticateLogin122',
update:'http://localhost/balaee/Balaee/index.php/SocialNetworking/user/AuthenticateLogin123'
},//end of api
reader:
{
type:'json',
},//end of reader
writer:
{
type:'json',
root:'records',
},//End of writer
}//end of proxy
});
Like I said, there is some more coding but I thought I would throw this out there as the built-in handling for this scenario (instead of the override). You could also drop the field type definitions if you wanted, they aren't required to define the persist property.

problem with PagingToolbar Extjs 4

I'm using ExtJS v4 for making some rich interfaces, the problem is that i encounter difficulties from time to time (something quite normal for a beginner in Extjs: p), the problem i encounter now, concern the pagination, in fact on my page i have all the records that are displayed, even after specifying the item by nbr of pages if possible to help me thanks
Ext.onReady(onReady);
function onReady() {
var itemsPerPage = 10;
var store = new Ext.data.JsonStore({
autoLoad: false,
pageSize: itemsPerPage,
proxy: new Ext.data.HttpProxy({
type: 'ajax',
url: '../Service.asmx/GetMyDvpt',
reader: {
type: 'json',
root: 'd',
//totalProperty: 'total',
idProperty: 'Id'
},
headers: {
'Content-type': 'application/json'
}
}),
fields: ['NOM_EXP', 'NOM_ESP', 'NOM_VAR', 'SURF_PG', 'DD_CYCLE_PROD']
});
store.load({
params: {
start: 0,
limit: itemsPerPage
}
});
Ext.create('Ext.grid.Panel', {
store: store,
columns: [
{ dataIndex: 'NOM_EXP', header: 'NOM_EXP' },
{ dataIndex: 'NOM_ESP', header: 'NOM_ESP' },
{ dataIndex: 'NOM_VAR', header: 'NOM_VAR' },
{ dataIndex: 'SURF_PG', header: 'SURF_PG' },
{ dataIndex: 'DD_CYCLE_PROD', header: 'DD_CYCLE_PROD', flex: 1 }
],
renderTo: 'panel',
title: 'Dvpt Grid',
width: 570,
height: 350,
dockedItems: [{
xtype: 'pagingtoolbar',
store: store,
dock: 'bottom',
displayInfo: true
}]
});
}
You must create new instances of Ext JS objects with Ext.create, because objects instantiated with the new keyword won't take care of the Ext JS class system.
When you look at the load() method source code, you'll see how the configuration options get applied, and so would you:
store.load({
start: 0,
limit: itemsPerPage
});
Since the store has already been configured with pageSize, there's no need for the limit options, since it gets the pageSize as default.
store.load({
start: 0
});
I'd also recommend to have a look at the loadPage() method, that handles setting all the paging relevant parameters correctly:
store.loadPage(1);
Another enhancement is to set autoLoad to true, then you could omit the store load completely.
There is also no need to create a Ext.data.HttpProxy manually, since the configuration object specifies the ajax type and will take care of instantiating the correct proxy type for you.
Since you specified a JSON reader, there should be no need to set the HTTP accept header. Content-Type is anyway a response header and the corresponding request header would be Accept.
So your code should look like this:
Ext.onReady(onReady);
function onReady() {
var store = Ext.create('Ext.data.JsonStore', {
autoLoad: true,
pageSize: 10,
proxy: {
type: 'ajax',
url: '../Service.asmx/GetMyDvpt',
reader: {
type: 'json',
root: 'd',
totalProperty: 'total',
idProperty: 'Id'
}
},
fields: ['NOM_EXP', 'NOM_ESP', 'NOM_VAR', 'SURF_PG', 'DD_CYCLE_PROD']
});
Ext.create('Ext.grid.Panel', {
store: store,
columns: [
{ dataIndex: 'NOM_EXP', header: 'NOM_EXP' },
{ dataIndex: 'NOM_ESP', header: 'NOM_ESP' },
{ dataIndex: 'NOM_VAR', header: 'NOM_VAR' },
{ dataIndex: 'SURF_PG', header: 'SURF_PG' },
{ dataIndex: 'DD_CYCLE_PROD', header: 'DD_CYCLE_PROD', flex: 1 }
],
renderTo: 'panel',
title: 'Dvpt Grid',
width: 570,
height: 350,
dockedItems: [{
xtype: 'pagingtoolbar',
store: store,
dock: 'bottom',
displayInfo: true
}]
});
}
When dealing with problems like this, I usually test the backend service with a REST client. There are many addons for different browsers available, for example RESTClient for Firefox or Advanced REST clinet for Chrome. Make sure that your service behaves correct without any UI, just by sending plain HTTP request with manually defined parameters. Only move to the GUI part when when everything works as expected.
For the GUI part I encourage you to study the source code of Ext JS within the API Documentation, it's well structured and documented and you'll learn a lot.
Since version 4 Ext JS comes with a MVC application framework, which simplifies the creation of large RIA apps a lot. Read more at the Application Architecure Guide.
Paging Toolbar supports remote paging by default. If local paging is required paging then reload store on 'datachange' and 'refresh' event fired.