When the app launches it will display screen1. And then when we click on a button it will display panel1 or panel2. My code as follows; I get an error when i add panel2.
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'card',
items: [
{
xtype: 'panel',
items: { xtype: 'screen1' }
},
{
xtype: 'panel',
items: { xtype:'panel1' }
}
]
});
}
As soon as i add another panel; and i get an error
TypeError: namespace is undefined
[Break On This Error]
if (namespace === from || namespace.substring(0, from.length) === from) {
Code:
items: [
{
xtype: 'panel',
items: { xtype: 'screen1' }
},
{
xtype: 'panel',
items: { xtype:'panel1' }
},
{
xtype: 'panel',
items: { xtype:'panel2' }
}
]
NOTE: I have added the Panel2 in the views: [ Panel2']
UPDATE
Ext.define('MyApp.view.Panel2', {
extend: 'Ext.tab.Panel',
alias: 'widget.panel2',
height: 250,
width: 400,
activeTab: 0,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'panel',
title: 'Tab 1'
},
{
xtype: 'panel',
title: 'Tab 2'
},
{
xtype: 'panel',
title: 'Tab 3'
}
]
});
me.callParent(arguments);
}
});
It's most likely because you're missing dependencies. Since you didn't post your application definition, you need to require the views in the controller (or, if you aren't even that far yet, in the requires on the application itself).
Have a look at /examples/app/simple in the download to see how it sets up requires.
Related
I am trying to show a view as a "modal" within my application. The main application is a tab panel and when the user does a certain action, I want to popup a view ontop of this tabpanel. I know on native iOS you can do this by pushing a view as a modal but how do I do this in Sencha?
Any ideas?
You can do this:
Ext.define('MyApp.controller.MyController4', {
extend: 'Ext.app.Controller',
config: {
control: {
"button#mybutton": {
tap: 'onMybuttonTap'
}
}
},
onMybuttonTap: function(button, e, options) {
Ext.Viewport.add({xtype:'modalpanel'});
}
});
Views:
Ext.define('MyApp.view.ModaPanel', {
extend: 'Ext.Panel',
alias: 'widget.modalpanel',
config: {
centered: true,
height: 300,
html: 'Cool Story Bro....',
itemId: 'modalPanel',
width: 300,
hideOnMaskTap: true,
modal: true,
scrollable: true,
hideAnimation: {
type: 'popOut',
duration: 200,
easing: 'ease-out'
},
showAnimation: {
type: 'popIn',
duration: 200,
easing: 'ease-out'
},
items: [
{
xtype: 'toolbar',
docked: 'top',
title: 'Blah Blah'
}
]
}
});
Ext.define('MyApp.view.MyTabPanel', {
extend: 'Ext.tab.Panel',
config: {
items: [
{
xtype: 'container',
title: 'Tab 1',
items: [
{
xtype: 'button',
itemId: 'mybutton',
text: 'MyButton10'
}
]
},
{
xtype: 'container',
title: 'Tab 2'
},
{
xtype: 'container',
title: 'Tab 3'
}
]
}
});
EDIT:
You are probably looking for an actionsheet if this is not exactly what you want. See the Sencha Touch Kitchensink for the different types of Overlays.
I tried adding this.callParent(arguments) to the tab panel's initialize event
as suggested by http://www.sencha.com/forum/showthread.php?234909-tab-panel-doesn-t-switch-between-tabs-when-added-dynamically but I get:
Uncaught Error: this.callParent() was called but there's no such method (doFire) found in the parent class (Ext.Base).
Could someone point me in the right direction?
Thank you.
My controller follows:
Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
config: {
refs: {
mytabpanel: '#mytabpanel'
}
},
init: function(application) {
this.control({
mytabpanel: {
initialize: function(component, options){
var bar = component.getTabBar();
bar.insert(0, { flex:1, xtype:'toolbar', title: '' });
bar.insert(bar.getItems().length,
{
xtype: 'toolbar',
flex: 1,
title: '',
items: [
{
xtype : 'button',
docked: 'right',
ui: 'round',
iconCls: 'info',
iconMask: true,
handler: function(){
}
}
]
});
this.callParent(arguments);
}
}
});
}
});
My view follows:
Ext.define('MyApp.view.MyTabPanel', {
extend: 'Ext.tab.Panel',
config: {
id: 'mytabpanel',
items: [
{
xtype: 'container',
title: 'Tab 1',
iconCls: 'info',
html: 'tab 1'
},
{
xtype: 'container',
title: 'Tab 2',
iconCls: 'info',
html: 'tab 2'
},
{
xtype: 'container',
title: 'Tab 3',
iconCls: 'info',
html: 'tab 3'
}
],
tabBar: {
docked: 'bottom'
}
}
});
EDIT Sunday, 30 December 6:57 a.m (GMT - 4:00)
From searching the web I now believe that because I am overriding initialize then I need to call the superclass' initialize method so that its code will be executed as well. As pointed out by user1479606 calling this.callParent will never work. So, the question becomes: How do I call the superclass' initialize method?
I think your application won't work in your case because you should use this.callParent(arguments) in your view not your controller otherwise your parent class will always be Ext.Base.
For easier to understand and better approach, why don't you follow the Sencha Touch 2 convention like this:
config: {
refs: {
mytabpanel: '#mytabpanel'
}
control: {
mytabpanel: {
initialize: 'domytabpanel'
}
}
},
domytabpanel: function(component, options) {
var bar = component.getTabBar();
bar.insert(0, {
flex:1,
xtype:'toolbar',
title: ''
});
bar.insert(bar.getItems().length,
{
xtype: 'toolbar',
flex: 1,
title: '',
items: [
{
xtype : 'button',
docked: 'right',
ui: 'round',
iconCls: 'info',
iconMask: true,
handler: function(){
}
}
]
});
}
Hope it helps :)
I'm creating a sencha touch app and the design requires a segmented button in the tab bar.
Is there an easy way to do this with sencha built-in features or do I have to create that by myself (add a toolbar with the segmented button as an item and create all the controls to actually get the same thing)?
extend: 'Ext.TabPanel',
requires: [
'Ext.SegmentedButton',
],
xtype: 'album',
id: 'album',
fullscreen: true,
config: {
tabBar: {
layout: {
pack: 'center',
},
items: {
xtype: 'segmentedbutton',
allowDepress: false,
listeners: {
initialize: function() {
Ext.SegmentedButton.implement({
setActive: function(activeItem) {
this.setActiveItem(activeItem);
}
});
}
}
}
},
autoDestroy: true,
activeItem: 1,
items: [
{
title: 'HIGHLIGHTS',
xtype: 'highlightview',
id: 'highlightView'
},
{
title: 'KATEGORIEN',
xtype: 'categoryView',
id: 'categoryView',
},
{
title: 'SUCHE',
xtype: 'searchView',
id: 'searchView',
}
],
}
That's what I tried so far. the listener is there to get around the error of [Object] Object has no method 'setActive', but doesn't result in the behaviour I'd like it to have.
//take a tap panel and inside the tap panel create panel as a xtype
//give item id to each button in segmented button to create listener and later on assign a //function to it
extend: 'Ext.TabPanel',
requires: [
'Ext.SegmentedButton'
],
xtype: 'album',
id: 'album',
enter code here`enter code here`
fullscreen: true,
config: {
cls:[
'styles'
],
scrollable: 'vertical',
items: [
{
xtype: 'panel',
title: 'Close Case',
items: [
{
xtype: 'segmentedbutton',
allowDepress: true,
height: 50,
items: [
{
text: 'Option 1',
pressed: true,
handler: function() {
console.log("Picked #1");
alert("foo");
itemId: "newButton11"
}
},
{
text: 'Option 2',
handler: function() {
alert("foo");
}
},
{
text: 'Option 3',
handler: function() {
alert("foo");
}
}
]
}
]
}
],
listeners: [
{
delegate: "#newButton",
event: "tap",
fn: "onNewButtonTap"
}
]
},
onNewButtonTap: function () {
//write your function here and it will work
}
//This is working for me just let me know if it works for you.
Once I have signed in I want the sign in page to be replaced with the dashboard page but for some reason I can't get the card to change as I cant get a refrence to it that will accept the setActiveItem method.
app.js
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
views: [
'MainPanel'
],
name: 'MyApp',
controllers: [
'MainController'
],
launch: function() {
Ext.create('MyApp.view.MainPanel', {fullscreen: true});
}
});
MainController.js
Ext.define('MyApp.controller.MainController', {
extend: 'Ext.app.Controller',
alias: 'controller.mainController',
config: {
},
init: function(application) {
this.control({
'button[action=submitSigninemEmail]': {
tap: 'signinemEmailFnc'
}
});
},
signinemEmailFnc: function() {
var email_fld = Ext.getCmp('signinemEmail').getValue();
var password_fld = Ext.getCmp('signinemPassword').getValue();
var md5password = MD5(password_fld);
Ext.data.JsonP.request({
url: 'http://www.solumac.co.uk/clients/uwana/v2/ajax/sencha.php',
params: {
method: 'signinem',
callback: 'signinem',
email: email_fld,
password: md5password
},
callback: function(result, params) {
if (result === true) {
if (params.status === true){
console.log('signed in');
MyApp.views.MainPanel.setActiveItem('dashboard', {type:'slide', direction:'left'});
} else {
console.log(params.message);
}
}
}
});
}
});
MainPanel.js
Ext.define('MyApp.view.MainPanel', {
extend: 'Ext.Panel',
alias: 'widget.mainPanel',
config: {
layout: {
type: 'card'
},
items: [
{
xtype: 'container',
id: 'signinem',
layout: {
type: 'fit'
},
items: [
{
xtype: 'titlebar',
docked: 'top',
id: 'signinemTitleBar',
title: 'Sign In',
items: [
{
xtype: 'button',
id: 'signinemButtonBack',
ui: 'back',
text: 'Back'
},
{
xtype: 'button',
align: 'right',
id: 'signinemButtonSignUp',
text: 'Sign Up'
}
]
},
{
xtype: 'container',
id: 'signinemPadding',
padding: 10,
width: '100%',
items: [
{
xtype: 'fieldset',
id: 'signinemFacebookSet',
title: 'Sign In with Facebook',
items: [
{
xtype: 'button',
id: 'signinemFacebook',
margin: 10,
width: '',
text: 'Facebook'
}
]
},
{
xtype: 'fieldset',
id: 'signinemEmailSet',
title: 'Sign In with Email',
items: [
{
xtype: 'textfield',
id: 'signinemEmail',
margin: 10,
label: 'email'
},
{
xtype: 'passwordfield',
id: 'signinemPassword',
margin: 10,
label: 'Password'
},
{
xtype: 'checkboxfield',
action: 'changeField',
id: 'signinemShow',
itemId: 'mycheckbox',
margin: 10,
label: 'show password',
labelWidth: '80%'
},
{
xtype: 'button',
action: 'submitSigninemEmail',
id: 'signinemSubmit',
margin: 10,
text: 'Submit'
}
]
}
]
}
]
},
{
xtype: 'container',
id: 'dashboard',
layout: {
type: 'fit'
},
items: [
{
xtype: 'titlebar',
docked: 'top',
id: 'dashboardBar',
title: 'Dashboard'
}
]
},
listeners: [
{
fn: 'onSigninemShowCheck',
event: 'check',
delegate: '#signinemShow'
},
{
fn: 'onSigninemShowUncheck',
event: 'uncheck',
delegate: '#signinemShow'
}
]
},
onSigninemShowCheck: function(checkboxfield, e, options) {
alert('show password');
},
onSigninemShowUncheck: function(checkboxfield, e, options) {
alert('hide password');
}
});
I believe the problem lies with the line...
MyApp.views.MainPanel.setActiveItem('dashboard', {type:'slide', direction:'left'});
...which doesn't work, but have drawn a complete blank as to what should replace it.
if you change
Ext.create('MyApp.view.MainPanel', {fullscreen: true});
to
Ext.Viewport.add(Ext.create('MyApp.view.MainPanel'));
in your app.js, then in your controller change
MyApp.views.MainPanel.setActiveItem('dashboard', {type:'slide', direction:'left'});
to
Ext.Viewport.setActiveItem(Ext.create('dashboard'),{
// other stuff
});
and add dashboard to your views array in app.js I believe it should work
You can't just do a setActiveItem of the id string like you did above:
MyApp.views.MainPanel.setActiveItem('dashboard', {type:'slide', direction:'left'});
You first have to get the reference to the component using Ext.getCmp().
Also, MyApp.views.MainPanel is a class name, and not an instance. You would need to get the specific instance object, and then use it to set the active item.
Here's some code that will work for you:
var mypanel = Ext.ComponentQuery('mainPanel')[0];
var active = Ext.getCmp('dashboard');
mypanel.setActiveItem(active, {type: 'slide', direction: 'left'});
I'm also including a 1 file application that does what you want:
Ext.define('MyApp.view.MyPanel', {
extend: 'Ext.Panel',
alias: 'widget.mypanel',
config: {
layout: {
type: 'card'
},
items: [
{
xtype: 'titlebar',
docked: 'top',
items: [
{
xtype: 'button',
handler: function(button, event) {
var comp = Ext.ComponentQuery.query('mypanel')[0];
var active = Ext.getCmp('c1');
comp.setActiveItem(active);
},
text: 'one'
},
{
xtype: 'button',
handler: function(button, event) {
var comp = Ext.ComponentQuery.query('mypanel')[0];
var active = Ext.getCmp('c2');
comp.setActiveItem(active);
},
text: 'two'
}
]
},
{
xtype: 'container',
html: 'Hello, first container',
id: 'c1'
},
{
xtype: 'container',
html: 'hello, second container',
id: 'c2'
}
]
}
});
I need the tab-panels to fit browser window size. I have used card layout, and it is not re-sizing to fit the browser window. I think i'm missing some properties in my viewPort.
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'card',
items: [
{
xtype: 'panel',
items: { xtype: 'tabP1' }
},
{
xtype: 'panel',
items: { xtype:'tabP2' }
}
,
{
xtype: 'panel',
items: { xtype:'tabP3' }
}
]
});
},
2.) One of my tabpanels; I am using absolute layout. I am using this layout because it's easy to set form components where i ever i desire it to be. Therefore, i would like a solution that works with the same layout.
Ext.define('MyApp.view.MyForm', {
extend: 'Ext.form.Panel',
alias:'widget.tabP1',
// height: 250,
// width: 726,
layout: {
type: 'absolute'
},
bodyPadding: 10,
title: 'My Form',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'gridpanel',
title: 'My Grid Panel',
columns: [
{
xtype: 'gridcolumn',
dataIndex: 'string',
text: 'String'
},
{
xtype: 'numbercolumn',
dataIndex: 'number',
text: 'Number'
},
{
xtype: 'datecolumn',
dataIndex: 'date',
text: 'Date'
},
{
xtype: 'booleancolumn',
dataIndex: 'bool',
text: 'Boolean'
}
],
viewConfig: {
}
}
]
});
me.callParent(arguments);
}
});
UPDATE 2
UPDATE 2
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'card',
items: [
{
xtype: 'tabP1'
},
{
xtype:'tabP2'
}
,
{
xtype:'tabP3'
}
]
});
},
onSuccess: function() {
this.getViewport().getLayout().setActiveItem(1);
},
I get an error when i use your code, saying that this.getViewport().getLayout().setActiveItem(1) is not a function. I think this is because i used border layout. How can i resolve this ?
Your problem is "over-nesting" Why are you putting 'tabPFoo' inside a panel with no layout? They are at best, redundant, also causing the layout system to spend more cycles when it's not needed.
Ext.require('*');
Ext.onReady(function(){
var vp = new Ext.container.Viewport({
layout: 'card',
items: [{
xtype: 'grid',
store: {
fields: ['name'],
data: [{
name: 'Name 1'
}]
},
columns: [{
flex: 1,
dataIndex: 'name',
text: 'Name'
}],
listeners: {
itemclick: function(view){
var grid = view.ownerCt,
next = grid.nextSibling();
vp.getLayout().setActiveItem(next);
}
}
}, {
xtype: 'grid',
store: {
fields: ['name'],
data: [{
name: 'Name 2'
}]
},
columns: [{
flex: 1,
dataIndex: 'name',
text: 'Name'
}],
listeners: {
itemclick: function(view){
var grid = view.ownerCt,
next = grid.nextSibling();
vp.getLayout().setActiveItem(next);
}
}
}, {
xtype: 'grid',
store: {
fields: ['name'],
data: [{
name: 'Name 3'
}]
},
columns: [{
flex: 1,
dataIndex: 'name',
text: 'Name'
}],
listeners: {
itemclick: function(view){
var grid = view.ownerCt,
next = grid.previousSibling().previousSibling();
vp.getLayout().setActiveItem(next);
}
}
}]
});
});
Obviously that's not MVC style, but that's the structure the layout should take.