Tab Panel Listener not working - extjs

When try to call the function method in tab panel on click, method is calling in listener. Here my code,
var homepnl=Ext.create('Ext.TabPanel', {
id:'homepnl',
width:'100%',
height:'100%',
tabBarPosition: 'bottom',
defaults: {
styleHtmlContent: true
},
items: [
{
title: 'My Items',
iconCls: 'star',
id:'divtab1',
items: [myitemspnl]
},
{
title: 'Add Items',
iconCls: 'compose',
id:'divtab2',
items: [additemspnl]
},
{
title: 'Friend List',
iconCls: 'team',
//id:'friendsid',
id:'divtab3',
items:[friendslistpnl],
},
{
title: 'Search',
iconCls: 'search',
items: [searchpnl]
},
{
title: 'Settings',
iconCls: 'settings',
items: [settingspnl]
}
],
listeners: {
tabchange: function (homepnl, tab) {
alert(homepnl.id);// No alert is coming here
}
}
});
What the problem with my code here? Please help me to solve

I am looking at Sench touch documentation, there is no event tabchange. See documentation.
You can use activeitemchange event.
Use below code in listeners :
listeners: {
activeitemchange: function (homepnl, value, oldValue) {
alert(homepnl.id);
}
}

Related

ExtJS: Issue with scope in class

I'm keep facing with a issue to choice exact component with scope. As you'll notice below I've created 2 different functions inside gridpanel. One of those creates a Ext.MessageBox for confirm. And other function creates a Ext.window.Window depends on button click of MessageBox.
The thing here is; It should destroy related component with cancel and no buttons. Both buttons always point to gridpanel because of var me = this state and destroys the gridpanel itself.
How can I point destroy method directly to related component?
Ext.define('MyApp.FooGrid', {
extend: 'Ext.grid.Panel',
reference: 'fooGrid',
getGridMenu: function () {
// Here is the 'Update' function; with right-click user being able to see `contextmenu`
var me = this;
var ret = [
{
text: 'Update',
listeners: {
click: me.onUpdate,
scope: me
}
}
];
return me.callParent().concat(ret);
},
onUpdate: function () {
var me = this,
gridRec = this.getSelectionModel().getSelection(); // Here being able to retrieve row data.
Ext.MessageBox.confirm(translations.confirm, translations.confirmChange, me.change, me);
return gridRec;
},
change: function (button) {
var me = this;
var selectedRec = me.onUpdate();
var selectedRecEmail = selectedRec[0].data.email; //Retrieves selected record's email with right-click action
if (button === "yes") {
return new Ext.window.Window({
alias: 'updateWin',
autoShow: true,
title: translations.update,
modal: true,
width: 350,
height: 200,
items: [
{
xtype: 'container',
height: 10
},
{
xtype: 'textfield',
width: 300,
readOnly: true,
value: selectedRecEmail //Display selected record email
},
{
xtype: 'textfield',
width: 300,
fieldLabel: translations.newPassword
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'bottom',
items: [
{
xtype: 'tbfill'
},
{
xtype: 'button',
text: translations.cancel,
listeners: {
click: function () {
me.destroy(); // Here is the bug: When user clicks on this button; should destroy current window but it destroys 'gridpanel' itself
}
}
},
{
xtype: 'button',
text: translations.save,
listeners: {
click: function () {
console.log("I'll save you!");
}
}
}
]
}
]
});
} else {
console.log('this is no!');
me.destroy(); // Another bug raises through here: If user will click on No then 'messagebox' should destroy. This one is destroys the gridpanel as well.
}
}
});
How can I point destroy method directly to related component?
Firstly on confirmation box button's(No) click, you don't need to destroy it will automatically hide the box whenever you click into No.
And for update window instead of using me.destroy() you need to use directly button.up('window').destroy() so it will only destroy your update window not the grid.
And also you don't need to again call me.onUpdate() inside of change function otherwise it will again show the confirmation box. You can directly get selected record on the change function like this me.getSelection().
In this Fiddle, I have created a demo using your code and I have put my efforts to get result.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create('Ext.data.Store', {
storeId: 'demostore',
fields: ['name', 'email', 'phone'],
data: [{
name: 'Lisa',
email: 'lisa#simpsons.com',
phone: '555-111-1224'
}, {
name: 'Bart',
email: 'bart#simpsons.com',
phone: '555-222-1234'
}, {
name: 'Homer',
email: 'homer#simpsons.com',
phone: '555-222-1244'
}, {
name: 'Marge',
email: 'marge#simpsons.com',
phone: '555-222-1254'
}]
});
Ext.create('Ext.grid.Panel', {
title: 'Demo GRID',
store: 'demostore',
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}],
height: 200,
listeners: {
itemcontextmenu: function (grid, record, item, index, e, eOpts) {
e.stopEvent();
grid.up('grid').getGridMenu().showAt(e.getXY());
}
},
renderTo: Ext.getBody(),
getGridMenu: function () {
var me = this;
if (!me.contextMenu) {
me.contextMenu = Ext.create('Ext.menu.Menu', {
width: 200,
items: [{
text: 'Update',
handler: me.onUpdate,
scope: me
}]
});
}
return me.contextMenu;
},
onUpdate: function () {
var me = this;
Ext.MessageBox.confirm('Confirmation ', 'Are your sure ?', me.change, me);
},
change: function (button) {
var me = this,
selectedRecEmail = me.getSelection()[0].data.email; //Retrieves selected record's email with right-click action
if (button === "yes") {
return new Ext.window.Window({
autoShow: true,
title: 'Update',
modal: true,
width: 350,
height: 200,
items: [{
xtype: 'tbspacer',
height: 10
}, {
xtype: 'textfield',
width: 300,
readOnly: true,
value: selectedRecEmail //Display selected record email
}, {
xtype: 'textfield',
inputType:'password',
width: 300,
fieldLabel: 'New Password'
}],
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
items: [{
xtype: 'tbfill'
}, {
xtype: 'button',
text: 'cancel',
listeners: {
click: function (btn) {
btn.up('window').destroy(); // Here is the bug: When user clicks on this button; should destroy current window but it destroys 'gridpanel' itself
}
}
}, {
xtype: 'button',
text: 'save',
listeners: {
click: function () {
console.log("I'll save you!");
}
}
}]
}]
});
}
}
});
}
});

Form panel not showing by set active item

Am new to sencha touch, my problem is i have a separate view to show a form panel by clicking on control event the form panel view will load, but when i click on the event nothing display on my screen. Just a blank screen to show..I dont know what am doing. The form panel is taken from sencha form panel tutorial
The following are my form panel view
Ext.define('WinReo.view.AddContact', {
extend: 'Ext.Container',
xtype: 'addcontact',
requires: [
'Ext.TitleBar'
//'Ext.Video'
],
config: {
layout:'fit'
},
initialize:function(){
console.log('inside initialize');
var formPanel = Ext.create('Ext.form.Panel', {
//xytpe:'formpanel',
fullscreen: true,
layout:'fit',
items: [{
xtype: 'fieldset',
items: [
{
xtype: 'textfield',
name : 'name',
label: 'Name'
},
{
xtype: 'emailfield',
name : 'email',
label: 'Email'
},
{
xtype: 'passwordfield',
name : 'password',
label: 'Password'
}
]
}]
});
formPanel.add({
xtype: 'toolbar',
docked: 'bottom',
layout: { pack: 'center' },
items: [
{
xtype: 'button',
text: 'Set Data',
handler: function() {
formPanel.setValues({
name: 'Ed',
email: 'ed#sencha.com',
password: 'secret'
})
}
},
{
xtype: 'button',
text: 'Get Data',
handler: function() {
Ext.Msg.alert('Form Values', JSON.stringify(formPanel.getValues(), null, 2));
}
},
{
xtype: 'button',
text: 'Clear Data',
handler: function() {
formPanel.reset();
}
}
]
});
}
});
This is the controller event to show form panel view
onItemSwiped: function(list,index,target,record,e)
{
var addcontact= Ext.create('WinReo.view.AddContact');
Ext.Viewport.add(addcontact);
Ext.Viewport.setActiveItem(addcontact);
},
Just a simple task but am spending too much time to fix this one..please help me to solve this issue. Thanks in advance..
Your right about setActiveItem and you need to use it. because Ext.Viewport.add() only adds to viewPort not shows the view.
So only problem in your code is you created formPanel, but not added it in the AddContact View.
...........
// same code
{
xtype: 'button',
text: 'Get Data',
handler: function() {
Ext.Msg.alert('Form Values', JSON.stringify(formPanel.getValues(), null, 2));
}
},
{
xtype: 'button',
text: 'Clear Data',
handler: function() {
formPanel.reset();
}
}
]
});
this.add(formPanel); // add this line
}
});
See this fiddle

List not showing in card layout in 2.1.1 version. Working Perfectly in 2.0 version

IMPORTANT: THIS IS WORKING IN VERSION 2.0 AND NOT IN 2.1.1
My app has 2 different tabs at the bottom (near by, search)
Both this tab use the same list as given below.
Also both NearBy and Search use card layout, the only difference is in Near By the list is in the first card and for Search the list is in the Second card
i am trying this for last 2 day and no progress in this. Please help me
Ext.define('ChurchLookup.view.ChurchList', {
extend: 'Ext.List',
xtype: 'churchlist',
config:
{
title: 'Zip Code',
cls: 'x-contacts',
grouped: true,
store: 'Churches',
itemTpl:
[
'<div class="headshot" style="background-image:url(resources/images/church-type-logo/{icon}.png);"></div>',
'{name}, {city}',
'<span>{phone} / {email}</span>'
].join('')
}});
For Near by when the tab is clicked the list will displayed inside the tab panel.
This is working perfectly and I can see the list.
NEAR BY CARD CODE
Ext.define('ChurchLookup.view.NearBy',
{
extend: 'Ext.Panel',
xtype: 'nearbycard',
config:
{
iconCls: 'locate',
title: 'Near By',
scrollable: 'vertical',
layout:
{
type: 'card',
animation:
{
type: 'pop',
duration: 500,
}
},
items:
[
{
docked: 'top',
xtype: 'titlebar',
title: 'Near by Churches',
items:
[
{
itemId: 'btnBackNearBy',
text: "Back",
ui: "back",
hidden: true,
action: 'onBackNearBy'
}/*,
{
itemId: 'btnHomeSettings',
iconMask:true,
iconCls: 'settings',
ui: 'border',
align: 'right',
action: 'pingHomeBadge'
}*/
]
},
{
xtype: 'churchlist'
},
{
xtype: 'churchdetailsnearby'
}
],
listeners:
[
{
delegate: "#btnHomeSettings",
event: "tap",
fn: "onHomeScreenSettings"
},
{
delegate: "#btnBackNearBy",
event: "tap",
fn: "onBackNearBy"
}
]
},
onHomeScreenSettings: function ()
{
this.fireEvent("homeScreenSettings", this);
},
onBackNearBy: function ()
{
this.fireEvent("onBackNearBy", this);
}
});
But for the search when we click the "Search" tab it will show a card layout with 2 card.
The frist card is the search form and the second card is the list.
When the user fill the form and click the search button I just load the store and change the card layout to show the list.
But the card layout is showing the second page but not the list.
SEARCH TAB CODE
Ext.define('ChurchLookup.view.Search',
{
extend: 'Ext.Panel',
xtype: 'searchcard',
config:
{
iconCls: 'search',
title: 'Search',
scrollable: 'vertical',
layout:
{
type: 'card',
animation:
{
type: 'pop',
duration: 500,
}
},
items:
[
{
docked: 'top',
xtype: 'titlebar',
title: 'Search Church',
items:
[
{
itemId: 'btnBackSearch',
text: "Back",
ui: "back",
hidden: true,
action: 'onBackSearch'
}/*,
{
itemId: 'btnHomeSettings',
iconMask:true,
iconCls: 'settings',
ui: 'border',
align: 'right',
action: 'pingHomeBadge'
}*/
]
},
{
xtype: 'searchform'
},
{
xtype: 'favouritecard'
},
{
xtype: 'churchdetailssearch'
}
],
listeners:
[
{
delegate: "#btnHomeSettings",
event: "tap",
fn: "onHomeScreenSettings"
},
{
delegate: "#btnBackSearch",
event: "tap",
fn: "onBackSearch"
}
]
},
onHomeScreenSettings: function ()
{
this.fireEvent("homeScreenSettings", this);
},
onBackSearch: function ()
{
this.fireEvent("onBackSearch", this);
}
});
Maybe height problem.
Is 'churchdetailssearch' the same as 'churchlist' ?
If churchdetailssearch' has toolbar or something set layout :'vbox' to 'churchdetailssearch', and add the list of 'churchdetailssearch' flex : 1.
Maybe useful the page.
Explain how to a scrollable List use dynamic height without fixed height

How to add a Event Listener to Ext.NavigationViewin Sencha Touch?

I have defined a Ext.navigation.View, I need to attached a event handler
to an element specified in my code as:
title: 'Timetable XXX',
iconMask: true,
iconCls: 'XXX-icon-timetable'
Any idea how to do it?
Ext.define('XXX.view.NavigViewTimetable', {
extend: 'Ext.navigation.View',
alias: 'widget.navigviewtimetable',
requires: [
'XXX.view.TimetableContainer',
'XXX.view.DetailView',
'XXX.view.TimetableEdit',
'XXX.view.TimetableDayList'
],
config: {
navigationBar: {
items: [
{
xtype: 'button',
text: 'Add',
itemId: 'addButton',
ui: 'custom-btn-up-timetable',
align: 'right',
hidden: false
},
],
ui: 'custom-toolbar-top-1L'
},
items: [
{
xtype: 'timetablecontainer'
},
//Toolbar
{
xtype: "toolbar",
docked: "bottom",
ui: 'custom-toolbar-2L',
items: [
{
xtype: "button",
text: 'Today',
ui: 'custom-btn-dwn-timetable',
//handler: this.onTodayButtonTap,
//scope: this,
itemId: 'todayButton'
},
{
xtype: 'spacer'
},
{
xtype: "segmentedbutton",
items: [
{
text: 'Daily',
ui: 'custom-btn-dwn-timetable'
},
{
text: 'List',
ui: 'custom-btn-dwn-timetable',
//disabled: true,
pressed: true
}
],
itemId: 'segBtn',
align: 'right'
}
]
}
],
listeners: [
{
delegate: '#addButton',
event: 'tap',
fn: 'onAddButtonTap'
},
{
delegate: '#todayButton',
event: 'tap',
fn: 'onTodayButtonTap'
},
{
delegate: '#segBtn',
event: 'toggle',
fn: 'onSegBtnToggle'
}
],
// I NEED ADD LISTEN TO AN EVENT HERE
title: 'Timetable XXX',
iconMask: true,
iconCls: 'XXX-icon-timetable'
},
onAddButtonTap: function () {
console.log("addItemCommand [NavigViewTimetable]");
this.fireEvent("addItemCommand", this);
},
onTodayButtonTap: function(){
console.log('onTodayButtonTap [NavigViewTimetable]');
this.fireEvent('todayButtonTapCommand', this)
},
onSegBtnToggle: function (segBtn, btn, isPressed) {
//console.log("'" + btn.config.text +"' on segmented button pressed" );
if (btn.config.text == 'List'){
this.fireEvent('listToggleCommand', this);
}else if (btn.config.text == 'Daily'){
this.fireEvent('dailyToggleCommand', this);
}
}
});
Instead of putting code related to event handlers inside views, I'd prefer using Controllers. That will definitely reduce efforts maintaining code afterwords. Another thing, if you decide to use controllers then you can make use of action config for each of the button. Like -
xtype: 'button',
text: 'Add',
itemId: 'addButton',
ui: 'custom-btn-up-timetable',
align: 'right',
hidden: false,
action:'addButtonAction'
Then in controller, you can use control config option. Ex of controller can be -
Ext.define('XXX.controller.ButtonController',{
extend:'Ext.app.Controller',
config:{
refs:{
views:['Theviews.youwanto.refer'],
//addtional references
},
control:{
'button[action=addButtonAction]':{
tap:'functionForAddButton'
}
}
},
functionForAddButton:function(){
console.log('Add Button tapped');
}
);
You can also use action config on segmeneted buttons -
xtype: "segmentedbutton",
items: [
{
text: 'Daily',
ui: 'custom-btn-dwn-timetable',
action:'dailyButtonAction'
},
{
text: 'List',
ui: 'custom-btn-dwn-timetable',
//disabled: true,
pressed: true,
action:'listButtonAction'
}
],
You can always define event handlers inside views but IMO that's not following MVC principal.

Issue with event handler in EXT JS 4 with card layout

I am working on adding an event handler to a "card layout" Panel.
The problem I am having is I am getting the below error in the Google Chrome console.
Uncaught ReferenceError: navigate is not defined
This is my EXTJS code file:
Ext.define('COMP.app.DailyBulletin', {
extend: 'Ext.panel.Panel',
alias: 'widget.dailybulletin',
height: 300,
width: 200,
layout: 'card',
bodyStyle: 'padding:15px',
activeItem: 0, // index or id
bbar: ['->', {
id: 'card-prev',
text: '« Previous',
handler: function(btn){
navigate(btn.up("panel"), "prev");
},
disabled: true
},{
id: 'card-next',
text: 'Next »',
handler: function(btn){
navigate(btn.up("panel"), "next");
},
}],
items: [{
id: 'card-0',
html: 'page 0'
},{
id: 'card-1',
html: 'page 1'
}],
navigate: function(panel, direction){
var layout = panel.getLayout();
layout[direction]();
Ext.getCmp('card-prev').setDisabled(!layout.getPrev());
Ext.getCmp('card-next').setDisabled(!layout.getNext());
},
});
When I debug the JS in the Google Chrome Developer Tool I can see the issue is that the event handler can't access the navigate function, as it doesn't think it's there. If I just move the code from the navigate function into the event handler and change the layout and direction from expecting parameters to just getting them directly the navigation works fine. This tells me my issue is in how I am calling the navigate function and that I am doing something wrong there.
I'm new to EXT JS and any help is greatly appreciated, thanks!
Try something like this:
Ext.define('COMP.app.DailyBulletin', {
extend: 'Ext.panel.Panel',
alias: 'widget.dailybulletin',
height: 300,
width: 200,
layout: 'card',
bodyStyle: 'padding:15px',
activeItem: 0, // index or id
items: [{
id: 'card-0',
html: 'page 0'
}, {
id: 'card-1',
html: 'page 1'
}],
initComponent: function() {
Ext.apply(this, {
bbar: ['->', {
id: 'card-prev',
text: '« Previous',
scope: this,
handler: function(btn) {
this.navigate(btn.up("panel"), "prev");
},
disabled: true
}, {
id: 'card-next',
text: 'Next »',
handler: function(btn) {
scope: this,
this.navigate(btn.up("panel"), "next");
},
}]
});
this.callParent();
},
navigate: function(panel, direction) {
var layout = panel.getLayout();
layout[direction]();
Ext.getCmp('card-prev').setDisabled(!layout.getPrev());
Ext.getCmp('card-next').setDisabled(!layout.getNext());
},
});

Resources