PDA

View Full Version : Switching between tabs on button click



bunty
19 Sep 2012, 6:30 AM
Hi,

I want to switch between tabs on button click, something like a wizard. But since wizard can't have tabs, hence need to implement the entire finctionality for the Previous and next button writing some code. Below is the layout for Tab Panel and Button.


Ext.onReady(function(){ // basic tabs 1, built from existing content
var tabPanel = Ext.widget('tabpanel', {
renderTo: 'tabs1',
width: 1000,
height: 550,
activeTab: 0,
defaults :{
bodyPadding: 10
},
items: [{
contentEl:'script',
title: 'Tab1',
},{
contentEl:'markup',
title: 'Tab2'
}]
});
Ext.widget('button', {
text: '<< Previous',
width: 100,
handler: function() {
//Ext.getDom('form_main').submit();
alert('Previous');
},
renderTo: 'back'
});

Ext.widget('button', {
text: 'Next >>',
width: 100,
handler: function() {
//Ext.getDom('form_main').submit();
alert('Next');
},
renderTo: 'next'
});

Please let me know how to change between tabs on click og NExt/Previous button.

Regards,

Tim Toady
19 Sep 2012, 6:36 AM
On your tabpanel you can use the setActiveTab method
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.tab.Panel-method-setActiveTab

redraid
19 Sep 2012, 6:45 AM
Example:

Ext.create('Ext.tab.Panel', {
width: 400,
height: 400,
renderTo: document.body,
items: [{
title: 'Foo'
}, {
title: 'Bar',
tabConfig: {
title: 'Custom Title',
tooltip: 'A button tooltip'
}
}],
bbar: [
{
text: 'next',
handler: function (btn) {
var tabs = btn.up('tabpanel'),
activeTab = tabs.getActiveTab(),
nextTab = activeTab.next('panel');

if (nextTab) {
alert('next');
tabs.setActiveTab(nextTab);
}
}
},
{
text: 'prev',
handler: function (btn) {
var tabs = btn.up('tabpanel'),
activeTab = tabs.getActiveTab(),
prevTab = activeTab.prev('panel');

if (prevTab) {
alert('prev');
tabs.setActiveTab(prevTab);
}
}
}
]
});

bunty
19 Sep 2012, 7:48 AM
Hi redraid,

Thanks for the response. IT worked excellently for me. Is it possible to disable the previous button when the 1st tab is opened and change the text of next button to finish when the last tab is opened?

Regards,

scottmartin
19 Sep 2012, 8:42 AM
Here is a good online example of a wizard using card layout:
http://ext4all.com/post/simple-extjs-wizard-with-card-layout

You should be able to set the logic of disabling the buttons as needed.

Scott.

redraid
19 Sep 2012, 9:16 AM
No problem it's easy:


Ext.define('TabWizard', {
extend: 'Ext.tab.Panel',

initComponent: function() {
var me = this;

me.addEvents(['beforechangestep', 'changestep']);

me.bbar = [
{
itemId: 'prevBtn',
text: 'prev',
handler: function(btn) {
var activeTab = me.getActiveTab(),
prevTab = activeTab.prev('panel');

if (prevTab) {
me.setActiveTab(prevTab);
}
}
},
{
itemId: 'nextBtn',
text: 'next',
handler: function(btn) {
var activeTab = me.getActiveTab(),
nextTab = activeTab.next('panel');

if (nextTab) {
me.setActiveTab(nextTab);
}
}
}
];

me.on('beforetabchange', function (tabPanel, newCard, oldCard) {
var ni = me.items.indexOf(newCard),
oi = me.items.indexOf(oldCard);

if (Math.abs(ni - oi) > 1) {
// Disable step over
return false;
}

if (me.fireEvent('beforechangestep', me, ni+1, newCard)) {
me.fireEvent('changestep', me, ni+1, newCard);
} else {
return false;
}
});
me.on('tabchange', me.setupButtons);
me.callParent(arguments);
},

onBoxReady: function() {
this.setupButtons();
},

setupButtons: function() {
var me = this,
activeTab = me.getActiveTab(),
activeTabIndex = me.items.indexOf(activeTab),
tabCount = me.items.getCount(),
nextBtn = me.down('#nextBtn'),
prevBtn = me.down('#prevBtn');

prevBtn.setDisabled(activeTabIndex == 0);
nextBtn.setDisabled(activeTabIndex == (tabCount - 1));
},

getStep: function () {
return this.items.indexOf(this.getActiveTab()) + 1;
}
});

Ext.create('TabWizard', {
width: 400,
height: 400,
renderTo: document.body,
items: [{
title: 'Step 1'
}, {
title: 'Step 2'
}, {
title: 'Step 3'
}],
listeners: {
beforechangestep: function (wizard, step, pagePanel) {
if (step == 1) {
// deny change step
return false;
}
},
changestep: function (wizard, step, pagePanel) {
alert('Step ' + step);
},
}
});
‚Äč

demo: http://jsfiddle.net/2SrhU/1/

bunty
20 Sep 2012, 7:37 AM
I did this and it is working excellently :)


items: [{ contentEl:'script',
title: 'Plan Header',
listeners: {
activate: handleFirstTab
}
},{
contentEl:'markup',
title: 'Unit Cost',
listeners: {
activate: handleSecondTab
}
}],
bbar: [
'->',
{
text: '<< Previous',
id: 'prev',
width: 100,
disabled: true,
handler: function (btn) {
var tabs = btn.up('tabpanel'),
activeTab = tabs.getActiveTab(),
prevTab = activeTab.prev('panel');

if (prevTab) {
tabs.setActiveTab(prevTab);
}
}
},
{
text: 'Next >>',
id: 'next',
width: 100,
handler: function (btn) {
var tabs = btn.up('tabpanel'),
activeTab = tabs.getActiveTab(),
nextTab = activeTab.next('panel');

if (nextTab) {
tabs.setActiveTab(nextTab);
}
}
}
]
});

function handleFirstTab(){
//alert('hello');
Ext.getCmp('prev').disable();
Ext.getCmp('next').setText('Next >>');

}

function handleSecondTab(){

var prev = Ext.getCmp('prev');

if(prev.isDisabled()){
prev.enable();
}

Ext.getCmp('next').setText('Finish');
}

Thanks for the help, i did changes only on htat :)

Is their some way to optimize this code? Asking this since I have only 2 days experience in extjs :(

Regards,

scottmartin
20 Sep 2012, 7:42 AM
Is their some way to optimize this code?

The use if 'id' and getCmp is not considered good practice.

Use itemId instead.

Scott.

bunty
20 Sep 2012, 7:53 AM
other than that, is it a good idea to add the listeners and activate like I did above?

Another thing is when I add some elements, It is getting added the top left of the tab without any space. How to give proper spacing there? using a <br/> in html will give the space from top vertically but giving &nbsp; is not working:(

Please help on this.

Regards,

scottmartin
20 Sep 2012, 8:09 AM
Have a look at bodyPadding:



Ext.create('Ext.panel.Panel', {
title: 'Hello',
width: 200,
bodyPadding: 5,
html: '<p>World!</p>',
renderTo: Ext.getBody()
});


As for the listener approach, I would just set the property instead of a listener unless you need the logic for some reason. The handlers would then change as needed

I would use afterrender or boxready instead of activate.

Scott.

bunty
20 Sep 2012, 8:16 AM
The layout is a bit complicated and still a lot of things to implement but definitely i will try out what you suggested and let you know if any concerns.

One last question for this thread: When I add textfield in the panel, then everything is coming one after another. If I want to place it one beside another with ptoper spacing then what property should be used? Other thing coming into my mind is to use a table,tr and td but still i want to know the best approach to do this since tr and td is the oldest approach.
Now I have this:

Ext.widget('panel', { renderTo: 'pan3',
title: 'Basic Panel',
collapsible:true,
width:980,
height:155,
bodyPadding: 5,
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
name: 'first',
id: 'first_name',
allowBlank:false
},{
fieldLabel: 'Last Name',
name: 'last'
},{
fieldLabel: 'Company',
name: 'company'
}, {
fieldLabel: 'Email',
name: 'email',
vtype:'email'
}
],
});

Please advice and thanks.

Regards,

scottmartin
20 Sep 2012, 8:24 AM
Have a look at the Form examples. You are looking for a fieldContainer with hbox layout/padding:
http://www.sencha.com/products/extjs/examples
http://dev.sencha.com/deploy/ext-4.1.0-gpl/examples/form/contact-form.js

Scott.

bunty
20 Sep 2012, 8:30 AM
Thanks a lot for the help. Will try it out :)