Is id of model can only be int in extjs4? - extjs

I have a model and its id is type string. I load a record to display in grid but the id is show 'NaN'.
json
{"results":[{"id":"FT01","name":"area1","enable":true}],"total":1,"success":true}
model
Ext.define('YX.model.Area', {
extend : 'Ext.data.Model',
fields : [
{ name : 'id', type : 'string' },
{ name : 'name', type : 'string' },
{ name : 'enable', type : 'boolean', defaultValue : true }
]
});
store
Ext.define('YX.store.AreaStore', {
extend : 'YX.store.ListStore',
model : 'YX.model.Area',
proxy : {
type : 'ajax',
url : 'area/list.do',
reader : Utils.ajax.gridReader
}
});
Utils.ajax.gridReader =
{
type : 'json',
root : 'results',
successProperty : 'success',
totalProperty : 'total'
}
If I set proxy.reader to a direct object then id is show correctly in grid.
proxy : {
type : 'ajax',
url : 'area/list.do',
reader : {
type : 'json',
root : 'results',
successProperty : 'success',
totalProperty : 'total'
}
}

That may depends on what you do with the model, and the type of storage that backs your data. In principle, there should not be such a restriction, but that may be an expectation of some part of the framework (or third-party code).
Anyway, I've written a minimal test case with your model and a grid, and the id string is displayed correctly. That means that you probably have an issue somewhere else in your code... Most probably the proxy, reader or store.
Here's the test code (running there):
Ext.define('Area', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'string'
}, {
name: 'name',
type: 'string'
}, {
name: 'enable',
type: 'boolean',
defaultValue: true
}]
});
Ext.onReady(function() {
Ext.widget('grid', {
renderTo: Ext.getBody(),
height: 300,
columns: [
{dataIndex: 'id', text: "ID"},
{dataIndex: 'name', text: "Name"}
],
store: {
model: 'Area',
proxy: {
type: 'memory'
,data: [
{id: 'foo', name: "Foo"}
,{id: 'bar', name: "Bar"}
]
},
autoLoad: true
}
});
});

this error is because of your field name is "id".
default idProperty='id' field and idProperty field must have int data.but in your case it is not.
so this code is giving you this error.
if you won't need idProperty then chanege you field's name "id" to something else
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Model-cfg-idProperty

If you want your ID to be a number, you can customize it using identifier.
This is how it worked for me. I added this code in my model:
identifier: {
type: 'sequential',
seed: 10
},

Related

Create Select field in detail window

I am creating a custom plugin where I need to list some stuff in the backend area. Each item in the list has the option to open a detail window where I want to display some info and a SELECT OPTION field but not sure how to create it. That field is just to select the option you want and save it in the database.
Is it possible to create it in myplugin/Resources/views/backend/my_plugin/model/product.js file?
I have something like this (sample):
Ext.define('Shopware.apps.MyPlugin.model.Product', {
extend: 'Shopware.data.Model',
configure: function() {
return {
controller: 'MyPlugin',
detail: 'Shopware.apps.MyPlugin.view.detail.Product'
};
},
fields: [
{ name : 'id', type: 'int', useNull: true },
{ name : 'Name', type: 'string' },
{ name : 'Lastname', type: 'string' },
{ name : 'Date', type: 'date' },
{ name : 'Color', type: 'SELECT?' }
]
});
Of course the Color field doesnt recognize the SELECT there but I was wondering if there's another word for it?
I was hoping to create that new field like this:
fields: [
...
{
name : 'Color',
type: 'SELECT?',
values: {'green', 'blue', 'red'}
}
]
If I am completly wrong could you please guide me where to create this field?
Thanks in advance.
You're defining a model, not a plugin and it looks like you want to configure 'Color' as an enum? Am I right?
The standard types are:
Ext.data.field.Field //(Default, implies no conversion)
Ext.data.field.String
Ext.data.field.Integer
Ext.data.field.Number
Ext.data.field.Boolean
Ext.data.field.Date
(see documentation under Field Types)
You can probably just use a string unless you want model validation...
You could create a custom type, extended from string or field and use a custom validator. (see same page under Validation)
Example:
Ext.define('App.field.Color', {
extend: 'Ext.data.field.Field',
alias: 'data.field.color',
// Match list of colors
validators: {
type: 'list',
list: ['green', 'blue', 'red']
}
});
Ext.define('App.model.Product', {
extend: 'Ext.data.Model',
fields: [
{ name : 'id', type: 'int', useNull: true },
{ name : 'Name', type: 'string' },
{ name : 'Lastname', type: 'string' },
{ name : 'Date', type: 'date' },
{ name : 'Color', type: 'color' }
]
});

Define mapping in reader

I have defined a custom ComboBox component, that I want to re-use with multiple Stores. It has a simple config as below.
Ext.define('Myapp.CustomCombo', {
extend: 'Ext.form.ComboBox',
valueField: 'id',
displayField: 'name'
});
The model is
Ext.define('Myapp.model.ComboModel',{
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' },
{ name: 'linkCls', type: 'string' }
]
});
I define multiple stores each with its own proxy config & identified by a unique storeId, as below
Ext.create('Myapp.store.EmployeeComboStore', {
model: 'Myapp.model.ComboModel',
storeId: 'employeeLOVComboStore',
proxy: {
type: 'rest',
url: '/employees/getLovData',
reader: {
type: 'json',
rootProperty: 'data'
}
}
});
The server responds with a json as below
{
"data" : [
{"employeeId": 1, "employeeName": "Chris"},
{"employeeId": 2, "employeeName": "Jack"},
]
}
I can have multiple such stores, like departmentStore with a different proxy URL and where in, the server response could be
{
"data" : [
{"departmentId": 1, "departmentName": "Sales"},
{"departmentId": 2, "departmentName": "Marketing"},
]
}
I want to define a mapping in the Reader, with instructions to map data differently in different stores, as in.. employeeId should be mapped to 'id' & employeeName to 'name' in employeeStore, whereas departmentId should be mapped to 'id' & departmentName to 'name' in departmentStore.
I've seen that there are options to define mapping for each field in a Model, but I would want to define a mapping in a Reader, since the server responds with data from a relational database where field names would be the columnNames.
What you can do, is to send along metaData from the server to the client.
The json response can look like this:
{
data: [{ ... }],
msg: "...",
total: 99,
metaData: {
fields: [{ ... }],
columns: [{ ... }],
idProperty: "id",
messageProperty: "msg",
root: "data"
}
}
In you case it would be sufficient if the json response would look like this
{
data: [{ ... }],
metaData: {
fields: [
{ name: 'Id', type: 'int', mapping: 'departmentId' },
{ name: 'Name', type: 'string', mapping: 'departmentName' },
]
}
}
Here is also a good example how it works: Basic Meta Data Config

extjs4 grid grouped with function

Ext.define('record.SecurityCase', {
extend : 'Ext.data.Model',
fields : [{
name : 'id',
type : 'string',
persist : false
}, {
name : 'takeplaceTime',
type : 'date',
persist : true
}, {
name : 'brief',
type : 'string',
persist : true
}],
groupField: 'takeplaceTime'
});
A grid with store used model above.And I want it to be grouped with 'takeplaceTime'.for example:
obj.takeplaceTime='2013-10-01';obj2.takeplaceTime='2013-04-01';obj3.takeplaceTime='2013-12-01';obj4.takeplaceTime='2012-12-01';
obj;obj2;obj3 are one group as its year is 2013. obj4 will be another ,year 2012.
Is there a groupRenderFunction to handle this?
You can define calculated property in Model for grouping. Example:
Ext.define('Model1', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'seniority', type: 'string'},
{name: 'department', type: 'string'},
{name: 'group', type: 'string', convert: function(value, record) {
return record.get('name').substr(0, 1); // first letter of name
} }
]
});
Working sample in Ext JS 4.2: http://jsfiddle.net/BmVeg/1/

Sencha Touch 2 association problems

I get from server next JSON:
{
"contextPath":"http://apps.dhis2.org/demo",
"user":{
"id":"GOLswS44mh8",
"name":"System Administrator",
"isAdmin":true,
"ou":{
"id":"ImspTQPwCqd",
"name":"Sierra Leone"
}
}
}
I need convert this JSON in two Models : User model and OrganizationUnit model.
I read this tutorial http://docs.sencha.com/touch/2.2.1/#!/api/Ext.data.reader.Reader so it my code :
User model :
Ext.define('mobile-visualizer.model.User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'string'},
{name: 'name', type: 'string'},
{name: 'isAdmin', type: 'boolean'}
],
hasOne: {
model: "mobile-visualizer.model.OrganizationUnit",
name: "ou"
},
proxy: {
type: 'ajax',
url : 'http://apps.dhis2.org/demo/dhis-web-visualizer/initialize.action',
method : 'GET',
withCredentials : true,
useDefaultXhrHeader : false,
reader: {
type: 'json',
rootProperty: 'user'
}
}
}
});
OrganizationUnit model :
Ext.define('mobile-visualizer.model.OrganizationUnit', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'string'},
{name: 'name', type: 'string'}
],
belongsTo: 'mobile-visualizer.model.User'
}
});
Store :
Ext.define('mobile-visualizer.store.UsersStore', {
extend : 'Ext.data.Store',
model : "mobile-visualizer.model.User",
autoLoad : false,
storeId : "usersStore",
proxy : {
type : 'ajax',
url : 'http://apps.dhis2.org/demo/dhis-web-visualizer/initialize.action',
method : 'GET',
withCredentials : true,
useDefaultXhrHeader : false,
reader : {
type : 'json',
rootProperty : 'user'
}
}
});
So, when I try get user from store using another code :
var store = Ext.create('mobile-visualizer.store.UsersStore');
store.load({
callback : function() {
// the user that was loaded
var user = store.first();
console.log(user.ou())
}
});
I have error : Uncaught TypeError: Object [object Object] has no method 'ou'
I can get all information about user but I can't get ou from user. It look like some association issue.
But I make all as like official tutorial . Please help to resolve this problem.
Thanks.
Follow my rules and everything will come out rosy:
http://extjs-tutorials.blogspot.ca/2012/05/extjs-hasmany-relationships-rules.html
http://extjs-tutorials.blogspot.ca/2012/05/extjs-belongsto-association-rules.html
These are for extjs, but very similar for sencha touch.
You are forgetting the associationKey.
Also, no need to redefine proxy in store as it will inherit its model's proxy.
Also, a user probably belongs to an org unit and doesn't have one...

Howto obtain child item data with hasMany relation in extjs4 grid selectionchange event

I have a storage with models:
Ext.define('App.Supplier.Store', {
extend : 'Ext.data.Store',
constructor : function(config) {
Ext.regModel('Supplier', {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'irn', type: 'string'}
],
hasMany : {model: 'SupplierContact', name: 'contacts', associationKey: 'contacts'}
});
Ext.regModel('SupplierContact', {
fields: [
{name: 'id', type: 'int'},
{name: 'email', type: 'string'},
{name: 'phone', type: 'string'},
{name: 'name', type: 'string'}
],
belongsTo: 'Supplier'
});
config = config || {};
config.model = 'Supplier';
config.proxy = {
type : 'ajax',
url : '/supplier/search/process',
reader : {
type : 'json',
root : 'data',
totalProperty : 'totalCount',
successProperty: 'success'
}
};
config.pageSize = 10;
config.remoteSort = true;
config.simpleSortMode = true;
// call the superclass's constructor
App.Supplier.Store.superclass.constructor.call(this, config);
}
});
I have a valid json from url and this code works fine:
var store = new App.Supplier.Store({storeId: 'supplierStore'});
store.load({
callback: function() {
var supplier = store.first();
console.log("Order ID: " + supplier.getId() + ", which contains items:");
supplier.contacts().each(function(contact) {
alert(contact.data.phone);
});
}
});
My grid:
Ext.define('App.Supplier.Grid', {
extend : 'Ext.grid.GridPanel',
alias : 'widget.supplierGrid',
cls : 'supplier-grid',
iconCls: 'icon-grid',
collapsible: true,
animCollapse: false,
title: 'Expander Rows in a Collapsible Grid',
height: 300,
buttonAlign:'center',
headers : [
{text : 'Id', dataIndex : 'id', width : 20},
{text : 'Name', dataIndex : 'name', flex : 4 },
{text : 'IRN', dataIndex : 'irn', flex : 3}
],
initComponent : function() {
this.store = new App.Supplier.Store({storeId: 'supplierStore'});
this.store.load();
this.callParent(arguments);
this.on('selectionchange', this.onRowSelect, this);
},
onRowSelect: function(sm, rs) {
if (rs.length) {
alert(sm.contacts); // undefined
alert(rm.contacts); // undefined
var info = this.getComponent('infoPanel');
info.updateDetail(rs[0].data);
}
}
});
How to get contacts in onRowSelect for selected row ?
PS: json from server:
{"totalCount":100,
"success":true,
"data":[{
"id":2,
"name":"department 0",
"irn":"123490345907346123-0",
"contacts":[{
"id":3,
"phone":"+7907 123 12 23",
"email":"test#localhost",
"name":"hh"
}, {
"id":4,
"phone":"+7832 123 12 23",
"email":"test2#localhost",
"name":"gtftyf"
}]
}]}
Can you provide your json as well? I think your json is not correct so that, ExtJS loads the relationships as well. In order to load the relationships as well, you will need to provide the contacts details in the returned json as well..
You should have something like this:
sucess: true,
totalCount: 10,
data: [{
id: 142,
name: 'xyz',
irn: 'test',
contacts: [{
id: 130,
email: 'xyz#site.com',
phone: 123445,
name: 'Supplier XYZ'
},{
id: 131,
email: 'test#site.com',
phone: 123445,
name: 'Supplier XYZ'
}]
}, ...
]
Update:
Json is correct! The problem lies with the way you access your data. If you look at the signature of selectionchange event, you will notice that the first is DataView and second is an array of selected records. So, in your case the rs is an array of the selected rows. You should be able to access it as rs[0].contacts.
Another way to access the selected records will be to use the DataView object. You can use the getSelectedRecords method to get the array of the selected records.

Resources