Hi Frank,
Could you please quickly modify the 2.x code as commented by Rich Waters, so that the wizard can be embedded/placed in anywhere in the document?
Expecting a quick help from you.
Thanks,
Biju
Hi Frank,
Could you please quickly modify the 2.x code as commented by Rich Waters, so that the wizard can be embedded/placed in anywhere in the document?
Expecting a quick help from you.
Thanks,
Biju
I have written a new version of this wizard extending the panel class.
It can be placed anywhere in the document, and I hope it could be usefull.
here is the code:
wizard.js
CSS CodeCode:Ext.namespace('Ext.ux'); /** * Ext.ux.Wizard Extension Class * * @author Pontifex * @version 1.0 * * Ext. Version 2.0.2 * @class Ext.ux.Wizard * @extends Ext.Panel * @constructor * @param {Object} config Configuration options */ Ext.ux.Wizard = function(config) { var _config = Ext.apply({ layout: 'card', activeItem: 0, bodyStyle: 'paddingTop:15px', defaults: { // applied to each contained panel border: false }, buttons : [ {text:'Previous', handler: this.movePrevious, scope: this, disabled:true}, {text:'Next', handler: this.moveNext, scope: this}, {text:'Finish', handler: this.finishHanlder, scope: this, disabled:true}, {text:'Cancel', handler: this.hideHanlder, scope: this} ] }, config||{}); this.currentItem = 0; this.template = new Ext.Template('Step {current} of {count}'); this.mandatorySteps = _config['mandatorySteps']; Ext.ux.Wizard.superclass.constructor.call(this, _config); this.addEvents('leave', 'activate', 'finish', 'cancel'); this.on('render', function(){ this.footer.addClass('x-panel-footer-wizard'); this.footer.insertFirst({html: '<div class="x-panel-footer-wizard-status"> </div>'}); return true; }); this.on('afterlayout', function(){ if(this._firstTime === true) { this._firstTime = false; this.setStatus(); this.fireEvent('activate', this.layout.activeItem); } return true; }); }; // end of Ext.ux.Wizard constructor // extend Ext.extend(Ext.ux.Wizard, Ext.Panel, { getCurrentStep: function() { return this.currentItem + 1; }, getStepCount: function() { return this.items.items.length; }, setCurrentStep: function(step) { this.move(step-1); }, /** * @private */ beforeMove: function(currentItem, nextItem, forward) { return this.fireEvent('leave', currentItem, nextItem, forward); }, /** * @private */ setStatus: function() { var BUTTON_PREVIOUS = 0; var BUTTON_NEXT = 1; var BUTTON_FINISH = 2; var BUTTON_CANCEL = 3; var isFirstItem = (this.getCurrentStep() == 1); var isLastItem = (this.getCurrentStep() == this.getStepCount()); var minimunSteps = isNaN(parseInt(this.mandatorySteps)) ? this.getStepCount() : Math.min(Math.max(parseInt(this.mandatorySteps), 1), this.getStepCount()); this.buttons[BUTTON_PREVIOUS].setDisabled(isFirstItem); this.buttons[BUTTON_NEXT].setDisabled(isLastItem); this.buttons[BUTTON_FINISH].setDisabled(!(isLastItem || (minimunSteps < this.getCurrentStep()))); this.footer.first('div div', true).firstChild.innerHTML = this.template.applyTemplate({'current': this.getCurrentStep(), 'count': this.getStepCount()}); }, /** * @private */ move: function(item) { if(item >= 0 && item < this.items.items.length) { if(this.beforeMove(this.layout.activeItem, this.items.items[item], item > this.currentItem)) { this.layout.setActiveItem(item); this.currentItem = item; this.setStatus(); this.fireEvent('activate', this.layout.activeItem); } } }, /** * @private */ moveNext:function(btn,e){ this.move(this.currentItem+1); }, /** * @private */ movePrevious:function(btn,e){ this.move(this.currentItem-1); }, /** * @private */ hideHanlder :function(){ if(this.fireEvent('cancel')) this.hide(); }, /** * @private */ finishHanlder:function(){ if(this.fireEvent('finish')) this.hide(); } });
usage:Code:.x-panel-footer-wizard { border-color:#a9bfd3; border-style:solid; border-width:0 1px 1px 1px; background:#d0def0 url(../images/default/toolbar/bg.gif) repeat-x top left; } .x-panel-footer-wizard-status { padding-left: 5px; padding-top: 11px; color:#15428b; font:bold 11px tahoma,arial,verdana,sans-serif; float:left; width:auto; }
Kind regards,Code:var wizard = new Ext.ux.Wizard({ id: 'myWizard', title: 'My Example Wizard', mandatorySteps: 2, // at least two steps are required // the panels (or "cards") within the layout items: [{ id: 'card-0', style: {'padding': '5px'}, html: '<h1>Welcome to the Wizard!</h1><p>Step 1 of 5</p>' },{ id: 'card-1', style: {'padding': '5px'}, html: '<p>Step 2 of 5</p>' },{ id: 'card-2', style: {'padding': '5px'}, html: '<p>Step 3 of 5</p>' },{ id: 'card-3', style: {'padding': '5px'}, html: '<p>Step 4 of 5</p>' },{ id: 'card-4', style: {'padding': '5px'}, html: '<h1>Congratulations!</h1><p>Step 5 of 5 - Complete</p>' }] }); wizard.on({ 'leave': { fn: function(currentItem, nextItem, forward) { var msg = 'Leaving ' + currentItem.id + ', entering ' + nextItem.id + '\nAre you sure you want to do that?'; return forward ? window.confirm(msg) : true; }, scope: this.wizard }, 'activate': { fn: function(currentItem) { Ext.MessageBox.alert('Wizard', 'Entering ' + currentItem.id); }, scope: this.wizard }, 'cancel': { fn: function() { Ext.MessageBox.alert('Wizard', 'Cancel'); }, scope: this.wizard }, 'finish': { fn: function() { Ext.MessageBox.alert('Wizard', 'Finish'); }, scope: this.wizard } }, this);
Pontifex
nice work. It worth of time consuming that. Thanks,guys![]()
Is there a demo of this actually working anywhere?
Can anyone please provide a working demo...
i have not been able to get this to work...
a working demo or download would be awesome.
thanks
Unfortunately I do not have a public web that can show,
so I hope this demo could be usefull.
Kind regards,
Pontifex
had a chance to look it over...
looks awesome...
you mentioned above that the wizard could be called from anywhere on a form. How?
now just need to figure out how to submit to database.
thanx, Pontifex
demo.js
PHP Code:
Ext.namespace('valinor');
valinor.demo = function() {
var wizard; // componente
var step1; // customer form
var step2; // vehicle form
var step3; // notes
function buildFormularioCliente() {
var txtNombre = new Ext.form.TextField({
fieldLabel: 'Name',
maxLength: 100,
name: 'cliNombre',
anchor: '90%'
});
var txtDireccion = new Ext.form.TextField({
fieldLabel: 'Address',
maxLength: 100,
name: 'cliDireccion',
anchor: '90%'
});
var txtTelefono = new Ext.form.TextField({
fieldLabel: 'Phone',
maxLength: 50,
name: 'cliTelefono',
anchor: '90%'
});
var txtFax = new Ext.form.TextField({
fieldLabel: 'Fax',
maxLength: 15,
name: 'cliFax',
anchor: '90%'
});
var txtEmail = new Ext.form.TextField({
fieldLabel: 'Email',
maxLength: 50,
name: 'cliEmail',
anchor: '90%'
});
var btn = new Ext.Button();
btn.on('click', function(){var pBar = Ext.getCmp('downBar1');
pBar.wait({
interval: 100, //bar will move fast!
duration: 5000,
increment: 15
}); });
var pBarForm = new Ext.FormPanel({
labelWidth: 140, // label settings here cascade unless overridden
labelAlign: 'right',
frame: false,
bodyStyle:'padding:5px 5px 5px 5px',
width: 350,
defaults: {width: 230},
defaultType: 'textfield',
items: [new Ext.Panel({html: '<h1>Customer data</h1>', border: false}),
txtNombre,
txtDireccion,
txtTelefono,
txtFax,
txtEmail,
new Ext.ProgressBar(
{
id : "downBar1",
width:520,
height:100,
autoShow :true
}),btn
]
});
return pBarForm
};
function buildFormularioVehiculo() {
var pBar = new Ext.ProgressBar(
{
id : "downBar2",
width:520,
autoShow :true
});
var btn = new Ext.Button();
btn.on('click', function(){var pBar = Ext.getCmp('downBar2');
pBar.wait({
interval: 100, //bar will move fast!
duration: 5000,
increment: 15
}); });
var pBarForm = new Ext.FormPanel({
labelWidth: 140, // label settings here cascade unless overridden
labelAlign: 'right',
frame: false,
bodyStyle:'padding:5px 5px 5px 5px',
width: 350,
defaults: {width: 230},
defaultType: 'textfield',
items: [new Ext.Panel({html: '<h1>Customer data</h1>', border: false}),
pBar,
btn
]
});
return pBarForm;
}
function buildFormularioNotas() {
return {id: 'panelNotas',
html: '<h1>Step 3</h1>'};
}
function buildWizard() {
step1 = buildFormularioCliente();
step2 = buildFormularioVehiculo();
step3 = buildFormularioNotas();
wizard = new Ext.ux.Wizard({
id: 'myWizard',
title: 'My Example Wizard',
// the panels (or "cards") within the layout
items: [step1, step2, step3]
});
wizard.on({
'leave': {
fn: function(currentItem, nextItem, forward) {
var msg = 'Leaving ' + currentItem.id + ', entering ' + nextItem.id
+ '\n(Add some validation code here!!)'
+ '\nAre you sure you want to do that?';
return forward ? window.confirm(msg) : true;
},
scope: this.wizard
},
'activate': {
fn: function(currentItem) {
if(currentItem.id == '') {
try {
Ext.getCmp('cliCodigo').focus(true, true);
} catch(e) {}
}
},
scope: this.wizard
} ,
'cancel': {
fn: function() {
Ext.MessageBox.alert('Wizard', 'Cancel');
},
scope: this.wizard
},
'finish': {
fn: function() {
Ext.MessageBox.alert('Wizard', 'Finish');
},
scope: this.wizard
}
}, this);
var viewport = new Ext.Viewport({ layout:'border',
id: 'viewPort',
items:[new Ext.Panel({ id: 'centerPanel',
region:'center',
title:false,
deferredRender:false,
layout: 'fit',
border: false,
bodyStyle: {padding: '10px'}
})
]
});
Ext.getCmp('centerPanel').add(wizard);
Ext.getCmp('viewPort').doLayout();
wizard.render();
}
return {
init: function(){
this.getWizard();
},
getWizard: function() {
Ext.QuickTips.init();// Enable Quicktips
buildWizard();
}
}
}();
Ext.onReady(valinor.demo.init, valinor.demo, true);
hi frank ,
I used your demo of wizard, but it doexn't work well,
My source code is:
App={}
App.AppName = "Wizard DEMO";
CreateProject = function(){
var wizard;
return {
init:function(){
wizard = new Ext.ux.wizard(Ext.id(),{
autoCreate:true,
width:630,
height:380,
resizable:false,
autoScroll:false
});
wizard.addStepContent({
title:App.AppName+' Wizard:'+'Welcome',
goNextConfirm:false,
goPerviousConfirm:false,
fn:this.welcomePage
});
wizard.addStepContent({
title:App.AppName+' Wizard:'+'Please input project\'s info',
goNextConfirm:true,
goPerviousConfirm:true,
autoResetForm:true,
fn:this.newProjectForm
});
wizard.addStepContent({
title:App.AppName+' Wizard:'+'Finish',
fn:this.finish
});
},
show:function(btn,e){wizard.show(/*btn.ui.wrap*/)},
welcomePage:function(){
var dlg = this.dlg;
/**
* this.container must be appeared in every Setp.fn
*/
this.container = dlg.body.createChild({
tag:'div',
cls:'wizard_container',
children:[
{tag:'br'},
{
tag:'h3',cls:'wizard',
html:'Start out config your project'
},
{
tag:'div',
cls:'wizard_intro',
html:'Project Tracker provides innovate infrastructure of bug/defect tracking software solution that deliver not for professional developer,but also public tester in a easy-to-learn/use User Interface. '
}
]
});
},
newProjectForm:function(){
var dlg = this.dlg;
var formEl = this.container;
this.container = dlg.body.createChild({
tag:'div',
cls:'wizard_container'
});
var formEl = this.container.createChild({
tag:'form',
id:'wizard_newProjectForm',
children:[
{
tag:'fieldset',
style:'border:1px solid #818181;height:203px;padding:8px;padding-top:0;',
children:[
{
tag:'legend',
cls:'',
html:"<b>User Basic Information</b>"
},
{tag:'br'},
{
tag:'div',
children:[{
tag:'span',
style:'width:80px;display:block;float:left;',
html:"Project Name:"
},
{
tag:'input',
name:'title',
cls:'x-form-text x-form-field',
type:'text',
size:25
},{tag:'span',html:' *'},
{tag:'br'},
{tag:'br'},
{
tag:'span',
style:'width:80px;display:block;float:left;',
html:"Project Details:"
},
{
tag:'textarea',
name:'project_Details',
cls:'x-form-field',
style:'height:90px;width:50%;overflow-x:hidden;',
width:100
},{tag:'span',html:' *'},
{tag:'br'},
{tag:'br'},
{
tag:'span',
style:'width:80px;display:block;float:left;',
html:"Founder:"
},
{
tag:'input',
name:'founder',
cls:'x-form-text x-form-field',
type:'text',
size:15
},{
tag:'span',html:' * '
},{
tag:'button',html:'Users...'
}]
}
]
},
{tag:'br'},
{
tag:'input',
type:'submit',
value:'Create My Account'
}
]
});
formEl.on('submit',function(e,formDOM){
e.stopEvent();//cancel browser action
Ext.Ajax.request({
url:'/deepcms/user/Server/Submitter.asp',
method:'post',
params:'do=createNewUser'+
'&'+Ext.Ajax.serializeForm(formDOM),
success:commonFn.XHR_Response_Handler.ok,
failure:commonFn.XHR_Response_Handler.failure
});
nextBtn.enable();
});
//get Focus
formEl.child('input[name="title"]').focus();
},
finish:function(){
var dlg = this.dlg;
this.container = dlg.body.createChild({tag:'div'});
this.container.createChild({
tag:'img',
cls:'left',
vspace:1,
hspace:1,
src:'/deepcms/resources/tracker/setup_2.jpg'
});
this.container.createChild({
tag:'div',
cls:'left',
style:'margin-top:25%;width:60%;text-indent:10em',
children:[
{
tag:'h3',
html:'Finish!'
}
]
});
}
};
}();
wizard.js:
Ext.ux.wizard = function(config){
var _config = Ext.apply({
renderTo : Ext.getBody(),
buttons : [
{text:'Pervious', handler: this.movePervious, scope: this, hidden:true},
{text:'Next', handler: this.moveNext, scope: this},
{text:'Finish', handler: this.finisHanlder, scope: this, hidden:true},
{text:'Cancel', handler: this.hideHanlder, scope: this}
]
}, config||{});
this.id = 0;
this.stepPages = [];
this.loaded_Page_No;
this.loaded_Page;
Ext.ux.wizard.superclass.constructor.call(this, _config);
this.render();
this.on('show',function(){
if(!this.loaded_Page_No){
this.move(1);//first one
}
},this);
this.dlg = this;
};
Ext.extend(Ext.ux.wizard , Ext.Window, {
/**
* Add steps' content to dialog body.
* @param {Object} config
* An object containing configuration properties for a step.
* This may contain any of the following properties:
* @cfg {String} title The title of step(be set to Ext.dialog.title)
* @cfg {Boolean} goNextConfirm Optional. True if showing a confirm dialog to ask the user before go Next Step.
* @cfg {Boolean} goPerviousConfirm Optional. True if showing a confirm dialog to ask the user before go Previous Step.
* @cfg {Boolean} autoResetForm Optional. True if reseting form after go Next/Previous Step.
* @cfg {Functionfn} The function to add step's content.
*/
addStepContent:function(step){
// just names it for a mention that this is 'Class'.
var Class_Page = step.fn;
if(typeof Class_Page != 'function')throw 'argments must be a function.';
Class_Page.prototype = {
id:this.id++,
titletep.title||'Step:'+(this.id++),
goNextConfirm:!!(step.goNextConfirm),
goPerviousConfirm:!!(step.goPerviousConfirm),
autoResetForm:!!(step.autoResetForm),
dlg:this.dlg,
container:null,
getDIV:function(){
return this.container;
},
notiflyDlg:function(moveDirection){
return moveDirection=='>'?this.goNextConfirm:this.goPerviousConfirm;
}
};
var incomingPage = new Class_Page();
var StepPanel = incomingPage.getDIV();
if( StepPanel){
StepPanel.setStyle('display','none');
}
this.stepPages.push(incomingPage);
},
/**
* @private
*/
move:function(pageNo){
if( this.loaded_Page && (pageNo!=0) ){
this.loaded_Page.applyStyles('display:none');
}
//获取每个页面的实例 get a instance for every page
var pageInstance = this.stepPages[(pageNo-1)];
var step = pageInstance.getDIV();//always less one than the length of index
step.show();
this.dlg.setTitle(pageInstance.title);
if(pageInstance.autoResetForm){
step.child('form').dom.reset();
}
this.loaded_Page = step;
this.loaded_Page_No = pageNo;
},
/**
* @private
*/
moveNext:function(btn,e){
var body = this.dlg.body;
var pageInstance = this.stepPages[this.loaded_Page_No-1];//pervious page!
if( pageInstance && pageInstance.notiflyDlg('>')){
if(!window.confirm('Do you want to go Next Page?'))
return;
};
this.move(this.loaded_Page_No+1);
var isLastPage = (this.loaded_Page_No)==(this.stepPages.length);
if(this.dlg.buttons[0].disabled&&!isLastPage){
this.dlg.buttons[2].hide();
this.dlg.buttons[0].enable(); //'pervious button'
}
if(isLastPage){//arrives at last page
btn.disable();
this.dlg.buttons[2].show();//'finish' button
this.dlg.buttons[3].hide();
}
if(this.loaded_Page_No > 0){//first one
this.dlg.buttons[0].show();
}
},
/**
* @private
*/
movePervious:function(btn,e){
var body = this.dlg.body;
var pageInstance = this.stepPages[this.loaded_Page_No-1];//pervious page!
if( pageInstance && pageInstance.notiflyDlg('<')){
if(!window.confirm('Do you want to go Pervious?'))
return;
};
this.move(this.loaded_Page_No-1);
var isNo1Page = ((this.loaded_Page_No)==1);
if(this.dlg.buttons[1].disabled&&!isNo1Page){
this.dlg.buttons[2].hide();
this.dlg.buttons[3].show();
this.dlg.buttons[1].enable();
}
if(isNo1Page){//arrives at pervious page
btn.disable();
this.dlg.buttons[0].hide();
this.dlg.buttons[1].enable();//'movefisrt' button
}
},
/**
* @override
*/
hideHanlder :function(){
this.hide();
},
/**
* @override
*/
finisHanlder:function(){}
});
please help me ,thank you very much