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.
Related
So I have made a simple list component view. When I tap a listing's disclosure button, I have a controller that will create a detail view that also pushes data about that respective listing into the detail view for use in a tpl property.
here is my code:
app/view/Main:
Ext.define ('Prac.view.Main', {
extend: 'Ext.Panel',
xtype: 'mainpanel',
requires: ['Prac.store.Names'],
config:{
layout: 'vbox',
items: [
{
xtype: 'titlebar',
docked: 'top',
title: 'Mainpanel',
items: [
{
xtype: 'button',
ui: 'confirm',
iconCls: 'add',
action: 'addName',
align: 'right'
}
]
},
{
xtype: 'list',
flex: 1,
grouped: true,
indexBar: true,
itemTpl: '{firstName} {lastName}',
store: 'Names',
onItemDisclosure: true,
}
]
}
});
app/controller/Main:
Ext.define ('Prac.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
view: 'viewpanel',
det: 'detail'
},
control: {
'list' : {
disclose: 'showDetail'
}
}
},
showDetail: function(list, record) {
var det = Ext.create('Prac.view.Detail', {
data: record.data
});
Ext.Viewport.setActiveItem(det);
}
});
app/view/Detail:
Ext.define('Prac.view.Detail', {
extend: 'Ext.Panel',
xtype: 'detail',
config: {
items: [
{
xtype: 'titlebar',
title: 'Detail View',
docked: 'top'
},
{
xtype: 'panel',
styleHtmlContent: true,
scrollable: 'vertical',
title: 'Details',
//html: 'Hello, World!'
tpl: 'Hello {firstName} {lastName}',
data: null
}
]
}
});
I think that the issue might be of scope. Since the tpl property is nested inside the 'items' property rather than the config, the component is unable to use the data passed to the detail view from the controller. So I am wondering not just how to push data from one view to another, but how to push data from one view to a specific component in another view.
You are absolutely right. You are not setting data of the nested panel, you are setting the data of the Prac.view.Detail instead.
Data is a config property of a panel. That means sencha will create a setData() method for you. When you use this method internally applyData() or updateData() will be called respectively.
In your case this should work:
Ext.define('Prac.view.Detail', {
extend: 'Ext.Panel',
xtype: 'detail',
config: {
items: [
{
xtype: 'titlebar',
title: 'Detail View',
docked: 'top'
},
{
xtype: 'panel',
styleHtmlContent: true,
scrollable: 'vertical',
title: 'Details',
//html: 'Hello, World!'
tpl: 'Hello {firstName} {lastName}',
data: null
}
]
},
updateData: function ( newData, oldData ) {
var nestedPanel = this.down( 'panel' );
nestedPanel.setData( newData );
},
applyData: function ( newData, oldData ) {
var nestedPanel = this.down( 'panel' );
nestedPanel.setData( newData );
}
});
So when one sets the data of the Prac.view.Detail the applyData method will be called and it grabs the nested panel to set its data instead.
I have been trying to add a custom class into one of my views but when I run the application, I get an error in the console log "Cannot create an instance of unrecognized alias: widget.[object Object]". My code is as follows:
SubCategoryListView.js
Ext.define('RestaurantGlobal.view.SubCategoryListView',{
extend: 'Ext.List',
xtype: 'SubCategoryListView',
requires: ['RestaurantGlobal.store.ItemColumnsStore'],
config:{
items:[
{
xtype: Ext.create('Ext.List', {
fullscreen: true,
items: [{
xtype: 'toolbar',
docked: 'top',
ui: 'neutral',
items: [
{
text:'Veg',
align :'center',
handler: function () {
var sto = Ext.create('RestaurantGlobal.store.ItemColumnsStore');
// clear all existing filters
sto.clearFilter();
sto.filter('Info2', 'False');
}
},
{
text:'Non-Veg',
align :'center',
handler: function () {
var sto = Ext.create('RestaurantGlobal.store.ItemColumnsStore');
// clear all existing filters
sto.clearFilter();
sto.filter('Info2', 'True');
}
},
],
store: 'RestaurantGlobal.store.ItemColumnsStore',
itemTpl: ['{Name} {Image}']
}],
}),
}
]
}
});
SubCategories.js
Ext.define('RestaurantGlobal.view.SubCategories', {
extend: 'Ext.Panel',
requires : ['RestaurantGlobal.view.SubCategoryListView'],
config: {
styleHtmlCls: 'maincontainer',
styleHtmlContent: true,
layout: {
type: 'vbox'
},
items: [
{
xtype: 'titlebar',
flex: 0.5,
docked: 'top',
title: 'Category Name'
},
{
xtype: 'SubCategoryListView',
},
{
xtype: 'container',
items: [
{
xtype: 'button',
docked: 'bottom',
margin: '0 0 0 0',
text: 'Place Order'
}
]
}
]
}
});
Please help me in this regard. Also, is there a way to filter a single store to display them into 2 tabs in the same tabpanel?
I am not using tab panel in this case.
The culprit is this:
xtype: Ext.create('Ext.List', {
xtype must be a string.
You can theoritically put a component instance directly in the items:
items:[
Ext.create('Ext.List', {
fullscreen: true,
items: [{
xtype: 'toolbar',
docked: 'top',
ui: 'neutral',
items: [
{
text:'Veg',
align :'center',
handler: function () {
var sto = Ext.create('RestaurantGlobal.store.ItemColumnsStore');
// clear all existing filters
sto.clearFilter();
sto.filter('Info2', 'False');
}
},
{
text:'Non-Veg',
align :'center',
handler: function () {
var sto = Ext.create('RestaurantGlobal.store.ItemColumnsStore');
// clear all existing filters
sto.clearFilter();
sto.filter('Info2', 'True');
}
},
],
store: 'RestaurantGlobal.store.ItemColumnsStore',
itemTpl: ['{Name} {Image}']
}],
}
]
But in the context of a class definition that would really be ill inspired because this same component instance would be used by every instance you create of your class. Most probably resulting in a lot of problems...
In case you really need to create the component instance yourself, because you can't simply declare its configuration, do it by overriding the initComponent method, and create your component in there. The initComponent method will be called for each new instance of your class, so each one will have its own instance of the child component (sorry, I know that makes a lot of repetitions of the word "instance").
Anyway, it seems that what you are really trying to do is simply to override the list class:
Ext.define('RestaurantGlobal.view.SubCategoryListView',{
extend: 'Ext.List',
xtype: 'SubCategoryListView',
requires: ['RestaurantGlobal.store.ItemColumnsStore'],
// You class is already a list, just add your custom configuration
// directly to it:
config:{
fullscreen: true,
items: [{
xtype: 'toolbar',
docked: 'top',
ui: 'neutral',
items: [{
text:'Veg',
align :'center',
handler: function () {
var sto = Ext.create('RestaurantGlobal.store.ItemColumnsStore');
// clear all existing filters
sto.clearFilter();
sto.filter('Info2', 'False');
}
},{
text:'Non-Veg',
align :'center',
handler: function () {
var sto = Ext.create('RestaurantGlobal.store.ItemColumnsStore');
// clear all existing filters
sto.clearFilter();
sto.filter('Info2', 'True');
}
}],
store: 'RestaurantGlobal.store.ItemColumnsStore',
itemTpl: ['{Name} {Image}']
}]
}
});
Ext.define('RestaurantGlobal.view.SubCategoryListView',{
extend: 'Ext.List',
*xtype: 'SubCategoryListView',*
The problem is that you used xtype in class definition but it could be alias:
Ext.define('RestaurantGlobal.view.SubCategoryListView',{
extend: 'Ext.List',
alias: 'widget.SubCategoryListView',
and then you can use this class to create list in this case by:
xtype: 'SubCategoryListView'
as you expected.
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: {...}
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
Here is the thing I am stuck with:
Ext.define('Application.view.phone.AppScreen', {
extend: 'Ext.navigation.View',
// extend: 'Ext.Container',
xtype: 'appscreen',
id: 'appscreen',
alias: 'widget.appscreen',
config: {
items: [{
xtype: 'container',
title: 'My View',
layout: {
type: 'fit'
},
items:[{
html:'phone'
},
{
xtype:'list',
id:'AccountSummary',
name:'AccountSummary',
onItemDisclosure:true,
store:{
fields: ['Label', 'Amount'],
data: [
{
"Label":"Order",
"Amount": "18,275"
},
{
"Label":"Shipment",
"Amount": "25,255"
},
{
"Label":"Invoices",
"Amount": "11,125"
}
]
},
itemTpl: new Ext.XTemplate('{Label}<tpl if="Label==Order"><div class="meter"><span style="width: 60%"></span></div></tpl><tpl if="Label==Shipment"><div class="meter1"><span style="width: 60%"></span></div></tpl><br>$ {Amount} Cash')
}]
}]
}
});
I need to change the css dynamically for example if the label is order I need to apply the css meter,similarly meter1 for Shipment.Can someone please help me on this?
This should be fairly simple, take a look at my working TPL examle below:
new Ext.Container({
fullscreen : true,
tpl : '<tpl if="foo == "bar"">Is Bar</tpl>',
data : {
foo : 'bar'
}
});
I think you just need to add encoded quotes to your statement since your checking a string, see the updated code below:
itemTpl: new Ext.XTemplate('{Label}<tpl if="Label == "Order""><div class="meter"><span style="width: 60%"></span></div></tpl><tpl if="Label == "Shipment""><div class="meter1"><span style="width: 60%"></span></div></tpl><br>$ {Amount} Cash')