Sencha Touch: Ext.DataView not showing store data - sencha-touch

I know the typical reason for a DataView to be blank is because the model or JSON is wrong. From what I can tell, mine is right... so I'm not sure why my DataView is blank.
Controller
rpc.controllers.AboutController = new Ext.Panel({
id: 'rpc-controllers-AboutController',
title: 'About',
iconCls: 'info',
layout: 'card',
scroll: 'vertical',
items: [rpc.views.About.index],
dockedItems: [{ xtype: 'toolbar',
title: 'RockPointe Church | Mobile'
}],
listeners: {
activate: function () {
if (rpc.stores.AboutStore.getCount() === 0) {
rpc.stores.AboutStore.load();
}
}
}
});
View
rpc.views.About.index = new Ext.DataView({
id: 'rpc-views-about-index',
itemSelector: 'div.about-index',
tpl: '<tpl for="."><div class="about-index">{html}</div></tpl>',
store: rpc.stores.AboutStore,
fullscreen: true,
scroll: 'vertical'
});
Store
rpc.stores.AboutStore = new Ext.data.Store({
id: 'rpc-stores-aboutstore',
model: 'rpc.models.AboutModel',
autoLoad: true,
proxy: {
type: 'scripttag',
url: WebService('About', 'Index'),
method: 'GET',
reader: {
type: 'json',
root: 'results'
},
afterRequest: function (request, success) {
if (success) {
console.log("success");
} else {
console.log("failed");
}
console.log(request);
}
}
});
rpc.stores.AboutStore.proxy.addListener('exception', function (proxy, response, operation) {
console.log(response.status);
console.log(response.responseText);
});
Model
rpc.models.AboutModel = Ext.regModel('rpc.models.AboutModel', {
fields: ['html']
});
JSON
mycallback({"results":{"html":"... content removed for brevity ..."},"success":true});
Can anyone see what I might be doing wrong here?
There are no console/javascript errors. And the resources are showing that I am in fact pulling down the JSON from the WebService.
If I use console.log(rpc.stores.AboutStore.getCount()); inside my activate listener on the AboutController, the result is always 0, and I'm not entirely sure why
here's the staging app if you'd like to see the request
http://rpcm.infinitas.ws/ (note, this link will expire at some point)

Try returning your json value as an array instead of an object. I think Ext is expecting an array of records instead of just one.
For example
"{results : [{"html": "Your html"}]}"

Related

Using a custom Drop Down List field to set a value in a grid

I'm trying to use the Rally 2.1 SDK to set a custom data field (c_wsjf) in a grid. I have a custom drop down list that I want to check the value of (c_TimeCrticalitySizing).
I created c_TimeCrticalitySizing as a feature card field in my Rally workspace with different string values (such as "No decay"). Every drop down list value will set the custom field to a different integer. When I try to run the app in Rally I get this error:
"Uncaught TypeError: Cannot read property 'isModel' of undefined(…)"
I'm thinking the drop down list value may not be a string.
How would I check what the type of the drop down list value is?
How could I rewrite this code to correctly check the value of the drop down list so I can set my custom field to different integers?
Here's my code block for the complete app. I'm still trying to hook up a search bar so for now I directly call _onDataLoaded() from the launch() function.
// START OF APP CODE
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
featureStore: undefined,
featureGrid: undefined,
items: [ // pre-define the general layout of the app; the skeleton (ie. header, content, footer)
{
xtype: 'container', // this container lets us control the layout of the pulldowns; they'll be added below
itemId: 'widget-container',
layout: {
type: 'hbox', // 'horizontal' layout
align: 'stretch'
}
}
],
// Entry point of the app
launch: function() {
var me = this;
me._onDataLoaded();
},
_loadSearchBar: function() {
console.log('in loadsearchbar');
var me = this;
var searchComboBox = Ext.create('Rally.ui.combobox.SearchComboBox', {
itemId: 'search-combobox',
storeConfig: {
model: 'PortfolioItem/Feature'
},
listeners: {
ready: me._onDataLoaded,
select: me._onDataLoaded,
scope: me
}
});
// using 'me' here would add the combo box to the app, not the widget container
this.down('#widget-container').add(searchComboBox); // add the search field to the widget container <this>
},
// If adding more filters to the grid later, add them here
_getFilters: function(searchValue){
var searchFilter = Ext.create('Rally.data.wsapi.Filter', {
property: 'Search',
operation: '=',
value: searchValue
});
return searchFilter;
},
// Sets values once data from store is retrieved
_onDataLoaded: function() {
console.log('in ondataloaded');
var me = this;
// look up what the user input was from the search box
console.log("combobox: ", this.down('#search-combobox'));
//var typedSearch = this.down('#search-combobox').getRecord().get('_ref');
// search filter to apply
//var myFilters = this._getFilters(typedSearch);
// if the store exists, load new data
if (me.featureStore) {
//me.featureStore.setFilter(myFilters);
me.featureStore.load();
}
// if not, create it
else {
me.featureStore = Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem/Feature',
autoLoad: true,
listeners: {
load: me._createGrid,
scope: me
},
fetch: ['FormattedID', 'Name', 'TimeCriticality',
'RROEValue', 'UserBusinessValue', 'JobSize', 'c_TimeCriticalitySizing']
});
}
},
// create a grid with a custom store
_createGrid: function(store, data){
var me = this;
var records = _.map(data, function(record) {
//Calculations, etc.
console.log(record.get('c_TimeCriticalitySizing'));
var timecritsize = record.get('c_TimeCriticalitySizing');
//console.log(typeof timecritsize);
var mystr = "No decay";
var jobsize = record.get('JobSize');
var rroe = record.get('RROEValue');
var userval = record.get('UserBusinessValue');
var timecrit = record.get('TimeCriticality');
// Check that demoniator is not 0
if ( record.get('JobSize') > 0){
if (timecritsize === mystr){
var priorityScore = (timecrit + userval + rroe) / jobsize;
return Ext.apply({
c_wsjf: Math.round(priorityScore * 10) / 10
}, record.getData());
}
}
else{
return Ext.apply({
c_wsjf: 0
}, record.getData());
}
});
// Add the grid
me.add({
xtype: 'rallygrid',
showPagingToolbar: true,
showRowActionsColumn: true,
enableEditing: true,
store: Ext.create('Rally.data.custom.Store', {
data: records
}),
// Configure each column
columnCfgs: [
{
xtype: 'templatecolumn',
text: 'ID',
dataIndex: 'FormattedID',
width: 100,
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'WSJF Score',
dataIndex: 'c_wsjf',
width: 150
},
{
text: 'Name',
dataIndex: 'Name',
flex: 1,
width: 100
}
]
});
}
});
// END OF APP CODE
The app works great until I add the if (timecritsize === mystr) conditional.
I also use console.log() to check that I've set all values for timecritsize to "No decay"

Sencha List does not appear when trying to add() it to pabel

This is really wired. I have a tab in a TabPanel that I want to refresh every time the user taps it. In the tab there should be a list of things. when i am trying to add the list to the panel(the tab container), it is just do not appear! when i try to add other things they aper normally!
For example:
var listConfiguration = this.getListConfiguration();
var myPanel = Ext.create('Ext.Panel', {
html: 'This will be added to a Container'
});
Ext.getCmp('Peoplebutton').add(listConfiguration);
Ext.getCmp('Peoplebutton').add(myPanel);
This code gets the html perfectly in the place! but the list is not shown! The list code is working fine, I have checked it several times...
I would be very happy if someone can help me (:
The list code, working fine for sure
getListConfiguration: function() {
var store = Ext.create('Ext.data.Store', {
fields: ['firstName', 'lastName'],
sorters: 'firstName',
autoLoad: true,
grouper: {
groupFn: function(record) {
return record.get('firstName')[0];
}
},
proxy: {
type: 'ajax',
url: 'contacts.json'
}
});
return {
xtype: 'list',
id: 'list',
itemTpl: '{firstName} ,{lastName}',
grouped: true,
indexBar: true,
infinite: true,
useSimpleItems: true,
variableHeights: true,
striped: true,
ui: 'round',
store: store
};
}
It should be an issue with the height of the list component.
Try adding a fixed height to the list, or maybe flex: 1.
Hope it helps-

Sencha touch: JSONP parsing

Model:
app.models.Category = Ext.regModel("Category", {
fields: [
{ name: 'CategoryId', type: 'int' },
{ name: 'ImageUrl', type: 'string' },
{ name: 'ImageUrlFile', type: 'string' },
{ name: 'CategoyName', type: 'string' }
]
});
Storage:
app.stores.CategoryStore = new Ext.data.Store({
id: 'CategoryStore',
model: 'Category',
autoLoad: true,
proxy: {
type: 'scripttag',
url: 'http://localhost:1303/admin/categoriesservice/getcategories',
mehod: 'GET', //not needed
callbackKey: 'callback', //not needed
reader: {
type: 'json',
root: 'categories'//not needed with my JSONP
},
afterRequest: function (request, success) {
console.log("afterRequest");
if (success) {
console.log("success");
} else {
console.log("failed");
}
console.log(request);
}
}
});
Controller:
Ext.regController('Home', {
index: function () {
if (!this.indexView) {
this.indexView = this.render({
xtype: 'HomeIndex'
});
this.items = [app.views.HomeIndex];
}
app.viewport.setActiveItem(this.indexView);//this what i've missed
}
});
View
app.views.HomeIndex = Ext.extend(Ext.DataView, {
html: '<div class="gallery-view" style="display: block;width: 300px;border: 1px solid #fff;height: 300px;"></div>',
store: app.stores.CategoryStore, //full namespace needed
itemSelector: 'div.node',
initComponent: function () {
this.tpl = new Ext.XTemplate(
'<div style="padding:10px 5px 5px 5px;">',
'<tpl for=".">',
'<div class="node" style="background:url({ImageUrl});">',
'</div>',
'</tpl>',
'</div>'
);
//appened to successful solution
this.dataView = new Ext.DataView({
store: this.store,
tpl: this.xtpl,
itemSelector: 'div.node'
});
this.items = [this.dataView];
app.views.HomeIndex.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('HomeIndex', app.views.HomeIndex);
JSONP Result:
GetCategories([{"CategoryId":101,"CategoyName":"אוכל","ImageUrl":"http://www.teleclal.com/YnetApplicationMall/Content/images/categories/rest.png","ImageUrlFile":null,"InsertDate":"\/Date(1314507534000)\/","IsActive":true,"ApplicationId":0,"Applications":null},{"CategoryId":99,"CategoyName":"הצגות ומופעים","ImageUrl":"http://www.teleclal.com/YnetApplicationMall/Content/images/categories/shows.png","ImageUrlFile":null,"InsertDate":"\/Date(1314442037000)\/","IsActive":true,"ApplicationId":100,"Applications":null},{"CategoryId":111,"CategoyName":"בריאות","ImageUrl":"http://www.teleclal.com/YnetApplicationMall/Content/images/categories/spa.png","ImageUrlFile":null,"InsertDate":"\/Date(1314856845000)\/","IsActive":true,"ApplicationId":0,"Applications":null},{"CategoryId":142,"CategoyName":"נופש ותיירות","ImageUrl":"http://www.teleclal.com/YnetApplicationMall/Content/images/categories/vacation.png","ImageUrlFile":null,"InsertDate":"\/Date(1314713031000)\/","IsActive":true,"ApplicationId":0,"Applications":null},{"CategoryId":143,"CategoyName":"ביגוד","ImageUrl":"http://www.teleclal.com/YnetApplicationMall/Content/images/categories/clothes.png","ImageUrlFile":null,"InsertDate":"\/Date(1314713031000)\/","IsActive":true,"ApplicationId":0,"Applications":null},{"CategoryId":144,"CategoyName":"אתרים ואטרקציות","ImageUrl":"http://www.teleclal.com/YnetApplicationMall/Content/images/categories/attraction.png","ImageUrlFile":null,"InsertDate":"\/Date(1314713031000)\/","IsActive":true,"ApplicationId":0,"Applications":null},{"CategoryId":105,"CategoyName":"חשמל","ImageUrl":"http://www.teleclal.com/YnetApplicationMall/Content/images/categories/elctronic.png","ImageUrlFile":null,"InsertDate":"\/Date(1314713031000)\/","IsActive":true,"ApplicationId":0,"Applications":null}]);
The exception:
Uncaught TypeError: Cannot read property 'length' of undefined
Question:
Help how can i parse via storage or any other way the JSONP issue???
You have set this in your reader
reader: {
type: 'json',
root: 'categories'
}
And I can't see categories element in your json data. Check if this is correct or add this to your json in order to be working probably
{"categories":[ ...//old json //..]}
when I tried to define
function GetCategories(data){console.log(data);}
and then invoking the jsonp response (by ctrl+c/ctrl+v into the console), I was successful, meaning the the data is a valid json string.
but when I inspected your code, I haven't seen a mechanisem that defines that function (GetCategories).
I must say that i'm unfamilier with sencha. but I aswsome that problem is that no callback function was ever created.
I see that you define a 'callbackKey: 'callback''
is there somewhere in sencha documentation that allows you to define a 'callbackValue: 'GetCategories'' or such? try and check into that direction.
Try removing "autoLoad: true" from your code. It resolved my issues on the same matter as yours.

ExtJS 4: Properly set waitMsgTarget using MVC pattern

I have extjs 4.0 controller:
Ext.define('KS.controller.DailyReport', {
extend: 'Ext.app.Controller',
views: ['report.Daily'],
init: function() {
this.control({
'dailyReport button[action=send]': {
click: this.sendDailyReport
}
});
},
sendDailyReport: function(button) {
var win = button.up('window');
form = win.down('form');
form.getForm().waitMsgTarget = form.getEl();
form.getForm().waitMsg = 'Sending...';
if (form.getForm().isValid()) { // make sure the form contains valid data before submitting
form.submit({
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result.msg);
}
});
} else { // display error alert if the data is invalid
Ext.Msg.alert('Invalid Data', 'Correct them!')
}
}
});
and extjs view:
Ext.define('KS.view.report.Daily', {
extend: 'Ext.window.Window',
alias: 'widget.dailyReport',
title: 'Daily report',
layout: 'fit',
autoShow: true,
initComponent: function() {
this.items = [{
waitMsgTarget: true,
xtype: 'form',
url: 'dailyReport.php',
layout: 'fit',
waitMsgTarget: true,
waitMsg: 'Sending...',
items: [{
margin: 10,
xtype: 'datefield',
name: 'reportDate',
fieldLabel: 'Report for:',
format: 'd.m.Y.',
altFormats: 'd.m.Y|d,m,Y|m/d/Y',
value: '12.12.2011',
disabledDays: [0]
}]
}];
this.buttons = [{
text: 'Send',
action: 'send'
},
{
text: 'Cancel',
scope: this,
handler: this.close
}];
this.callParent(arguments);
}
});
As you can see I tried to set waitMsgTarget and waitMsg in both places but it is not appearing when I click Send button.
What is wrong?
You are really just misusing waitMsg in the following ways:
waitMsg is not a config option of Ext.form.Basic OR Ext.form.Panel. The waitMsg must be set within your Ext.form.action.Submit. This is why setting it in the view will never work.
In your controller you are doing the same thing and setting the waitMsg as if it were a property of Ext.form.Basic.
The fix is simple. Set waitMsg in your Ext.form.action.Submit. So, just change the line(s) within form.submit() to something like:
form.submit({
waitMsg: 'Sending...',
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
//..... your other stuff here
});
and remove these lines from the controller:
form.getForm().waitMsgTarget = form.getEl();
form.getForm().waitMsg = 'Sending...';
and for completeness remove these 2 line from the view (you have waitMsgTarget in there twice):
waitMsgTarget: true,
waitMsg: 'Sending...',
NOTE: To define the waitMsgTarget to something other than the form itself you must pass in the id of the target.
For example, in your view (ie form definition) you would want to change waitMsgTarget: true to:
waitMsgTarget: 'myWindowID',
//where myWindowID is the id of the container you want to mask
For reference, see:
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.action.Submit and
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.Basic

sencha touch search form

I really hope someone can help me, It seems like this should be obvious but sencha documentation isn't very easy to read and incomplete. I am trying to build a search form but it doesnt seem to take the store or the url and I can't figure out how to add parameters like page? Can anyone help? This code just produces Failed to load resource: null.
var searchField = new Ext.form.Search({
value:'Search',
url: 'someurl',
store: this.data_store,
cls:'searchfield',
listeners: {
focus: function(){ searchField.setValue(''); },
blur: function(){ if( searchField.getValue()=='' ){ searchField.setValue('Search'); } },
success: function(e){
console.log(e);
}
}
});
this.dockedItems = [ searchField ];
Ext.form.FormPanel doesn't take a Ext.data.Store or Ext.data.Model directly but does deal with Instances of Ext.data.Model. Lets say you have the following model:
Ext.regModel('MyForm', {
fields: [{name: 'id', type: 'int'},'name','description']
proxy: {
type: 'ajax',
url: 'url_to_load_and_save_form'
}
})
Now your form definition would look something like this:
Ext.form.MyForm = Ext.extend(Ext.form.FormPanel, {
record : null,
model: 'MyForm',
items: [{
xtype: 'hidden',
name: 'id'
},{
xtype: 'textfield',
name: 'name',
allowBlank: false
},{
xtype: 'textarea',
name: 'description'
}],
submit : function(){
var record = this.getRecord() || Ext.ModelMgr.create({}, this.model);
this.updateRecord(record , true);
record.save({
scope: this,
success : function(record, opts){
this.fireEvent('saved', record);
},
callback: function(){
this.setLoading(false);
}
});
}
});
Ext.reg('MyForm',Ext.form.MyForm);
Of course you should add in some validations and a button to actually call the Ext.form.MyForm.submit method.