extjs3支持按步骤处理(向导)控件

有些业务处理我们不能一步做完,所以我们希望实现一个类似于setup安装向导的控件,在ext官方的论坛上找到一个,但是只支持extjs2.×,下边的这个控件是在extjs3.×上做的

Ext.layout.UXCardLayout=Ext.extend(Ext.layout.CardLayout,{setActiveItem:function(item){
    item=this.container.getComponent(item);
    if(this.activeItem!=item){
      if(this.activeItem){
        this.activeItem.hide();
      }
      if(this.activeItem&&!this.activeItem.hidden){
        return ;
      }
      this.activeItem=item;
      item.show();
      this.layout();
    }
  }});
Ext.UXWizHeader=Ext.extend(Ext.BoxComponent,{height:55,region:"north",title:"Wizard",steps:0,stepText:"Step {0} of {1}: {2}",autoEl:{tag:"div",cls:"ext-ux-wiz-Header",children:[{tag:"div",cls:"ext-ux-wiz-Header-title"},{tag:"div",children:[{tag:"div",cls:"ext-ux-wiz-Header-step"},{tag:"div",cls:"ext-ux-wiz-Header-stepIndicator-container"}]}]},titleEl:null,stepEl:null,imageContainer:null,indicators:null,stepTemplate:null,lastActiveStep:-1,updateStep:function(currentStep,title){
    var html=this.stepTemplate.apply({0:currentStep+1,1:this.steps,2:title});
    this.stepEl.update(html);
    if(this.lastActiveStep!=-1){
      this.indicators[this.lastActiveStep].removeClass("ext-ux-wiz-Header-stepIndicator-active");
    }
    this.indicators[currentStep].addClass("ext-ux-wiz-Header-stepIndicator-active");
    this.lastActiveStep=currentStep;
  },onRender:function(ct,position){
    Ext.UXWizHeader.superclass.onRender.call(this,ct,position);
    this.indicators=[];
    this.stepTemplate=new Ext.Template(this.stepText),this.stepTemplate.compile();
    var el=this.el.dom.firstChild;
    var ns=el.nextSibling;
    this.titleEl=new Ext.Element(el);
    this.stepEl=new Ext.Element(ns.firstChild);
    this.imageContainer=new Ext.Element(ns.lastChild);
    this.titleEl.update(this.title);
    var image=null;
    for(var i=0,len=this.steps;i<len;i++){
      image=document.createElement("div");
      image.innerHTML="&#160;";
      image.className="ext-ux-wiz-Header-stepIndicator";
      this.indicators[i]=new Ext.Element(image);
      this.imageContainer.appendChild(image);
    }
  }});
Ext.UXWiz=Ext.extend(Ext.Window,{loadMaskConfig:{"default":"Saving..."},height:400,width:540,closable:true,resizable:false,modal:true,cards:null,previousButtonText:"&lt; Previous",nextButtonText:"Next &gt;",cancelButtonText:"Cancel",finishButtonText:"Finish",headerConfig:{},cardPanelConfig:{},previousButton:null,nextButton:null,cancelButton:null,cardPanel:null,currentCard:-1,headPanel:null,cardCount:0,initComponent:function(){
    this.initButtons();
    this.initPanels();
    var title=this.title||this.headerConfig.title;
    title=title||"";
    Ext.apply(this,{title:title,layout:"border",cardCount:this.cards.length,buttons:[this.previousButton,this.nextButton,this.cancelButton],items:[this.headPanel,this.cardPanel]});
    this.addEvents("cancel","finish");
    Ext.UXWiz.superclass.initComponent.call(this);
    this.cardPanel.activeItem=0;
  },getWizardData:function(){
    var formValues={};
    var cards=this.cards;
    for(var i=0,len=cards.length;i<len;i++){
      if(cards[i].form){
        formValues[cards[i].id]=cards[i].form.getValues(false);
      }else {
        formValues[cards[i].id]={};
      }
    }
    return formValues;
  },switchDialogState:function(enabled,type){
    this.showLoadMask(!enabled,type);
    this.previousButton.setDisabled(!enabled);
    this.nextButton.setDisabled(!enabled);
    this.cancelButton.setDisabled(true);
    if(this.closable){
      var ct=this.tools["close"];
      switch(enabled){
      case true:
        this.tools["close"].unmask();
        break ;
      default:
        this.tools["close"].mask();
        break ;
      }
    }
  },showLoadMask:function(show,type){
    if(!type){
      type="default";
    }
    if(show){
      if(this.loadMask==null){
        this.loadMask=new Ext.LoadMask(this.body);
      }
      this.loadMask.msg=this.loadMaskConfig["type"];
      this.loadMask.show();
    }else {
      if(this.loadMask){
        this.loadMask.hide();
      }
    }
  },initPanelsEvents:function(){
    var cards=this.cards;
    for(var i=0,len=cards.length;i<len;i++){
      cards[i].on("show",this.onCardShow,this);
      cards[i].on("hide",this.onCardHide,this);
      cards[i].on("clientvalidation",this.onClientValidation,this);
    }
  },initPanels:function(){
    var cards=this.cards;
    var cardPanelConfig=this.cardPanelConfig;
    Ext.apply(this.headerConfig,{steps:cards.length});
    this.headPanel=new Ext.UXWizHeader(this.headerConfig);
    Ext.apply(cardPanelConfig,{layout:new Ext.layout.UXCardLayout(),items:cards});
    this.initPanelsEvents();
    Ext.applyIf(cardPanelConfig,{region:"center",border:false,activeItem:0});
    this.cardPanel=new Ext.Panel(cardPanelConfig);
  },initButtons:function(){
    this.previousButton=new Ext.Button({text:this.previousButtonText,disabled:true,minWidth:75,handler:this.onPreviousClick,scope:this});
    this.nextButton=new Ext.Button({text:this.nextButtonText,minWidth:75,handler:this.onNextClick,scope:this});
    this.cancelButton=new Ext.Button({text:this.cancelButtonText,handler:this.onCancelClick,scope:this,minWidth:75});
  },onClientValidation:function(card,isValid){
    if(!isValid){
      this.nextButton.setDisabled(true);
    }else {
      this.nextButton.setDisabled(false);
    }
  },onCardHide:function(card){
    if(this.cardPanel.layout.activeItem.id===card.id){
      this.nextButton.setDisabled(true);
    }
  },onCardShow:function(card){
    var parent=card.ownerCt;
    var items=parent.items;
    for(var i=0,len=items.length;i<len;i++){
      if(items.get(i).id==card.id){
        break ;
      }
    }
    this.currentCard=i;
    this.headPanel.updateStep(i,card.title);
    if(i==len-1){
      this.nextButton.setText(this.finishButtonText);
    }else {
      this.nextButton.setText(this.nextButtonText);
    }
    if(card.isValid()){
      this.nextButton.setDisabled(false);
    }
    if(i==0){
      this.previousButton.setDisabled(true);
    }else {
      this.previousButton.setDisabled(false);
    }
  },onCancelClick:function(){
    if(this.fireEvent("cancel",this)!==false){
      this.close();
    }
  },onFinish:function(){
    if(this.fireEvent("finish",this,this.getWizardData())!==false){
      this.close();
    }
  },onPreviousClick:function(){
    if(this.currentCard>0){
      this.cardPanel.getLayout().setActiveItem(this.currentCard-1);
    }
  },onNextClick:function(){
    if(this.currentCard==this.cardCount-1){
      this.onFinish();
    }else {
      this.cardPanel.getLayout().setActiveItem(this.currentCard+1);
    }
  }});
Ext.UXWizCard=Ext.extend(Ext.FormPanel,{header:false,hideMode:"display",initComponent:function(){
    this.addEvents("beforecardhide");
    Ext.UXWizCard.superclass.initComponent.call(this);
  },isValid:function(){
    if(this.monitorValid){
      return this.bindHandler();
    }
    return true;
  },bindHandler:function(){
    var valid=true;
    this.form.items.each(function(f){
      if(f.isValid&&!f.isValid(true)){
        valid=false;
        return false;
      }
    });
    if(this.buttons){
      for(var i=0,len=this.buttons.length;i<len;i++){
        var btn=this.buttons[i];
        if(btn.formBind===true&&btn.disabled===valid){
          btn.setDisabled(!valid);
        }
      }
    }
    this.fireEvent("clientvalidation",this,valid);
  },initEvents:function(){
    var old=this.monitorValid;
    this.monitorValid=false;
    Ext.UXWizCard.superclass.initEvents.call(this);
    this.monitorValid=old;
    this.on("beforehide",this.bubbleBeforeHideEvent,this);
    this.on("beforecardhide",this.isValid,this);
    this.on("show",this.onCardShow,this);
    this.on("hide",this.onCardHide,this);
  },bubbleBeforeHideEvent:function(){
    var ly=this.ownerCt.layout;
    var activeItem=ly.activeItem;
    if(activeItem&&activeItem.id===this.id){
      return this.fireEvent("beforecardhide",this);
    }
    return true;
  },onCardHide:function(){
    if(this.monitorValid){
      this.stopMonitoring();
    }
  },onCardShow:function(){
    if(this.monitorValid){
      this.startMonitoring();
    }
  }});

 使用方法:

var wizard=new Ext.UXWiz({title:"\u5408\u5e76\u673a\u6784",headerConfig:{title:"\u673a\u6784\u5408\u5e76"},cardPanelConfig:{defaults:{baseCls:"x-small-editor",bodyStyle:"padding:40px 15px 5px 20px;background-color:#F6F6F6;",border:false}},cards:[new Ext.UXWizCard({title:"Welcome",items:[{border:false,bodyStyle:"background:none;",html:"\u673a\u6784\u5408\u5e76\uff0c\u9009\u62e9\u9700\u8981\u5408\u5e76\u7684\u673a\u6784\uff0c\u786e\u5b9a\u5408\u5e76\u540e\u7684\u76ee\u6807\u673a\u6784\uff0c\u4fdd\u5b58\u540e\u5408\u5e76\u524d\u7684\u673a\u6784\u5c06\u88ab\u5220\u9664\uff0c\u5176\u4eba\u5458\u4fe1\u606f\u5c06\u8f6c\u79fb\u5230\u65b0\u673a\u6784\u3002"}]}),new Ext.UXWizCard({title:"Your name",monitorValid:true,defaults:{labelStyle:"font-size:11px"},items:[{border:false,bodyStyle:"background:none;padding-bottom:30px;",html:"Please enter your first- and your lastname. Only letters, underscores and hyphens are allowed."},new Ext.form.TextField({name:"firstname",fieldLabel:"Firstname",allowBlank:false,validator:function(v){
        var t=/^[a-zA-Z_\- ]+$/;
        return t.test(v);
      }}),new Ext.form.TextField({name:"lastname",fieldLabel:"Lastname",allowBlank:false,validator:function(v){
        var t=/^[a-zA-Z_\- ]+$/;
        return t.test(v);
      }})]}),new Ext.UXWizCard({title:"Your email-address",monitorValid:true,defaults:{labelStyle:"font-size:11px"},items:[{border:false,bodyStyle:"background:none;padding-bottom:30px;",html:" Please enter your email-address."},new Ext.form.TextField({name:"email",fieldLabel:"Email-Address",allowBlank:false,vtype:"email"})]}),new Ext.UXWizCard({title:"Finished!",monitorValid:true,items:[{border:false,bodyStyle:"background:none;",html:"Thank you for testing this wizard. Your data has been collected "+"and can be accessed via a call to <pre><code>this.getWizardData</code></pre>"+"When you click on the \"finish\"-button, the \"finish\"-event will be fired.<br/>"+"If no attached listener for this event returns \"false\", this dialog will be "+"closed. <br />"}]})]});
wizard.on("finish",function(t,d){
  alert(Ext.encode(d));
  return false;
},wizard);
wizard.show();

 测试效果图:


extjs3支持按步骤处理(向导)控件
 官方网站:

http://www.siteartwork.de/wizardcomponent