Reputation: 785
I have one tab where the user must enter information and I want to validate the data when the user tries to change tabs. I'll prompt the user to verify that he wants to leave if the data input is incomplete.
I added the listener activeitemchange: on the tab panel, and I can prompt the user. However, it seems that Ext.Msg doesn't block the method call and I always "return true" from activeitemchange.
How can I change the code so the tab is only changed if the user clicks 'yes'?
Ext.Loader.setConfig({enabled: true});
Ext.application({
name: "Sencha",
launch: function () {
var tabPanel = Ext.create('Ext.tab.Panel', {
layout: 'card',
tabBarPosition: 'bottom',
listeners: {
activeitemchange: function (me, value, oldValue, eOpts) {
console.log("activeitemchange");
var oldTabIdx = me.getInnerItems().indexOf(oldValue);
var newTabIdx = me.getInnerItems().indexOf(me.getActiveItem());
console.log(oldTabIdx + " => " + newTabIdx);
if (oldTabIdx == 2) {
// me.getTabBar().setActiveItem(2);
Ext.Msg.confirm("Leave Screen?", "Are you sure you?", function (response) {
console.log(response);
if (response === 'no') {
console.log("User says stay.");
return false;
} else {
console.log("User says leave.");
return true;
}
});
}
// Always returns true because Ext.Msg.confirm doesn't block
return true; // false prevents tab change
}
},
items: [
{
id: 'tab1',
title: 'Home',
layout: 'fit',
xtype: 'container',
iconCls: 'home',
items: [
{html: 'page #1'}
]
},
{
id: 'tab2',
title: 'Two',
layout: 'fit',
xtype: 'container',
iconCls: 'star',
items: [
{html: 'page #2'}
]
},
{
id: 'tab3',
title: 'three',
layout: 'fit',
xtype: 'container',
iconCls: 'team',
items: [
{html: 'page #3'}
]
}
]
});
Ext.Viewport.add(tabPanel);
}
});
Attempted fix:
Ext.Loader.setConfig({enabled: true});
Ext.application({
name: "Sencha",
launch: function () {
var tabPanel = Ext.create('Ext.tab.Panel', {
layout: 'card',
tabBarPosition: 'bottom',
confirm: true,
listeners: {
activeitemchange: {
order: 'before',
fn: function (list, value, oldValue, eOpts) {
var me = this;
console.log(me.getConfirm()); // ERROR: getConfirm() is undefined
var oldTabIdx = me.getInnerItems().indexOf(oldValue);
var newTabIdx = me.getInnerItems().indexOf(value);
console.log(oldTabIdx + " => " + newTabIdx);
if (oldTabIdx == 2 && me.getConfirm()) {
Ext.Msg.confirm("Leave Screen?", "Are you sure you?", function (response) {
console.log(response);
if (response === 'no') {
console.log("User says stay.");
} else {
console.log("User says leave.");
me.setConfirm(false);
me.setActiveItem(newTabIdx);
}
});
return false;
} else {
me.setConfirm(true);
}
}
}
},
items: [
{
id: 'tab1',
title: 'Home',
layout: 'fit',
xtype: 'container',
iconCls: 'home',
items: [
{html: 'page #1'}
]
},
{
id: 'tab2',
title: 'Two',
layout: 'fit',
xtype: 'container',
iconCls: 'star',
items: [
{html: 'page #2'}
]
},
{
id: 'tab3',
title: 'three',
layout: 'fit',
xtype: 'container',
iconCls: 'team',
items: [
{html: 'page #3'}
]
}
]
});
Ext.Viewport.add(tabPanel);
}
});
Upvotes: 1
Views: 1590
Reputation: 1133
The problem is because Ext.Msg.confirm() is an asynchronous method. It opens a different thread so the listener continues with its normal execution no matter less what is happening on the child thread.
Only way I see is to fire setActiveItem() in the 'yes' callback.
Aditionally, to avoid a confirm loop I added a flag:
Ext.application({
name: "Sencha",
requires: [
'Sencha.MyPanel',
'Ext.MessageBox'
],
launch: function () {
var tabPanel = Ext.create('Sencha.MyPanel');
Ext.Viewport.add(tabPanel);
}
});
Ext.define('Sencha.MyPanel', {
extend: 'Ext.tab.Panel',
config: {
layout: 'card',
tabBarPosition: 'bottom',
confirm: true,
listeners: {
activeitemchange: {
order: 'before',
fn: function (list, value, oldValue, eOpts) {
var me = this;
console.log(me.getConfirm()); // ERROR: getConfirm() is undefined
var oldTabIdx = me.getInnerItems().indexOf(oldValue);
var newTabIdx = me.getInnerItems().indexOf(value);
console.log(oldTabIdx + " => " + newTabIdx);
if (oldTabIdx == 2 && me.getConfirm()) {
Ext.Msg.confirm("Leave Screen?", "Are you sure you?", function (response) {
console.log(response);
if (response === 'no') {
console.log("User says stay.");
} else {
console.log("User says leave.");
me.setConfirm(false);
me.setActiveItem(newTabIdx);
}
});
return false;
} else {
me.setConfirm(true);
}
}
}
},
items: [
{
id: 'tab1',
title: 'Home',
layout: 'fit',
xtype: 'container',
iconCls: 'home',
items: [
{html: 'page #1'}
]
}, {
id: 'tab2',
title: 'Two',
layout: 'fit',
xtype: 'container',
iconCls: 'star',
items: [
{html: 'page #2'}
]
}, {
id: 'tab3',
title: 'three',
layout: 'fit',
xtype: 'container',
iconCls: 'team',
items: [
{html: 'page #3'}
]
}
]
}
});
Hope it helps-
Upvotes: 3