Using extjs 4 I get an error when attempting to use a view in my viewport. I think it is an issue with how the view is defined/where it is included. However, I can';t find what I've done wrong. I know this is an easy mistake, I just don't see it. I'll post the code below. Error is
TypeError: name is undefined
View I want to use:
Ext.define('MC.view.SideBar', {
extend: 'Ext.Container',
alias: 'widget.SideBar',
items:[
{ xtype: 'panel',
bodyPadding: 5,
html:'facebook'
},
{ xtype: 'panel',
bodyPadding: 5,
html:'twitter?'
}
]
//... more configuration ...
});
Viewport
Ext.create('Ext.container.Viewport', {
layout: {
//align:'center',
pack:'center',
type:'hbox',
align:'stretch',
border:true
},
items: [
{xtype:'panel',
layout:{
type:'vbox',
align:'stretch',
pack:'start'
},
border:true,
width: '80%',
items:[
{xtype:'panel',
border:true,
flex:2,
//width:'100%',
html:'toolbar/logo'
},
{xtype:'panel',
border:true,
flex:8,
layout:{
type:'hbox',
align:'stretch',
pack:'start'
},
items: [
//{xtype:'SideBar'},
**{xtype:'SideBar',**
flex:22,
height:'100%'
},
{xtype:'panel',
flex:88,
height:'100%'
}
],
html:'lower'
}
]
}
]
});
Controller where views are referenced
Ext.define('MC.controller.Monolith', {
extend: 'Ext.app.Controller',
views: [
'TopBar', 'SideBar'
],
init: function() {
console.log('Initialized Monolith controller! This happens before the Application launch function is called');
}
});
Finally the application file
Ext.application({
name: 'MC',
//appFolder: 'app',
autoCreateViewport: true,
controllers: [
'Monolith'
],
//models: [],
//stores: [],
launch: function() {
console.log('mesacart');
// This is fired as soon as the page is ready
}
});
I've tried everything I can think of, but it must be simple since there isnt much code here yet....
For views and controllers you don't need to specify their 'MC.controller' and 'MC.view' prefix when declaring them.
So you end up with:
views: [
'TopBar', 'SideBar'
],
and so on.
EDIT:
when you ask to auto create the viewport you need to define a viewport class as MC.view.Viewport
See your full code example in jsfiddle:
http://jsfiddle.net/dbrin/qW4hR/
Ext.define('MC.view.Viewport', {
extend: 'Ext.container.Viewport',
layout: {...}
Related
I am using the lastest sencha cmd for the build with ext-5.0.1.
Everythings look good during the development status (http://www.imageupload.co.uk/5Med) but after the build.
All the textfields collapsed like shown (http://www.imageupload.co.uk/5MeQ), and have no response to the changes in width, minWidth, flex... etc.
And also the properties y and x are not functioning.
If someone had had similar situation before, please help, thx
My cmd is v5.0.3.324
Here are part of my code:
In my Main.js:
Ext.define('ExtTest2.view.main.Main', {
extend: 'Ext.container.Container',
requires: [
'ExtTest2.view.main.MainController',
'ExtTest2.view.main.MainModel'
],
xtype: 'app-main',
controller: 'main',
viewModel: {
type: 'main'
},
layout: {
type: 'fit'
},
itemId:'Stage'
});
MainController.js:
Ext.define('ExtTest2.view.main.MainController', {
extend: 'Ext.app.ViewController',
requires: [
],
alias: 'controller.main',
init: function(){
this.Start();
},
Start: function(){
var data = {
itemId: "Page_Login",
xtype: "panel",
items: [
{
padding: 30,
layout:{
type: 'vbox',
align: 'center'
},
xtype: "fieldset",
y: "30%",
height: 150,
items: [
{
xtype: "textfield",
itemId: "Textfield_Username",
fieldLabel: "用戶名稱",
labelStyle: "color:#FFFFFF"
},
{
fieldLabel: "密碼",
itemId: "Textfield_Password",
labelStyle: "color:#FFFFFF",
xtype: "textfield"
},
{
itemId: "Button_Login",
text: "登入",
width: 100,
xtype: "button"
}
]
}
]
};
var container = Ext.ComponentQuery.query('#Stage')[0];
container.removeAll();
container.add(data);
container.updateLayout();
}
});
It is overnested because you add unnecessary container to app-main containing the fields.
It is very unusual to manipulate views from view controller like that - create a class for the fieldset, give it an alias (xtype) and simply instantiate that. Cramming controller handlers together with view definitions shall inevitably lead to Spaghetti Code.
You use vbox layout, without any flex or height to hold form fields. Form fields behave best in anchor layout that is the default for Ext.form.Panel.
I am trying to create a framework UI that creates container contents based on configs, and I get an error "TypeError: item.onAdded is not a function".
This does not happen in my smaller test app, but it does happen in our actual app. Can't figure out why.
Here is some partial code.
Ext.define('atlas.screen.Viewport', {
extend: 'Ext.container.Viewport',
alias: 'widget.atlas.Viewport',
autoScroll: true,
layout: 'fit',
requires: [
'base.framework.MainAppView',
'base.framework.MainAppNavigation'
],
items: [{
// MainAppView requires providing config with items to populate the north,
// west, and center regions.
xtype: 'mainAppView',
westItems: [{
xtype: 'mainAppNavigation'
}]
}]
});
Ext.define('base.framework.MainAppView', {
extend: 'Ext.container.Container',
alias: 'widget.mainAppView',
requires: ['base.util.CommonBaseUtil'],
autoScroll: true,
layout: 'border',
westItems: null,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'container',
itemId: 'appWestContainer',
region: 'west',
width: 85,
items: me.westItems,
hidden: true,
listeners: {
afterrender: CommonBaseUtil.showHide
}
}]
});
me.callParent(arguments);
},
applyWestItems: function(westItems) {
this.down('#appWestContainer').add(westItems);
}
});
Ext.define('base.framework.MainAppNavigation', {
extends: 'Ext.container.Container',
alias: 'widget.mainAppNavigation',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'button',
itemId: 'myButton',
text: 'test'
}]
});
me.callParent(arguments);
}
});
It was one of my favorite BS ExtJS issues, "extends" VS "extend". You would think Sencha Cmd could catch this.
I'm trying to create a view for toolbar in sencha and import it to my file but it keeps on throwing
Uncaught TypeError: Object [object Object] has no method 'getId'
Tell me what I am doing wrong.
I guess it is not allowed to create a view for toolbar only.
view/mainTool.js
Ext.define('test.view.mainTool',{
requires:['Ext.field.Search'
,'Ext.Toolbar'
],
config:{docked:'top',
ui:'normal',
items:[
{
xtype: 'searchfield',
placeHolder: 'Search...',
left: true,
id:'mainSearch',
width: 200,
},
{
xtype:'button',
ui:'action',
text:'filter',
id:'filter'
},
{xtype:'spacer'},
{
xtype:'button',
ui:'action',
text:'showOnMap',
id:'showOnMap'
},
{
xtype:'button',
ui:'action',
iconCls:'arrow_left',
id:'back'
},
{
xtype:'button',
ui:'action',
iconCls:'home',
id:'home'
}
]
}
});
app.js
Ext.application({
requires: [
'Ext.dataview.List',
'Ext.Panel',
'Ext.Spacer',
'test.view.list',
'test.view.mainTool',
'Ext.List',
'test.model.list1model',
'test.store.list1store'
],
launch : function(){
list1 =Ext.create('test.view.list');
list2 =Ext.create('test.view.list');
list2.setHidden(true);
maintool=Ext.create('test.view.mainTool');
Ext.create('Ext.Container',{
id:'contain',
layout:'hbox',
fullscreen:true,
items:[
maintool,
list1,
{xtype:'spacer'},
list2
]
})
}
});
You forgot to add extend: 'Ext.Toolbar' to your test.view.mainTool class. Do not forget, simply defining a class without extending an Ext component does not create a valid Ext View.
I cannot figure out how to show my Ext.dataview.List object inside of another object. If I try to show the Ext.dataview.List object in the viewport, by itself, I can see my data. But if I try to include it as a component inside of another component, it thinks there is no data (judging from the HTML output), and doesn't appear to display anything.
So, if I have an app.js with the following code:
Ext.application({
name: 'MobileUnion',
views: ['LocalsList'],
models: ['Local'],
stores: ['Locals'],
launch: function() {
// Initialize the main view
var mainView = {
xtype: 'localslist'
};
Ext.Viewport.add([mainView]);
}
});
I can set up MobileUnion.view.LocalsList this way, which results in no list:
Ext.define('MobileUnion.view.LocalsList', {
extend: 'Ext.Container',
alias: 'widget.localslist',
requires: 'Ext.dataview.List',
config: {
items: [
{
itemId: 'localsList',
store: 'Locals',
loadingText: 'Loading Locals...',
emptyText: '<div>No locals found.</div>',
onItemDisclosure: true,
itemTpl: '<div>{localName}</div><div>{designation}</div>'
}
]
}
});
Or, I can set it up this way, which results in a populated list, but not inside of another component:
Ext.define('MobileUnion.view.LocalsList', {
extend: 'Ext.dataview.List',
alias: 'widget.localslist',
config: {
itemId: 'localsList',
store: 'Locals',
loadingText: 'Loading Locals...',
emptyText: '<div>No locals found.</div>',
onItemDisclosure: true,
itemTpl: '<div>{localName}</div><div>{designation}</div>'
}
});
The reason I am trying to pull this off is so that I can get a list component to display inside of a tab panel.
Note: I have assembled a Fiddle with everything, here: http://www.senchafiddle.com/#6nCH8
I must be missing something basic, but at this point, having gone through the documentation, and purchased two books, one of which I've read fully, and the other of which I am reading while coding, I am still without an answer. Any help would be most greatly appreciated.
Additional Code
app/model/Local.js
Ext.define('MobileUnion.model.Local', {
extend: 'Ext.data.Model',
config: {
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
{ name: 'dateCreated', type: 'date', dateFormat: 'c' },
{ name: 'localName', type: 'string' },
{ name: 'designation', type: 'string' }
],
}
});
app/store/Locals.js
Ext.define('MobileUnion.store.Locals', {
extend: 'Ext.data.Store',
requires: ['MobileUnion.model.Local'],
config: {
model: 'MobileUnion.model.Local',
data: [
{ localName: 'ABCD', designation: '123' },
{ localName: 'WXYZ', designation: '456' }
],
autoLoad: true,
sorters: [{ property: 'dateCreated', direction: 'DESC'}]
}
});
In option 1, you define a container but you actually don't add items to you container. To add your list to the container, add xtype: 'list' to your items array. Next thing you have to do is to set the containers layout to fit, otherwise the list won't show up. This should work for you:
Ext.define('MobileUnion.view.LocalsList', {
extend: 'Ext.Container',
alias: 'widget.localslist',
requires: 'Ext.dataview.List',
config: {
layout: {
type: 'fit' //set containers layout
},
items: [
{
xtype: 'list', //add xtype
itemId: 'localsList',
store: 'Locals',
loadingText: 'Loading Locals...',
emptyText: '<div>No locals found.</div>',
onItemDisclosure: true,
itemTpl: '<div>{localName}</div><div>{designation}</div>'
}
]
}
});
More about layouts in Sencha: http://docs.sencha.com/touch/2-1/#!/guide/layouts
Good luck!
I have got the tabpanel - it's the main form (view).
In this tabpanel I define the different tabs - xtype:'panel'.
So, I have one main(controller) , main view and some tabs views.
The tab's views are referenced in main view.
I want to define listener of activate event of some child's panel in main controller.
How can I do that?
the main controller :
Ext.define('KP.controller.account.apartment.Main', {
extend: 'Ext.app.Controller',
views: ['account.apartment.Main',
'account.apartment.Requisites'
],
models: ['account.apartment.Requisites'
],
stores: ['account.apartment.Requisites'
],
init: function () {
}
});
The main view:
Ext.define('KP.view.account.apartment.Main', {
extend: 'Ext.window.Window',
alias: 'widget.ApartmentData',
height: 566,
width: 950,
activeItem: 0,
layout: {
type: 'fit'
},
autoShow: false,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'tabpanel',
activeTab: 0,
deferredRender: true,
items: [
{
xtype: 'RequisitesApartment'
}
]
}
]
});
me.callParent(arguments);
}
});
The child panel RequisitesApartment (view):
Ext.define('KP.view.account.apartment.Requisites', {
extend: 'Ext.panel.Panel',
alias: 'widget.RequisitesApartment',
id: 'panel_accountrequisites',
height: 350,
width: 1124,
autoScroll: true,
layout: {
type: 'fit'
},
listeners: {
activate: function () {
....load data....
...this listeners I want to push in 'main' controller...
}
},
initComponent: function () {
var me = this;
var grid_store = Ext.create('KP.store.account.apartment.Requisites');
Ext.applyIf(me, {
dockedItems: [
{
xtype: 'gridpanel',
height: 260,
autoScroll: true,
dock: 'bottom',
store: grid_store,
id: 'r_gridFlatParams',
forceFit: true,
columns: [
...some columns....
],
viewConfig: {
}
}
]
});
me.callParent(arguments);
}
});
Register it directly as control within the responsible controller
Here is a example with a working query. For sure you just will need the query, but I think it's a good example. The custom cfg property ident make it easy find each tab. As in the example below you will have specify a tabConfig within each panel and define the ident there.
Ext.create('Ext.tab.Panel', {
width: 400,
height: 400,
renderTo: document.body,
items: [{
title: 'Foo',
tabConfig: {
ident: 'foo'
},
}, {
title: 'Bar',
tabConfig: {
ident: 'bar',
title: 'Custom Title',
tooltip: 'A button tooltip'
}
}]
});
console.log(Ext.ComponentQuery.query('tabpanel tabbar tab[ident=foo]')[0]);
console.log(Ext.ComponentQuery.query('tabpanel tabbar tab[ident=bar]')[0]);
Another way is to use css id's which can be queried like '#my-name' but I recommend to use a custom one as in the example above
Well, I should put this code in 'main'(controller):
this.control({
'ApartmentData tabpanel RequisitesApartment': {
activate: function () {
console.log('hello!');
}
}
});
The problem was in wrong selector , that I used.
The correct selector is :
'ApartmentData tabpanel RequisitesApartment'
There 'ApartmentData'(define like a alias: 'widget.ApartmentData') - is the 'window' xtype -the main form.
tabpanel - panel with tabs in 'window', and 'apartServList'(define like alias: 'widget.RequisitesApartment') - the some panel.
Thanks for sra!
the correct thing to do is to pass a config object to the member function control into controller init function. From Sencha documentation : The control function makes it easy to listen to events on your view classes and take some action with a handler function.
A quick example straight from extjs docs:
Ext.define('MyApp.controller.Users', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'viewport > panel': {
render: this.onPanelRendered
}
});
},
onPanelRendered: function() {
console.log('The panel was rendered');
}
});
Hope this helps.
Cheers