which is the bestway to write sencha touch code? - sencha-touch-2

Ext.define('App.view.Main', {
extend: 'Ext.Container',
xtype: 'mainview',
requires: [
'App.view.Main1',
'App.view.Menu2',
'App.view.My1',
'App.view.My2',
'App.view.Form'
],
config: {
items: [
{
xtype: 'file1'
},
{
xtype: 'file2',
hidden: true
},
{
xtype: 'file3',
hidden: true
},
{
xtype: 'file4',
hidden: true
},
{
xtype: 'file5',
hidden: true
},
{
xtype: 'file6',
hidden: true
},
{
xtype: 'file7',
hidden: true
}
]
}
});
In the above code Main file is mainview and I am doing hiding all those xtypes and showing what i want. But it is very difficult to maintain project for hiding and showing.
In my project i have a view files of morethan 30.
Is there any way to add files whatever i want without this hide and show?

If your views are relatively similar, you should create them programmatically. So follow these steps:
Create your main view with no items, give it an id, says "main-view".
Place this function somewhere you feel suitable:
addItemsToMainView: function(numberOfFiles){
var mainView = Ext.getCmp('main-view');
for (var i=1; i<= numberOfFiles; i++){
var xtypeName = "file" + i.toString();
mainView.add({xtype: xtypeName, id: i.toString()});
}
// if you want to show and hide all of them
for (var i=1; i<= numberOfFiles; i++){
Ext.getCmp(i.toString()).hide();
// or Ext.getCmp(i.toString()).show();
}
}
The above code snippet is just an example but I believe you can get an idea of how it works.
Hope this helps.

Related

Populate custom component with store

Im trying to populate a custom component using a store (actually a store with local data) in a Sencha Touch 2 project.
My idea is to create one custom component for each element in the store, but actually nothing happens.
I have tried several things but anything works, could you help me? I have done an example to show the problem:
model:
Ext.define('project.model.city', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'country', type: 'string'},
{name: 'city', type: 'string'}
]
}
});
store:
Ext.define('project.store.cities', {
extend: 'Ext.data.Store',
requires: ['project.model.city'],
model: 'project.model.city',
autoLoad: true,
data: [
{ country: 'Germany', city: 'Berlin' },
{ country: 'Italy', city: 'Rome' }
]
});
View with store:
Ext.define('project.view.cityAll', {
extend: 'Ext.Panel',
xtype: 'cityAllView',
config: {
items:[{
xtype: 'cityItemView',
store: 'project.store.cities',
}]
}
});
Custom component View:
Ext.define('project.view.cityItem', {
extend: 'Ext.Panel',
xtype: 'cityItemView',
config: {
items: [{
itemTpl: '{city}'
}]
}
});
You need to assign store to cityItemView instead of cityAllView. cityItemView is having template specified and needs to be loaded with data.
Ext.define('project.view.cityItem', {
extend: 'Ext.Panel',
xtype: 'cityItemView',
config: {
items: [{
xtype:'list',
itemTpl: '{city}'
store:'project.store.cities'
}]
}
});
If you want to set data into panel, then you'd need to call setData(). A panel can not load data from store directly. You can use list view instead so show city, country pair. cityView no longer needed store property that way.
Give this a try.
You can add load listener in store which would loop through records and create as many panels:
listeners : {
load: function( me, records, successful, operation, eOpts ){
var plist = [];
var cv = Ext.Create('project.view.cityAll');
if(successful){
var data = records[i].getData();
for(var i=0; i<records.length; i++){
plist.push({
xtype : 'cityItemView',
data : data
});
}
cv.add(plist);
}
// Now add cv to viewport or wherever you want
}
}
You have to change cityItemView to use data whichever way you want. If you are using initialize method you can access it like this.config.data

Passing view with close button

I want the close button to be reusable so I created its own class so I can attach it to the views that need it. I want to just be able to pass the view that is attached to the view to the controller to close that view. It should be fairly simple and I would suspect that this is how many do it but I can't get it to work correctly. I get it to close the view but get the error
Uncaught TypeError: Cannot read property 'dom' of null
I understand this to generally mean that the view isn't being destroyed but I thought this told it to destroy the view:
Ext.Viewport.remove(curView, true);
Here is what I believe to be the pertinent code
Controller:
closeView: function(btn, e,opts){
var curView = btn.getParent().getParent();
console.log('From btn: ' + curView + ',' + opts);
Ext.Viewport.remove(curView, true);}
View:
Ext.define('SenchaFirstApp.view.DetailView',{
extend: 'Ext.tab.Panel',
requires: ['Ext.Toolbar', 'Ext.tab.Panel', 'Ext.form.FieldSet', 'Ext.field.Select'],
model: ['SenchaFirstApp.model.Details', 'SenchaFirstApp.model.SiteInfo'],
alias: 'widget.detailview',
// xtype: 'tabpanel',
config:
{
scrollable: true,
width: 1500,
height: 800,
// fullscreen: true,
layout: {type: 'card', animation:{type: 'flip'}},
centered: true,
border: 10,
tabBar: {
docked: 'top',
},
formParams: {
},
items:
[
{
//Tab bar
xtype: 'tbar',
title: 'Details View',
items: [
{
xtype: 'closebtn',
id: 'detailsBtn',
sourceForm: this
}]
},
{
title: 'Equipment Monitor', //first tab
xtype: 'monitor',
},
{
title: 'Site Information', //second tab
xtype: 'siteinfo',
}
]
} //End Config
I tried to use
Ext.Viewport.remove(Ext.Viewport.getActiveItem, true)
but that also didn't work. I suspect that has to do with how I created that view maybe. I'm new to Sencha so there could be many things I'm doing wrong so I appreciate the help.
I forgot to mention that, after closing the tab panel, I can't open it again without refreshing which again I'm sure is due to the view not being destroyed
It appears that the problem was using id's. I thought that I took them out but I guess not. I took the id's out and used alias's and got it working. I'm still not figuring out how to pass the view attached to the button but now
Ext.Viewport.remove(Ext.Viewport.getActiveItem, true)
is working. The true property tells it to destroy the view after removing it.

ExtJS RowExpander - nextBd is null

I have problem configuring RowExpander for my grid. When the grid renders the expander is already opened for each row and with nothing inside. When i click on its icon the following error is generated: nextBd is null. I found very similar problem here http://www.sencha.com/forum/showthread.php?185837-Grid-Panel-PlugIn-Rowexpander-nextBd-is-null but the solution does not work for me and still dont get it why plugin config cannot be passed in initComponent method:
Here is my grid code:
Ext.define('GSIP.view.plans.PlanReqList' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.gsip_devplan_list',
id: 'gsip_plan_list',
plugins: [{
ptype: 'rowexpander',
rowBodyTpl : [
'Nazwa:{name}'
]
}],
//title:i18n.getMsg('gsip.view.PlanReqList.title'),
layout: 'fit',
initComponent: function() {
this.store = 'DevPlan';
// this.plugins = [{
// ptype: 'rowexpander',
// rowBodyTpl : [
// {name}
// ]
// }];
this.features = [{ftype:'filters', encode:false, local:true},{ftype:'grouping'}];
this.tbar = [{
xtype:'commandbutton',
id: 'newReq',
iconCls:'icon-application_add',
text: i18n.getMsg('gsip.view.plans.PlanReqList.addReq'),
command: 'newReq',
}];
this.viewConfig = {
forceFit:true,
getRowClass: function(record, index) {
var c = record.get('elapsedPercent');
if (c >= 0) {
return 'elapsed-normal';
}
}
}
this.columns = [
{header: "Id", dataIndex: "id", width:50, sortable: true, filter:{type:'numeric'}},
{header: i18n.getMsg('gsip.view.plans.PlanReqList.column.name'), dataIndex: "name", flex:1, sortable: true, filter:{type:'string'} },
}
];
this.callParent(arguments);
},
The rowexpander plugin makes use of a feature called rowbody.
In your initComponent() you override this.features (which already includes rowbody) with this line:
this.features = [{ftype:'filters', encode:false, local:true},{ftype:'grouping'}];
Thus the rowbody feature is not included; thus the .x-grid-rowbody-tr class is not injected; thus rowexpander can't find such class for nextBd and returns null.
You should try:
var iNewFeatures = [{ftype:'filters', encode:false, local:true},{ftype:'grouping'}];
this.features = iNewFeatures.concat( this.features );
Lastly, plugins cannot be initiated in InitComponent(), you can either declare them as configs, or within the constructor. See this thread for more info.

extjs4 column hide in treepanel shared across tabs

My application (mvc) is designed as such with 3 tabs in my view
Ext.define('App.view.cube.MainView', {
extend: 'Ext.panel.Panel',
....
layout: 'card',
...
dockedItems: [{
xtype: 'panel',
items: [{
// a drop down containing 2 choices
}]
}],
items: [{
xtype: 'tabpanel',
itemId: 'mmtabs',
activeTab: 1,
items: [{
title: 'Served',
xtype: 'treepanel', // my own xtype extending this xtype
id: 'Served :',
itemId: '1'
}, {
title: 'UnServed',
xtype: 'treepanel', // my own xtype extending this xtype
id: 'UnServed :',
itemId: '0'
}, {
title: 'Total',
xtype: 'treepanel', // my own xtype extending this xtype
id: 'Total :',
itemId: '2'
}]
}]
});
Basically a drop down with two choices should allow the user to view the required columns within the grid (treepanel). The very first time the app is loaded and the user changes to a different choice in the dropdown the columns do not hide as they should. But if he were to navigate to another tab and then do the same thing everything works as it is supposed to. I cannot figure out the problem.
In the code above i am reusing
xtype : 'treepanel', // my own xtype extending this xtype
across the three tabs by having different itemIds ( i hope this is fine ).
In my controller i have a function to toggle to the view (hide/show specific columns)
initialview (iterate over all columns in all tabs and set the appropriate view)
changeview invoked on the combobox within my view.
toggleView: function (cubemwwar, viewId) {
if ("2" == viewId) {
cubemwwar.columns[1].setVisible(false);
cubemwwar.columns[2].setVisible(false);
cubemwwar.columns[3].setVisible(false);
cubemwwar.columns[4].setVisible(true);
cubemwwar.columns[5].setVisible(true);
cubemwwar.columns[6].setVisible(true);
}
if ("1" == viewId) {
cubemwwar.columns[1].setVisible(true);
cubemwwar.columns[2].setVisible(true);
cubemwwar.columns[3].setVisible(true);
cubemwwar.columns[4].setVisible(false);
cubemwwar.columns[5].setVisible(false);
cubemwwar.columns[6].setVisible(false);
}
}, // on controller's onlaunch
initialView: function () {
var numTabs = this.getCubeMainView().query('#mmtabs')[0].items.length;
for (var i = 0; i < numTabs; i++) {
var tab = this.getCubeMainView().query('#mmtabs')[0].items.items[i];
this.toggleView(tab, 1);
}
},
// change views based on user selection
// from the combobox's select event
changeView: function (combo, rec, idx) {
// first time somehow the columns do not hide
// hide/show appropriate columns
// rec[0].data.id .. .possible values 1 and 2 only.
this.toggleView(this.getCubeMainView().query('#mmtabs')[0].getActiveTab(), rec[0].data.id);
},
On startup I iterated over all the tabs set them to active then set the first one back to active. That had solved this problem.
for(var i=0;i<numTabs ; i++)
{
var tab = tabPanel.items.items[i];
this.toggleView(tab,1);
tabPanel.setActiveTab(i);
}
tabPanel.setActiveTab(0);
this.startingup = false;

ExtJS 4 PagingToolbar throwing dom errors on subsequent page loads

I'm fairly new to ExtJS, but have been able to get a GridPanel working with an associated paging toolbar. Everything works fine, until I close the popped up window and open another one. On the subsequent window loads, I get a "me.dom is undefined" error. If I remove the paging toolbar, everything works fine. I'm using version 4.0.7.
Thanks in advance.
Store definition:
Ext.define('VIMS.store.TOs',{
extend:'Ext.data.Store',
model:'VIMS.model.TO',
requires: 'VIMS.model.TO',
sorter:{property:'StartDate', direction:'DESC'},
buffered: true,
pageSize: 10,
listeners:{
beforeload: function(store,options) {
if(options.params && options.params.id){
store.getProxy().extraParams.id = options.params.id;
}
},
},
});
GridPanel definition:
Ext.define('VIMS.view.TaskOrderList' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.taskorderlist',
title : 'Task Orders',
store: 'TOs',
requires:'Ext.toolbar.Paging',
height:'100%',
columnLines:true,
/* removed this code ---------------------------------------
dockedItems :[{
xtype: 'pagingtoolbar',
store: 'TOs', // same store GridPanel is using
pageSize:10,
dock: 'bottom',
displayInfo: false,}],
-------------------------------------------- */
initComponent: function() {
this.columns = [
{header: 'Description', dataIndex: 'Description', flex: 1},
. . .
{header: 'Id', dataIndex: 'TaskOrderId', hidden:true},
];
// added from here ---------------------------------
var PagingBar = new Ext.PagingToolbar({
pageSize: 10,
store: 'TOs',
displayInfo: true,
});
this.bbar = PagingBar;
// to here ---------------------------------------
this.callParent(arguments);
}
});
To open the window, from my controller I use the following:
var view = Ext.widget('contractedit');
view.modal = true;
view.down('form').loadRecord(record);
The close is handled via the following:
closeMe: function(button) {
var win = button.up('window');
win.close();
},
you have an extra trailing comma that maybe getting in the way:
displayInfo: false,
also how r u managing the window?