I have a pie chart in sencha-touch that is not retrieving data from my store, it is gender data coming from a mysql database, the data is being retrieved using an ajax request here is the request and the store
Ext.define('Qvidi.controller.MyController', {
extend: 'Ext.app.Controller',
config: {
},
getGender: function() {
Ext.Ajax.request({
method: 'POST',
params: {
class: 'Qvidi',
method: 'getDataM'
},
url: 'server/index.php',
success: function( response ){
var r = Ext.decode( response.responseText );
Ext.getStore('GenderStore').setData( r.results );
}
});
}
});
and here is the store
Ext.define('Qvidi.store.GenderStore', {
extend: 'Ext.data.Store',
requires: [
'Qvidi.model.GenderModel',
'Ext.data.proxy.Ajax'
],
config: {
model: 'Qvidi.model.GenderModel',
storeId: 'GenderStore',
proxy: {
type: 'ajax',
extraParams: {
class: 'Qvidi',
method: 'getDataM'
},
url: 'server/index.php'
}
}
});
and lastly here is my model
Ext.define('Qvidi.model.GenderModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field'
],
config: {
fields: [
{
name: 'types'
},
{
name: 'counter'
}
]
}
});
here is a log data from inspect in google chrome
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
sencha-touch.js:13032 The key "minimum-ui" is not recognized and ignored.
app.js:39 loaded
Console.js?_dc=1456999436953:35 [DEPRECATE][Anonymous] loadData is deprecated, please use either add or setData
The last log was after I changed setData to loadData
and here is the retrieved sql in my method decoded to json
{
success: true,
total: 2,
results: [
{
types: "Male",
counter: 2182
},
{
types: "Females",
counter: 1134
}
]
}
here is my chart code
{
xtype: 'polar',
height: 377,
id: 'genderPieChart',
colors: [
'#115fa6',
'#94ae0a',
'#a61120',
'#ff8809',
'#ffd13e',
'#a61187',
'#24ad9a',
'#7c7474',
'#a66111'
],
store: 'GenderStore',
series: [
{
type: 'pie',
colors: [
'#115fa6',
'#94ae0a',
'#a61120',
'#ff8809',
'#ffd13e',
'#a61187',
'#24ad9a',
'#7c7474',
'#a66111'
],
labelField: 'types',
xField: 'counter',
yField: 'types'
}
],
interactions: [
{
type: 'rotate'
}
]
}
here is my php code
class Qvidi extends Connect {
function __construct(){
parent::__construct();
}
public function getDataM( $vars ){
$sql = "Select 'Male' as 'types', count(gender) AS 'counter' from quividi.vidireports where gender='1'
union
Select 'Females' as 'types', count(gender) AS 'counter' from quividi.vidireports where gender='2'";
$data = array();
$total = 0;
if( $result = $vars->db->query( $sql ) ) {
while( $row = $result->fetch_assoc() ){
$data[] = array( "types"=>$row["types"], "counter" => intval ($row["counter"] ) );
$total++;
}
$result->free();
}
echo json_encode( array( "success" => true, "total" => $total, "results" => $data ) );
}
ok so:
my php code
<?php
$callback=false;
if(isset($_REQUEST['callback']))
$callback = $_REQUEST['callback'];
$dati=array(
(object) array( 'types'=> 'Male', 'counter'=> 2182),
(object) array( 'types'=> 'Female', 'counter'=> 1134)
);
$resultObj= new stdClass();
$resultObj->results=$dati;
$resultObj->success=true;
if ($callback) {
header('Content-Type: text/javascript');
echo $callback . '(' . json_encode($resultObj) . ');';
}else {
echo json_encode($resultObj);
}
?>
my json response:
{"results":[{"types":"Male","counter":2182},{"types":"Female","counter":1134}],"success":true}
my model:
Ext.define('MyApp.model.GenderModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.Field'
],
fields: [
{
name: 'types'
},
{
name: 'counter'
}
]
});
my store:
you will need these requires for the store:
requires: [
'Ext.data.Store',
'Ext.data.proxy.JsonP',
'Ext.data.reader.Json'
]
myStore: {
autoLoad: true,
model: 'MyApp.model.GenderModel',
proxy: {
type: 'jsonp',
url: 'myphpurl',
reader: {
type: 'json',
rootProperty: 'results'
}
}
}
my chart:
{
xtype: 'polar',
colors: [
'#115fa6',
'#94ae0a',
'#a61120',
'#ff8809',
'#ffd13e',
'#a61187',
'#24ad9a',
'#7c7474',
'#a66111'
],
bind: {
store: '{myStore}'
},
series: [
{
type: 'pie',
angleField: 'counter',
label: {
field: 'types',
display: 'rotate',
contrast: true,
font: '12px Arial'
},
xField: 'counter',
yField: 'types'
}
],
interactions: [
{
type: 'rotate'
}
]
}
my final view:
Related
I have two entities, sent from two different APIs, with a one to one relationship.
I want to load both models in the same grid panel. The problem is that I can only load one store. To load the other store, I attached a callback to the grid reload event which edits the grid DOM manually to insert data form the second store.
My Question is: Can I load both the model and the association without using DOM hacks like I did?
The entities from APIs look like this:
Get /Users/Details:
{
"Id" : "55b795827572761a08d735ac",
"Username" : "djohns",
"Email" : "admin#mail.com",
"FirstName" : "Davey",
"LastName" : "Johns"
}
And:
Get /Users/Rights:
{
"_id" : "55b795827572761a08d735ac",
"Status" : "Activated",
"Roles" : [
"portal",
"dataApp"
]
}
Notice the same id, which is used in the API as the key/foreign key).
Now these are the models:
Ext.define('Portal.model.users.UserRights', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
mapping: 'Id'
},
{
name: 'Status'
},
{
name: 'UserId',
mapping: 'Id',
reference: 'Portal.model.users.UserDetails'
}
],
schema: {
namespace: 'Portal.model.users',
proxy: {
type: 'rest',
url: Portal.util.Util.constants.apiBaseURL + 'Users/Rights',
reader: {
type: 'json',
rootProperty: 'Objects'
}
}
}
});
And:
Ext.define('Portal.model.users.UserDetails', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
mapping: 'Id'
},
'FirstName',
'LastName',
'Username',
'Email'
],
});
And I defined a store for user details (while the store of the user rights is inside its own model):
Ext.define('Portal.store.UsersDetails', {
extend: 'Ext.data.Store',
model: 'Portal.model.users.UserDetails',
proxy: {
type: 'rest',
url: Portal.util.Util.constants.apiBaseURL + 'Users/Details',
reader: {
type: 'json',
rootProperty: 'Objects'
}
}
});
Here is how I configured the Grid:
Ext.define('Portal.view.users.UsersGrid', {
extend: 'Ext.grid.Panel',
store: 'UsersDetails',
columns: [
{
dataIndex: 'id',
text: 'Id'
},
{
dataIndex: 'Username',
text: 'Username'
},
{
dataIndex: 'Email',
text: 'Email'
},
{
dataIndex: 'FirstName',
text: 'First Name'
},
{
dataIndex: 'LastName',
text: 'Last Name'
},
{
text: "Status",
cls: "status-column",
renderer: function (value, meta, record) {
return "loading...";
}
}
],
loadUserRights: function () {
var columns = this.getEl().select('.status-column');
var cells = this.getEl().select(".x-grid-cell-" + columns.elements[0].id + " .x-grid-cell-inner");
data = this.getStore().getData();
Ext.each(data.items, function (record, index) {
var userRights = record.userUserRights();
userRights.load({
callback: function (records, operation, success) {
if (success) {
cells.elements[index].innerText = userRights.data.items[0].data.Status;
}
}
});
});
}
});
And then I load the gird from an external function:
grid.getStore().reload({
callback: function (records, operation, success) {
grid.loadUserRights();
}
});
I'm using Sencha 2.3.0 and I want to have a XTemplate side-to-side to a component (textfield) on a ListItem. The code above works fine for DataView/DataItem, but I want to use the grouped property that is only available on List/ListItem.
The nested Xtemplate gets rendered fine as DataItem. How can I make it work for ListItem? I'm also receptive for solutions that drop this nested structure and use the xtemplate as tpl property directly on the ListItem (of course the textfield with listeners must be implemented as well).
list
Ext.define( 'app.view.myList', {
//extend: 'Ext.dataview.DataView',
extend: 'Ext.dataview.List',
xtype: 'mylist',
requires: [
'app.view.MyItem'
],
config: {
title: "myTitle",
cls: 'mylist',
defaultType: 'myitem',
grouped: true,
store: 'myStore',
useComponents: true,
itemCls: 'myitem',
items: [
{
// some components
}
]
}
});
listitem
Ext.define( 'app.view.myItem', {
//extend: 'Ext.dataview.component.DataItem',
extend: 'Ext.dataview.component.ListItem',
xtype: 'myitem',
config: {
cls: 'myitem',
items: [
{
xtype: 'component',
tpl: new Ext.XTemplate([
'<table cellpadding="0" cellspacing="0" class="myitemXTemplate">',
//some xtemplate content
'</table>'
].join( "" ),
{
compiled: true
})
},
{
label: 'some label',
cls : 'myitemtextfield',
xtype: 'textfield',
name: 'myitemtextfield'
}
]
}
});
Thanks in advance!
Modifed /touch-2.4.2/examples/list/index.html
The model:
Ext.define('model1', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'firstName', type: 'string'},
{name: 'lastName', type: 'string'}
]
}
});
The CustomListItem
Ext.define('DataItem', {
extend: 'Ext.dataview.component.ListItem',
xtype: 'basic-dataitem',
requires: [
'Ext.Button',
'Ext.Component',
'Ext.layout.HBox',
'Ext.field.Checkbox'
],
config: {
dataMap : {
/* getFirstname : {
setData : 'firstName'
},*/
getLastname : {
setValue : 'lastName'
}
},
layout: {
type: 'hbox',
height:'200px',
},
firstname: {
cls: 'firstname',
xtype:'component',
data:{data:'hej'},
tpl: new Ext.XTemplate([
'<H1>',
'{data}',
'</H1>'
].join(""),
{
compiled: true
})
},
lastname: {
xtype:'textfield',
css:'lastname'
}
},
applyFirstname : function (config) {
return Ext.factory(config, Ext.Component, this.getFirstname());
},
updateFirstname : function (newName) {
if (newName) {
this.add(newName);
}
},
applyLastname : function (config) {
return Ext.factory(config, Ext.Component, this.getLastname());
},
updateLastname : function (newAge) {
if (newAge) {
this.add(newAge);
}
},
applyFirstName: function (config) {
return Ext.factory(config, 'Ext.Component', this.getLastname());
},
updateRecord: function(record) {
if (!record) {
return;
}
this.getFirstname().setData({data:record.get("firstName")});
this.callParent(arguments);
}
});
The store
var store = Ext.create('Ext.data.Store', {
//give the store some fields
model: 'model1',
//filter the data using the firstName field
sorters: 'firstName',
//autoload the data from the server
autoLoad: true,
//setup the grouping functionality to group by the first letter of the firstName field
grouper: {
groupFn: function (record) {
return record.get('firstName')[0];
}
},
//setup the proxy for the store to use an ajax proxy and give it a url to load
//the local contacts.json file
proxy: {
type: 'ajax',
url: 'contacts.json'
}
});
The list
xtype: 'list',
useSimpleItems: false,
defaultType: 'basic-dataitem',
id: 'list',
ui: 'round',
//bind the store to this list
store: store
I want to load store data dynamically and don't want to use model for this. if I provide data list gets populated but if I use store's proxy it doesn't get called and url is not getting hit. Please help.
Ext.define('TrainEnquiry.view.SearchTrainResults', {
extend: 'Ext.List',
xtype: 'searchedtrainresult',
requires: 'Ext.data.proxy.JsonP',
config: {
itemId: 'searchedtrainresult',
title: 'Train Result:',
itemTpl: '<div class="myContent">'+
'<div><b>{number}</b> </div>' +
'</div>',
store: {
fields: ['number'],
/*data: [
{number: 'Cowper'},
{number: 'Everett'},
{number: 'University'},
{number: 'Forest'}
]*/
proxy: {
url: 'http://abc.amazonaws.com/search.json',
type:'jsonp',
extraParams : {
'q' : '12313'
},
reader: {
type: 'json',
},
success: function() {
debugger;
console.log('success');
},
failure: function() {
debugger;
console.log('failure');
}
}
},
onItemDisclosure: true
}
});
I think your "fields" config option needs to be a proper Ext.data.Field object, so maybe this would work:
Ext.define('TrainEnquiry.view.SearchTrainResults', {
...
config: {
...
store: {
fields: [ { name: 'number', type: 'string'} ],
proxy: {
...
}
},
...
}
});
(Reference from Sencha forums)
You could try removing the pageParam and startParam from your proxy. Just like this
Ext.create('Ext.data.Store', {
storeId:'UserStore',
autoLoad: true,
model: 'UserModel',
proxy: {
type: 'jsonp', // Because it's a cross-domain
url : 'https://api.twitter.com/1/lists/members.json?owner_screen_name=Sencha&slug=sencha-team&skip_status=true',
reader: {
type: 'json',
root: 'users' // The returned JSON will have array
// of users under a "users" property
},
// Removing pageParam and startParam
pageParam: undefined,
startParam: undefined
}
});
Here is an example http://jsfiddle.net/alexrom7/YNTuN/
Try changing the type of your proxy store to Ajax (type: 'ajax'). Just like this
Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url: '/test.json',
reader: {
type: 'json',
}
},
autoLoad: true
});
I have this json
{
"root":{
"category":[
{
"categoryId":"1",
"children":{
"child":[
{
"subcategoryId":"1",
"children":{
"child":[
{
"productId":"1"
},
{
"productId":"2"
}
]
}
},
{
"subcategoryId":"2",
"children":{
"child":[
{
"productId":"3"
},
{
"productId":"4"
}
]
}
},
{
"subcategoryId":"3",
"children":{
"child":[
{
"productId":"5"
},
{
"productId":"6"
}
]
}
}
]
}
},
{
"categoryId":"2",
"children":{
"child":[
{
"subcategoryId":"4",
"children":{
"child":[
{
"productId":"7"
},
{
"productId":"8"
}
]
}
},
{
"subcategoryId":"5",
"children":{
"child":[
{
"productId":"9"
},
{
"productId":"10"
},
{
"productId":"11"
}
]
}
}
]
}
}
]
}
}
this model
Ext.define('ParentMode', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'categoryId', type: 'string'},
{name: 'children'} // VERY IMPORTANT TO ADD THIS FIELD
],
proxy: {
type: 'ajax',
url : 'store.php',
reader: {
type: 'json',
rootProperty: 'root.category' // this works fine
}
}
}
})
and I have 3 different views: a first view 'main' where I have a dataview where I display 'categoryId':
var myStore = Ext.create('Ext.data.Store', {
model: 'ParentMode',
autoLoad:true
});
var dataview = Ext.create('Ext.DataView', {
scrollable: false,
store: myStore,
listeners: {
itemtap: function(list, index, target, record){
this.up('main').push({
xtype: 'categories',
title: record.get('categoryId'),
extraRecord:record
})
}
}
});
as you can see here from this 'main' view I push a new view,'categories', when one item is tapped and I assign to it a new title getting 'categoryId', and up now all works well.
Now in 'categories' view I display all the 'subcategoryId' this way:
var dataview = Ext.create('Ext.dataview.DataView', {
store: myStore,
itemTpl: '<tpl for="children.child"><div class="category-thumb">SubcategoryID: {subcategoryId}</div></tpl>',
...
Now the problem is How can I in the itemTap push a new view, 'products', setting the title to 'subcategoryId'
I have this:
listeners: {
itemtap: function(list, index, target, record){
this.up('main').push({
xtype: 'products',
title: record.get('subcategoryId'),
})
}
}
the problem is that
title: record.get('subcategoryId'),
doesn't work, I think because it's nested into the json and I think I have to do some cycle but I don't know how.
And again same problem into the 'products' how can I get the 'productsId'
I have two Models: "Identity" and "Profile". The identity 'belongsTo' profile. When I get a record of type 'identity', I want to (by this record) get the correspondent profile. I'm trying using the following code:
Ext.define('App.model.Identity', {
extend: 'Ext.data.Model',
fields: [
// ...
{name: 'id_profile', type: 'int'},
// ...
],
belongsTo: {
model: 'App.model.Profile',
primaryKey: 'id',
foreignKey: 'id_profile',
associatedName: 'Profile'
},
proxy: {
type: 'ajax',
api: {
read: App.Config.getBaseUrl() + '/admin_identity/list',
create: App.Config.getBaseUrl() + '/admin_identity/create',
update: App.Config.getBaseUrl() + '/admin_identity/update',
destroy: App.Config.getBaseUrl() + '/admin_identity/destroy'
},
reader: {
type: 'json',
root: 'data'
}
}
});
Ext.define('App.model.Profile', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
// ...
],
belongsTo: {
model: 'App.model.Identity',
primaryKey: 'id',
foreignKey: 'id_profile',
name: 'identities'
},
proxy: {
// ...
}
});
When I try to do this:
function viewProfile(identity) {
identity.getProfile(function(profile){
console.log(profile);
});
}
What I get is an empty profile's object. The strange thing is that the Identity class didn't do any http request to get the profile. I'm doing this right?
Thanks in advance
Have you tried:
identity.getProfile({
success:function(profile, operation){
},
failure: function(profile, operation){
//check for a failure
}
});
I would also try removing the associatedName property.