Populating Combobox from remote server - extjs4

I have a combobox, i need to populate data from the server. In the server side i have the following data to be displayed.
PersonID
PersonFName
PersonLName
In the combobox, i need to display the text as PersonFName + PersonLName (Like James Smith- This is what it will display in the drop down) , and when a user selects a record, I need to display the corresponding PersonID (Like Person with PersonFName and PersonLName has the PersonID of 1) of that user.
I am unable to figure this out, here's my code
View :
{
xtype: 'combobox',
id: 'personcombo',
readOnly: false,
selectOnFocus: true,
forceSelection: true,
store: 'Person'
}
Store :
Ext.define('MyApp.store.PersonStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.Person'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'MyApp.model.Person',
proxy: {
type: 'ajax',
api: {
read: 'person.php',
create: 'person.php'
},
reader: {
type: 'array'
}
}
}, cfg)]);
}
});
Model :
Ext.define('MyApp.model.Person', {
extend: 'Ext.data.Model',
fields: [
{
name: 'PersonID'
},
{
name: 'PersonFName'
},
{
name: 'PersonLName'
}
]
});

I think your question is: how to display PersonFName + PersonLName in the combobox but keep the PersonID field as the value.
You should add a converted field which joins the first and last names in your data model and then make that one your combobox displayField config.
Though the other answer did bring up a good point that the defined store in your combo is Person but you are showing code for a store named PersonStore.
It would look something like this:
Model:
Ext.define('MyApp.model.Person', {
extend: 'Ext.data.Model',
fields: [
{
name: 'PersonID'
},
{
name: 'PersonFName'
},
{
name: 'PersonLName'
},
{
name: 'PersonName',
convert: function(value, record) {
return record.data.PersonFName + ' ' +
record.data.PersonLName;
}
}
]
});
Store:
// changed to "Person" instead of "PersonStore"
Ext.define('MyApp.store.Person', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.Person'
],
model: 'MyApp.model.Person',
proxy: {
type: 'ajax',
api: {
read: 'person.php',
create: 'person.php'
},
reader: 'array'
}
});
View:
{
xtype: 'combobox',
id: 'personcombo',
readOnly: false,
selectOnFocus: true,
forceSelection: true,
store: 'Person',
valueField: 'PersonID',
displayField: 'PersonName' // the converted field
}

Your combobox has 'Person' as the store, but I don't see you create a store called Person anywhere. Try store: Ext.create('MyApp.store.PersonStore', {autoLoad: true}).
You can also simplify your store:
Ext.define('MyApp.store.PersonStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.Person'
],
model: 'MyApp.model.Person',
proxy: {
type: 'ajax',
api: {
read: 'person.php',
create: 'person.php'
},
reader: 'array'
}
});

Related

How to set dynamic url in sencha touch using store?

I am new for this platform, Now i am unable to set dyanimic url using category id and token.
What i want:
I have list different items, which have different ids but same token, token(tokent is same one user) getting from login phase. I want to get value accorading to category id from the server.
Here is the my model:
Ext.define('MyApp.model.CategoryDisplayModelMenu', {
extend: 'Ext.data.Model',
config: {
fields: [
/*'cat_id',*/
'category',
'name',
],
belongsTo: "MyApp.model.CategoryDisplayModel"
}
});
and another related model is:
Ext.define('MyApp.model.CategoryDisplayModel', {
extend: 'Ext.data.Model',
requires: ['MyApp.model.CategoryDisplayModelMenu'],
config: {
fields: [
{name:'data', mapping: 'data'},
{name:'name'},
{name: 'category'},
{name: 'author'},
],
}
});
What i am set in store, but could not work:
Ext.define('MyApp.store.CategoryValueStore', {
extend: 'Ext.data.Store',
alias: 'store.CategoryValueStore',
requires: [
'MyApp.model.CategoryDisplayModel'
],
config: {
model: 'MyApp.model.CategoryDisplayModel',
storeId: 'categoriesvaluestore',
proxy: {
type: 'rest',
url: 'http://horror/myapp/api/word/searched_words/catID/'+ 1+'/'+ SDSILLYTOKEN+'/'+650773253e7f157a93c53d47a866204dedc7c363,
noCache: false,
reader: {
type: 'json',
rootProperty: ''
} } }
});
How to set above url, dynamic, cat id and token may be differnt.
But it works when i set these in store
Ext.define('MyApp.store.ArchitectureDisplayStore',{
extend: 'Ext.data.Store',
requires:[
'MyApp.view.Main'
],
config:
{
model: 'MyApp.model.CategoryDisplayModel',
autoLoad:true,
id:'Category',
proxy:
{
type: 'ajax',
url : 'http://horror/myapp/api/word/searched_words/catID/1/SDSILLYTOKEN/650773253e7f157a93c53d47a866204dedc7c363', // file containing json data
reader:
{
rootProperty:''
} } }
});
In View , I set getting value on list like this:
Ext.define("MyApp.view.ArchitectureDisplayMain", {
extend: 'Ext.Container',
alias: "widget.architecturewords",
config: {
{
xtype: 'list',
scrollable: true,
itemId: 'demolist',
itemTpl: [
'<div><tpl for="data"><ul class="catList">{name} -test- {category}</ul> <ul>{author}</ul></tpl></div>'
],
store: 'categoriesvaluestore',
}
}
});
My category display model:
Ext.define('MyApp.model.CategoryModelMenu', {
extend: 'Ext.data.Model',
config: {
fields: [
'cat_id',
'category_name',
],
belongsTo: "MyApp.model.CategoryModel"
}
});
and
Ext.define('MyApp.model.CategoryModel', {
extend: 'Ext.data.Model',
requires: ['MyApp.model.CategoryModelMenu'],
config: {
fields: [
{name:'data', mapping: 'data'},
{name: 'cat_id'},
{name: 'category_name'},
],
}
});
EDIT:
Ext.define('MyApp.view.Category', {
extend: 'Ext.List',
alias: "widget.category",
config: {
title: 'Stores',
cls: 'category-data',
scrollable: false,
store: 'CategoryStore',
itemTpl: [
'<div class="categoryListings">',
'<tpl for="data">',
'<span onClick="catOption({cat_id})">{category_name}</span> ',
'</tpl>',
'</div>',
].join('')
}
//}
});
function catOption(id){
console.log("ID--"+id);
var tokan= '650773253e7f157a93c53d47a866204dedc7c363';
Ext.Viewport.remove(Ext.Viewport.getActiveItem(), true);
Ext.Viewport.add([
{ xtype: 'wordsview' }
]);
} and others
In wordsview, I like to display respective words of clicked category.
It is ok, when click this, first item of id p1, it shows next view.
Please tell me, How to get dynamic data accorading to its category id and token. please give some solution.Thank you advance.
If i understood you correctly
Let's say if you have category id and token in localStorage.
You can do like this
proxy:
{
type: 'ajax',
url : 'http://horror/myapp/api/word/searched_words/catID/'+localStorage.catId+'/SDSILLYTOKEN/'+localStorage.token,
reader:{
rootProperty:''
}
}
OR
Do as #Alex posted. That is better way.. Like
function catOption(id){
console.log("ID--"+id);
var token= '650773253e7f157a93c53d47a866204dedc7c363';
var url = 'http://horror/myapp/api/word/searched_words/catID/'+id+'/SDSILLYTOKEN/'+token;
Ext.getStore("categoriesvaluestore").getProxy().setUrl(url);
Ext.getStore("categoriesvaluestore").load();
Ext.Viewport.remove(Ext.Viewport.getActiveItem(), true);
Ext.Viewport.add({ xtype: 'wordsview' });
}
When accessing your Store from your View or anywhere else, you can dinamically change the Url this way:
var stProxy = Ext.StoreMgr.get("myStore").getProxy();
stProxy.setUrl("http://the.new.url");
Ext.StoreMgr.set("myStore").setProxy(stProxy);
--
The particular problem in your scenario is that you may have to populate your list manually. If you want a List to include the result of calling the same Store with different URLs, I suggest to build a new local Store loading the content of all iterations. Then make the List "store" property be this global Store.

Adding a AJAX response data to a store

How to add a data to a json store if my data is coming from a back end AJAX call.
my store is as follows .
Ext.define('MyApp.store.GeographyMasterStore', { extend: 'Ext.data.Store',
requires: [
'MyApp.model.GeographyMasterModel'
],
config: {
model: 'MyApp.model.GeographyMasterModel',
storeId: 'geographyMasterStore',
proxy: {
type: 'ajax',
reader: {
type: 'json'
}
}
}
});
And my model is as follows:
Ext.define('MyApp.model.GeographyMasterModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'Code'
},
{
name: 'Description'
},
{
name: 'Level_Code',
mapping: 'Level Code'
},
{
name: 'Name'
}
]
}
});
If I add the data like this
var geographyMasterStore = Ext.getStore('geographyMasterStore');
geographyMasterStore.add(<data from backend AJAX call>);
it does not show me the mapped field i.e. Level_Code
Usually I when add a record to the store like this :
Ext.create('App.model.MyModel', JSON.parse(response.responseText);
Where response is the response from an Ext.Ajax.request
Hope this helps
You need create a model:
var record = Ext.create('model.GeographyMasterModel', Ext.JSON.decode(response.responseText));
save the model:
record.save()
reload the store:
geographyMasterStore.load()

Sencha Touch Grouper Property Conversion

I have a list reading from a Json store which contains a grouper on a field of type int. This field is called "req" in the sample model below. However, rather than group by the int value, I would like to assign a text value instead, so for example, in case of "1" I would group by "Yes" and in case of "0" I would group by "No". The conversion can be hard coded as it will not change. Where do I make this conversion in my code? Thanks for your help
Ext.define('MyApp.store.MyStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.MyData'
],
config: {
model: 'MyApp.model.MyData',
storeId: 'MyStore',
proxy: {
type: 'ajax',
url: '/path/to/data.json',
reader: {
type: 'json',
rootProperty: 'items'
}
},
grouper: {
property: 'req',
sortProperty: 'req'
},
groupDir: 'DESC'
}
});
Model:
Ext.define('Mypp.model.MyModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'example',
type: 'string'
},
{
name: 'req',
type: 'int'
}
]
}
});
Add to the Model a calculated field with convert() function:
Ext.define('Mypp.model.MyModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'example',
type: 'string'
},
{
name: 'req',
type: 'int'
},
{
name: 'reqDisplay',
type: 'string',
convert: function (value, record) {
if (value == null) {
var req = record.get('req');
value = req ? 'Yes' : 'No'
}
return value;
}
}
]
}
});
... and use it instead
grouper: {
property: 'reqDisplay',
sortProperty: 'reqDisplay'
},
Cheers, Oleg

How to use inner properties of a JSON response with Sencha Proxy

The JSONP proxy is largely working for me, but I need to set properties of a model based on some nested properties in the JSON response. I can't figure how to do this without extending the Reader class, but thought there might be an easier way that I'm just missing.
My Recipe model:
Ext.define('NC.model.Recipe', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'name', type: 'string' },
{ name: 'image', type: 'string' },
{ name: 'preparationText', type: 'string' },
{ name: 'ingredientsText', type: 'string' },
{ name: 'servings', type: 'string' }
]
}
});
My Store:
Ext.define('NC.store.Recipes', {
extend: 'Ext.data.Store',
config: {
model: 'NC.model.Recipe',
storeId: 'Recipes',
proxy: {
type: 'jsonp',
url: 'http://anExternalSite.com/api',
callbackKey: 'callback',
filterParam: 'text',
extraParams: {
type: 'Recipe'
},
reader: {
type: 'json',
idProperty: 'uuid',
}
}
}
});
The JSON format:
[
{
uuid: "/UUID(XXXX)/",
name: "Spicy Peanut Noodle Salad",
image: "http://someplace.com/noodle-salad.jpg",
properties: {
preparationText: "Make it all nice and stuff",
ingredientsText: "Heaps of fresh food",
servings: "serves 4",
}
},
{ ... },
{ ... }
]
I would like those 3 'properties' - preparationText, ingredientsText, and servings, to be placed in the model, but currently only id, name, and image are. What is the method to make this work? If it does involve extending the Reader class, some direction would be great.
Thanks.
You can change your code like this to access nested values
{ name: 'preparationText', type: 'string', mapping: 'properties.preparationText' },
This mapping path should start excluding the root element.

ExtJs4 Model with different poxy url's

I have defined a model which I want to use twice but with a different url int he proxy (in fact only the id differs) But how can I manage this?
Ext.define('TesterModel', {
extend: 'Ext.data.Model',
autoLoad: false,
fields: [
{ name: 'prename', type: 'string' },
{ name: 'lastname', type: 'string' },
{ name: 'dept', type: 'string' },
{ name: 'rackName', type: 'string' },
{ name: 'rackIP' , vtype:'IPAddress'}],
proxy: {
type: 'ajax',
url: 'php/getData_db.php?id=',
reader: {
type: 'json',
messageProperty: 'message',
root: 'data',
}
},
constructor: function() {
UrlParams=document.URL.split("?");
if(UrlParams.length > 1) {
SingleUrlParams=Ext.Object.fromQueryString(UrlParams[1]);
this.proxy.url = this.proxy.url + SingleUrlParams.right;
console.log(this.proxy.url);
}
return this;
}});
Ext.ModelMgr.getModel('TesterModel').load(0, { // load user with ID of "0"
success: function(tester) {
var rightPanel=Ext.getCmp('rightTester');
rightPanel.loadRecord(tester); // when tester is loaded successfully, load the data into the form
}
});
I thought that the constructor will be done before loading, but nope, it is done after. It's weired to me.
Any hints, please?
(the main URL it's like: .../index.html?left=xx&right=yy )
so I want to fill up a panel on the left with the one id, and a panel on the right window side eith th right id.
Thanks!
Try .getProxy().url = "what/ever.php"