* @link http://www.pradosoft.com/
* @copyright Copyright © 2005 PradoSoft
* @license http://www.pradosoft.com/license/
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
*/
Prado::using('System.Web.UI.WebControls.TMultiView');
Prado::using('System.Web.UI.WebControls.TPanel');
Prado::using('System.Web.UI.WebControls.TButton');
Prado::using('System.Web.UI.WebControls.TLinkButton');
Prado::using('System.Web.UI.WebControls.TImageButton');
Prado::using('System.Web.UI.WebControls.TDataList');
/**
* Class TWizard.
*
* TWizard splits a large form and present the user with a series of smaller
* form to complete. TWizard is analogous to the installation wizard commonly
* used to install software in Windows.
*
* The smaller forms are called wizard steps ({@link TWizardStep}, which can be accessed via
* {@link getWizardSteps WizardSteps}. In template, wizard steps can be added
* into a wizard using the following syntax,
*
*
*
* content in step 1, may contain other controls
*
*
* content in step 2, may contain other controls
*
*
*
*
* Each wizard step can be one of the following types:
* - Start : the first step in the wizard.
* - Step : the internal steps in the wizard.
* - Finish : the last step that allows user interaction.
* - Complete : the step that shows a summary to user (no interaction is allowed).
* - Auto : the step type is determined by wizard automatically.
* At any time, only one step is visible to end-users, which can be obtained
* by {@link getActiveStep ActiveStep}. Its index in the step collection is given by
* {@link getActiveStepIndex ActiveStepIndex}.
*
* Wizard content can be customized in many ways.
*
* The layout of a wizard consists of four parts: header, step content, navigation
* and side bar. Their content are affected by the following properties, respectively,
* - header: {@link setHeaderText HeaderText} and {@link setHeaderTemplate HeaderTemplate}.
* If both are present, the latter takes precedence.
* - step: {@link getWizardSteps WizardSteps}.
* - navigation: {@link setStartNavigationTemplate StartNavigationTemplate},
* {@link setStepNavigationTemplate StepNavigationTemplate},
* {@link setFinishNavigationTemplate FinishNavigationTemplate}.
* Default templates will be used if above templates are not set.
* - side bar: {@link setSideBarTemplate SideBarTemplate}.
* A default template will be used if this template is not set.
* Its visibility is toggled by {@link setDisplaySideBar DisplaySideBar}.
*
* The style of these wizard layout components can be customized via the following style properties,
* - header: {@link getHeaderStyle HeaderStyle}.
* - step: {@link getStepStyle StepStyle}.
* - navigation: {@link getNavigationStyle NavigationStyle},
* {@link getStartNextButtonStyle StartNextButtonStyle},
* {@link getStepNextButtonStyle StepNextButtonStyle},
* {@link getStepPreviousButtonStyle StepPreviousButtonStyle},
* {@link getFinishPreviousButtonStyle FinishPreviousButtonStyle},
* {@link getFinishCompleteButtonStyle FinishCompleteButtonStyle},
* {@link getCancelButtonStyle CancelButtonStyle}.
* - side bar: {@link getSideBarStyle SideBarStyle} and {@link getSideBarButtonStyle SideBarButtonStyle}.
*
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizard extends TWebControl implements INamingContainer
{
/**
* Wizard step types.
*/
const ST_AUTO='Auto';
const ST_START='Start';
const ST_STEP='Step';
const ST_FINISH='Finish';
const ST_COMPLETE='Complete';
/**
* Navigation commands.
*/
const CMD_PREVIOUS='PreviousStep';
const CMD_NEXT='NextStep';
const CMD_CANCEL='Cancel';
const CMD_COMPLETE='Complete';
const CMD_MOVETO='MoveTo';
/**
* Side bar button ID
*/
const ID_SIDEBAR_BUTTON='SideBarButton';
/**
* Side bar data list
*/
const ID_SIDEBAR_LIST='SideBarList';
/**
* @var TMultiView multiview that contains the wizard steps
*/
private $_multiView=null;
/**
* @var mixed navigation template for the start step.
*/
private $_startNavigationTemplate=null;
/**
* @var mixed navigation template for internal steps.
*/
private $_stepNavigationTemplate=null;
/**
* @var mixed navigation template for the finish step.
*/
private $_finishNavigationTemplate=null;
/**
* @var mixed template for wizard header.
*/
private $_headerTemplate=null;
/**
* @var mixed template for the side bar.
*/
private $_sideBarTemplate=null;
/**
* @var TWizardStepCollection
*/
private $_wizardSteps=null;
/**
* @var TPanel container of the wizard header
*/
private $_header;
/**
* @var TPanel container of the wizard step content
*/
private $_stepContent;
/**
* @var TPanel container of the wizard side bar
*/
private $_sideBar;
/**
* @var TPanel navigation panel
*/
private $_navigation;
/**
* @var TWizardNavigationContainer container of the start navigation
*/
private $_startNavigation;
/**
* @var TWizardNavigationContainer container of the step navigation
*/
private $_stepNavigation;
/**
* @var TWizardNavigationContainer container of the finish navigation
*/
private $_finishNavigation;
/**
* @var boolean whether ActiveStepIndex was already set
*/
private $_activeStepIndexSet=false;
/**
* @var TDataList side bar data list.
*/
private $_sideBarDataList;
/**
* @return string tag name for the wizard
*/
protected function getTagName()
{
return 'div';
}
/**
* Adds {@link TWizardStep} objects into step collection.
* This method overrides the parent implementation and is
* invoked when template is being instantiated.
* @param mixed object instantiated in template
*/
public function addParsedObject($object)
{
if(is_object($object))
$this->getWizardSteps()->add($object);
}
/**
* @return TWizardStep the currently active wizard step
*/
public function getActiveStep()
{
return $this->getMultiView()->getActiveView();
}
/**
* @param TWizardStep step to be activated
*/
public function setActiveStep($step)
{
if(($index=$this->getWizardSteps()->indexOf($step))<0)
throw new TInvalidOperationException('wizard_step_invalid');
$this->setActiveStepIndex($index);
}
/**
* @return integer the zero-based index of the active wizard step
*/
public function getActiveStepIndex()
{
return $this->getMultiView()->getActiveViewIndex();
}
/**
* @param integer the zero-based index of the wizard step to be activated
*/
public function setActiveStepIndex($value)
{
$value=TPropertyValue::ensureInteger($value);
$multiView=$this->getMultiView();
if($multiView->getActiveViewIndex()!==$value)
{
$multiView->setActiveViewIndex($value);
$this->_activeStepIndexSet=true;
if($this->_sideBarDataList!==null && $this->getSideBarTemplate()!==null)
{
$this->_sideBarDataList->setSelectedItemIndex($this->getActiveStepIndex());
$this->_sideBarDataList->dataBind();
}
}
}
/**
* @return TWizardStepCollection collection of wizard steps
*/
public function getWizardSteps()
{
if($this->_wizardSteps===null)
$this->_wizardSteps=new TWizardStepCollection($this);
return $this->_wizardSteps;
}
/**
* @return boolean whether to display a cancel button in each wizard step. Defaults to false.
*/
public function getDisplayCancelButton()
{
return $this->getViewState('DisplayCancelButton',false);
}
/**
* @param boolean whether to display a cancel button in each wizard step.
*/
public function setDisplayCancelButton($value)
{
$this->setViewState('DisplayCancelButton',TPropertyValue::ensureBoolean($value),false);
}
/**
* @return boolean whether to display a side bar that contains links to wizard steps. Defaults to true.
*/
public function getDisplaySideBar()
{
return $this->getViewState('DisplaySideBar',true);
}
/**
* @param boolean whether to display a side bar that contains links to wizard steps.
*/
public function setDisplaySideBar($value)
{
$this->setViewState('DisplaySideBar',TPropertyValue::ensureBoolean($value),true);
$this->requiresControlsRecreation();
}
/**
* @return ITemplate navigation template for the start step. Defaults to null.
*/
public function getStartNavigationTemplate()
{
return $this->_startNavigationTemplate;
}
/**
* @param ITemplate navigation template for the start step.
*/
public function setStartNavigationTemplate($value)
{
$this->_startNavigationTemplate=$value;
$this->requiresControlsRecreation();
}
/**
* @return ITemplate navigation template for internal steps. Defaults to null.
*/
public function getStepNavigationTemplate()
{
return $this->_stepNavigationTemplate;
}
/**
* @param ITemplate navigation template for internal steps.
*/
public function setStepNavigationTemplate($value)
{
$this->_stepNavigationTemplate=$value;
$this->requiresControlsRecreation();
}
/**
* @return ITemplate navigation template for the finish step. Defaults to null.
*/
public function getFinishNavigationTemplate()
{
return $this->_finishNavigationTemplate;
}
/**
* @param ITemplate navigation template for the finish step.
*/
public function setFinishNavigationTemplate($value)
{
$this->_finishNavigationTemplate=$value;
$this->requiresControlsRecreation();
}
/**
* @return ITemplate template for wizard header. Defaults to null.
*/
public function getHeaderTemplate()
{
return $this->_headerTemplate;
}
/**
* @param ITemplate template for wizard header.
*/
public function setHeaderTemplate($value)
{
$this->_headerTemplate=$value;
$this->requiresControlsRecreation();
}
/**
* @return ITemplate template for the side bar. Defaults to null.
*/
public function getSideBarTemplate()
{
return $this->_sideBarTemplate;
}
/**
* @param ITemplate template for the side bar.
*/
public function setSideBarTemplate($value)
{
$this->_sideBarTemplate=$value;
$this->requiresControlsRecreation();
}
/**
* @return string header text. Defaults to ''.
*/
public function getHeaderText()
{
return $this->getViewState('HeaderText','');
}
/**
* @param string header text.
*/
public function setHeaderText($value)
{
$this->setViewState('HeaderText',TPropertyValue::ensureString($value),'');
}
/**
* @return string the URL that the browser will be redirected to if the cancel button in the
* wizard is clicked. Defaults to ''.
*/
public function getCancelDestinationUrl()
{
return $this->getViewState('CancelDestinationUrl','');
}
/**
* @param string the URL that the browser will be redirected to if the cancel button in the
* wizard is clicked.
*/
public function setCancelDestinationUrl($value)
{
$this->setViewState('CancelDestinationUrl',TPropertyValue::ensureString($value),'');
}
/**
* @return string the URL that the browser will be redirected to if the wizard finishes.
* Defaults to ''.
*/
public function getFinishDestinationUrl()
{
return $this->getViewState('FinishDestinationUrl','');
}
/**
* @param string the URL that the browser will be redirected to if the wizard finishes.
*/
public function setFinishDestinationUrl($value)
{
$this->setViewState('FinishDestinationUrl',TPropertyValue::ensureString($value),'');
}
/**
* @return TStyle the style for the buttons displayed in the side bar.
*/
public function getSideBarButtonStyle()
{
if(($style=$this->getViewState('SideBarButtonStyle',null))===null)
{
$style=new TStyle;
$this->setViewState('SideBarButtonStyle',$style,null);
}
return $style;
}
/**
* @return TStyle the style common for all navigation buttons.
*/
public function getNavigationButtonStyle()
{
if(($style=$this->getViewState('NavigationButtonStyle',null))===null)
{
$style=new TStyle;
$this->setViewState('NavigationButtonStyle',$style,null);
}
return $style;
}
/**
* @return TWizardNavigationButtonStyle the style for the next button in the start wizard step.
*/
public function getStartNextButtonStyle()
{
if(($style=$this->getViewState('StartNextButtonStyle',null))===null)
{
$style=new TWizardNavigationButtonStyle;
$style->setButtonText('Next');
$this->setViewState('StartNextButtonStyle',$style,null);
}
return $style;
}
/**
* @return TWizardNavigationButtonStyle the style for the next button in each internal wizard step.
*/
public function getStepNextButtonStyle()
{
if(($style=$this->getViewState('StepNextButtonStyle',null))===null)
{
$style=new TWizardNavigationButtonStyle;
$style->setButtonText('Next');
$this->setViewState('StepNextButtonStyle',$style,null);
}
return $style;
}
/**
* @return TWizardNavigationButtonStyle the style for the previous button in the start wizard step.
*/
public function getStepPreviousButtonStyle()
{
if(($style=$this->getViewState('StepPreviousButtonStyle',null))===null)
{
$style=new TWizardNavigationButtonStyle;
$style->setButtonText('Previous');
$this->setViewState('StepPreviousButtonStyle',$style,null);
}
return $style;
}
/**
* @return TWizardNavigationButtonStyle the style for the complete button in the finish wizard step.
*/
public function getFinishCompleteButtonStyle()
{
if(($style=$this->getViewState('FinishCompleteButtonStyle',null))===null)
{
$style=new TWizardNavigationButtonStyle;
$style->setButtonText('Complete');
$this->setViewState('FinishCompleteButtonStyle',$style,null);
}
return $style;
}
/**
* @return TWizardNavigationButtonStyle the style for the previous button in the start wizard step.
*/
public function getFinishPreviousButtonStyle()
{
if(($style=$this->getViewState('FinishPreviousButtonStyle',null))===null)
{
$style=new TWizardNavigationButtonStyle;
$style->setButtonText('Previous');
$this->setViewState('FinishPreviousButtonStyle',$style,null);
}
return $style;
}
/**
* @return TWizardNavigationButtonStyle the style for the cancel button
*/
public function getCancelButtonStyle()
{
if(($style=$this->getViewState('CancelButtonStyle',null))===null)
{
$style=new TWizardNavigationButtonStyle;
$style->setButtonText('Cancel');
$this->setViewState('CancelButtonStyle',$style,null);
}
return $style;
}
/**
* @return TPanelStyle the style for the side bar.
*/
public function getSideBarStyle()
{
if(($style=$this->getViewState('SideBarStyle',null))===null)
{
$style=new TPanelStyle;
$this->setViewState('SideBarStyle',$style,null);
}
return $style;
}
/**
* @return TPanelStyle the style for the header.
*/
public function getHeaderStyle()
{
if(($style=$this->getViewState('HeaderStyle',null))===null)
{
$style=new TPanelStyle;
$this->setViewState('HeaderStyle',$style,null);
}
return $style;
}
/**
* @return TPanelStyle the style for each internal wizard step.
*/
public function getStepStyle()
{
if(($style=$this->getViewState('StepStyle',null))===null)
{
$style=new TPanelStyle;
$this->setViewState('StepStyle',$style,null);
}
return $style;
}
/**
* @return TPanelStyle the style for the navigation panel.
*/
public function getNavigationStyle()
{
if(($style=$this->getViewState('NavigationStyle',null))===null)
{
$style=new TPanelStyle;
$this->setViewState('NavigationStyle',$style,null);
}
return $style;
}
/**
* Raises OnActiveStepChanged event.
* This event is raised when the current visible step is changed in the
* wizard.
* @param TEventParameter event parameter
*/
public function onActiveStepChanged($param)
{
$this->raiseEvent('OnActiveStepChanged',$this,$param);
}
/**
* Raises OnCancelButtonClick event.
* This event is raised when a cancel navigation button is clicked in the
* current active step.
* @param TEventParameter event parameter
*/
public function onCancelButtonClick($param)
{
$this->raiseEvent('OnCancelButtonClick',$this,$param);
if(($url=$this->getCancelDestinationUrl())!=='')
$this->getResponse()->redirect($url);
}
/**
* Raises OnFinishButtonClick event.
* This event is raised when a finish navigation button is clicked in the
* current active step.
* @param TEventParameter event parameter
*/
public function onFinishButtonClick($param)
{
$this->raiseEvent('OnFinishButtonClick',$this,$param);
if(($url=$this->getFinishDestinationUrl())!=='')
$this->getResponse()->redirect($url);
}
/**
* Raises OnNextButtonClick event.
* This event is raised when a next navigation button is clicked in the
* current active step.
* @param TEventParameter event parameter
*/
public function onNextButtonClick($param)
{
$this->raiseEvent('OnNextButtonClick',$this,$param);
}
/**
* Raises OnPreviousButtonClick event.
* This event is raised when a previous navigation button is clicked in the
* current active step.
* @param TEventParameter event parameter
*/
public function onPreviousButtonClick($param)
{
$this->raiseEvent('OnPreviousButtonClick',$this,$param);
}
/**
* Raises OnSideBarButtonClick event.
* This event is raised when a link button in the side bar is clicked.
* @param TEventParameter event parameter
*/
public function onSideBarButtonClick($param)
{
$this->raiseEvent('OnSideBarButtonClick',$this,$param);
}
/**
* @return TMultiView the multiview holding wizard steps
*/
protected function getMultiView()
{
if($this->_multiView===null)
{
$this->_multiView=new TMultiView;
$this->_multiView->setID('WizardMultiView');
$this->_multiView->attachEventHandler('OnActiveViewChanged',array($this,'onActiveStepChanged'));
$this->_multiView->ignoreBubbleEvents();
}
return $this->_multiView;
}
/**
* Adds a wizard step to the multiview.
* This method should only be used by control developers.
* It is invoked when a step is added into the step collection of the wizard.
* @param TWizardStep wizard step to be added into multiview.
*/
public function addedWizardStep($step)
{
if(($wizard=$step->getWizard())!==null)
$wizard->getWizardSteps()->remove($step);
$step->setWizard($this);
$this->getMultiView()->getViews()->add($step);
$this->wizardStepsChanged();
}
/**
* Removes a wizard step from the multiview.
* This method should only be used by control developers.
* It is invoked when a step is removed from the step collection of the wizard.
* @param TWizardStep wizard step to be removed from multiview.
*/
public function removedWizardStep($step)
{
$this->getMultiView()->getViews()->remove($step);
$step->setWizard(null);
$this->wizardStepsChanged();
}
/**
* Creates the child controls of the wizard.
* This method overrides the parent implementation.
* @param TEventParameter event parameter
*/
public function onInit($param)
{
parent::onInit($param);
if($this->getActiveStepIndex()<0 && $this->getWizardSteps()->getCount()>0)
$this->setActiveStepIndex(0);
$this->ensureChildControls();
}
/**
* Saves the current active step index into history.
* This method is invoked by the framework when the control state is being saved.
*/
public function saveState()
{
$index=$this->getActiveStepIndex();
$history=$this->getHistory();
if(!$history->getCount() || $history->peek()!==$index)
$history->push($index);
}
/**
* Indicates the wizard needs to recreate all child controls.
*/
protected function requiresControlsRecreation()
{
if($this->getChildControlsCreated())
$this->setChildControlsCreated(false);
}
/**
* Renders the wizard.
* @param THtmlWriter
*/
public function render($writer)
{
$this->ensureChildControls();
$this->applyControlProperties();
parent::render($writer);
}
/**
* Applies various properties to the components of wizard
*/
protected function applyControlProperties()
{
$this->applyHeaderProperties();
$this->applySideBarProperties();
$this->applyStepContentProperties();
$this->applyNavigationProperties();
}
/**
* Applies properties to the wizard header
*/
protected function applyHeaderProperties()
{
if(($style=$this->getViewState('HeaderStyle',null))!==null)
$this->_header->getStyle()->mergeWith($style);
if($this->getHeaderTemplate()===null)
{
$this->_header->getControls()->clear();
$this->_header->getControls()->add($this->getHeaderText());
}
}
/**
* Applies properties to the wizard sidebar
*/
protected function applySideBarProperties()
{
$this->_sideBar->setVisible($this->getDisplaySideBar());
if($this->_sideBarDataList!==null && $this->getDisplaySideBar())
{
$this->_sideBarDataList->setDataSource($this->getWizardSteps());
$this->_sideBarDataList->setSelectedItemIndex($this->getActiveStepIndex());
$this->_sideBarDataList->dataBind();
if(($style=$this->getViewState('SideBarButtonStyle',null))!==null)
{
foreach($this->_sideBarDataList->getItems() as $item)
{
if(($button=$item->findControl('SideBarButton'))!==null)
$button->getStyle()->mergeWith($style);
}
}
}
if(($style=$this->getViewState('SideBarStyle',null))!==null)
$this->_sideBar->getStyle()->mergeWith($style);
}
/**
* Applies properties to the wizard step content
*/
protected function applyStepContentProperties()
{
if(($style=$this->getViewState('StepStyle',null))!==null)
$this->_stepContent->getStyle()->mergeWith($style);
}
/**
* Apply properties to various navigation panels.
*/
protected function applyNavigationProperties()
{
$wizardSteps=$this->getWizardSteps();
$activeStep=$this->getActiveStep();
$activeStepIndex=$this->getActiveStepIndex();
if(!$this->_navigation || $activeStepIndex<0 || $activeStepIndex>=$wizardSteps->getCount())
return;
// set visibility of different types of navigation panel
$showStandard=true;
foreach($wizardSteps as $step)
{
if(($step instanceof TTemplatedWizardStep) && ($container=$step->getNavigationContainer())!==null)
{
if($activeStep===$step)
{
$container->setVisible(true);
$showStandard=false;
}
else
$container->setVisible(false);
}
}
$activeStepType=$this->getStepType($activeStep);
if($activeStepType===self::ST_COMPLETE)
{
$this->_sideBar->setVisible(false);
$this->_header->setVisible(false);
}
$this->_startNavigation->setVisible($showStandard && $activeStepType===self::ST_START);
$this->_stepNavigation->setVisible($showStandard && $activeStepType===self::ST_STEP);
$this->_finishNavigation->setVisible($showStandard && $activeStepType===self::ST_FINISH);
if(($navigationStyle=$this->getViewState('NavigationStyle',null))!==null)
$this->_navigation->getStyle()->mergeWith($navigationStyle);
$displayCancelButton=$this->getDisplayCancelButton();
$cancelButtonStyle=$this->getCancelButtonStyle();
$buttonStyle=$this->getViewState('NavigationButtonStyle',null);
if($buttonStyle!==null)
$cancelButtonStyle->mergeWith($buttonStyle);
// apply styles to start navigation buttons
if(($cancelButton=$this->_startNavigation->getCancelButton())!==null)
{
$cancelButton->setVisible($displayCancelButton);
$cancelButtonStyle->apply($cancelButton);
}
if(($button=$this->_startNavigation->getNextButton())!==null)
{
$button->setVisible(true);
$style=$this->getStartNextButtonStyle();
if($buttonStyle!==null)
$style->mergeWith($buttonStyle);
$style->apply($button);
}
// apply styles to finish navigation buttons
if(($cancelButton=$this->_finishNavigation->getCancelButton())!==null)
{
$cancelButton->setVisible($displayCancelButton);
$cancelButtonStyle->apply($cancelButton);
}
if(($button=$this->_finishNavigation->getPreviousButton())!==null)
{
$button->setVisible($this->allowNavigationToPreviousStep());
$style=$this->getFinishPreviousButtonStyle();
if($buttonStyle!==null)
$style->mergeWith($buttonStyle);
$style->apply($button);
}
if(($button=$this->_finishNavigation->getCompleteButton())!==null)
{
$button->setVisible(true);
$style=$this->getFinishCompleteButtonStyle();
if($buttonStyle!==null)
$style->mergeWith($buttonStyle);
$style->apply($button);
}
// apply styles to step navigation buttons
if(($cancelButton=$this->_stepNavigation->getCancelButton())!==null)
{
$cancelButton->setVisible($displayCancelButton);
$cancelButtonStyle->apply($cancelButton);
}
if(($button=$this->_stepNavigation->getPreviousButton())!==null)
{
$button->setVisible($this->allowNavigationToPreviousStep());
$style=$this->getStepPreviousButtonStyle();
if($buttonStyle!==null)
$style->mergeWith($buttonStyle);
$style->apply($button);
}
if(($button=$this->_stepNavigation->getNextButton())!==null)
{
$button->setVisible(true);
$style=$this->getStepNextButtonStyle();
if($buttonStyle!==null)
$style->mergeWith($buttonStyle);
$style->apply($button);
}
}
/**
* @return TStack history containing step indexes that were navigated before
*/
protected function getHistory()
{
if(($history=$this->getControlState('History',null))===null)
{
$history=new TStack;
$this->setControlState('History',$history);
}
return $history;
}
/**
* Determines the type of the specified wizard step.
* @param TWizardStep
* @return string type of the step, 'Finish', 'Start', 'Step'.
*/
protected function getStepType($wizardStep)
{
if(($type=$wizardStep->getStepType())===self::ST_AUTO)
{
$steps=$this->getWizardSteps();
if(($index=$steps->indexOf($wizardStep))>=0)
{
$stepCount=$steps->getCount();
if($stepCount===1 || ($index<$stepCount-1 && $steps->itemAt($index+1)->getStepType()==='Complete'))
return self::ST_FINISH;
else if($index===0)
return self::ST_START;
else if($index===$stepCount-1)
return self::ST_FINISH;
else
return self::ST_STEP;
}
else
return $type;
}
else
return $type;
}
/**
* Clears up everything within the wizard.
*/
protected function reset()
{
$this->getControls()->clear();
$this->_header=null;
$this->_stepContent=null;
$this->_sideBar=null;
$this->_sideBarDataList=null;
$this->_navigation=null;
$this->_startNavigation=null;
$this->_stepNavigation=null;
$this->_finishNavigation=null;
}
/**
* Creates child controls within the wizard
*/
protected function createChildControls()
{
$this->reset();
$this->createSideBar();
$this->createHeader();
$this->createStepContent();
$this->createNavigation();
// $this->clearChildState();
}
/**
* Creates the wizard header.
*/
protected function createHeader()
{
$this->_header=new TPanel;
if(($template=$this->getHeaderTemplate())!==null)
$template->instantiateIn($this->_header);
else
$this->_header->getControls()->add($this->getHeaderText());
$this->getControls()->add($this->_header);
}
/**
* Creates the wizard side bar
*/
protected function createSideBar()
{
if($this->getDisplaySideBar())
{
if(($template=$this->getSideBarTemplate())===null)
$template=new TWizardSideBarTemplate;
$this->_sideBar=new TPanel;
$template->instantiateIn($this->_sideBar);
$this->getControls()->add($this->_sideBar);
if(($this->_sideBarDataList=$this->_sideBar->findControl(self::ID_SIDEBAR_LIST))!==null)
{
$this->_sideBarDataList->attachEventHandler('OnItemCommand',array($this,'dataListItemCommand'));
$this->_sideBarDataList->attachEventHandler('OnItemDataBound',array($this,'dataListItemDataBound'));
$this->_sideBarDataList->setDataSource($this->getWizardSteps());
$this->_sideBarDataList->setSelectedItemIndex($this->getActiveStepIndex());
$this->_sideBarDataList->dataBind();
}
}
else
{
$this->_sideBar=new TPanel;
$this->getControls()->add($this->_sideBar);
}
}
/**
* Event handler for sidebar datalist's OnItemCommand event.
* This method is used internally by wizard. It mainly
* sets the active step index according to the button clicked in the sidebar.
* @param mixed sender of the event
* @param TDataListCommandEventParameter
*/
public function dataListItemCommand($sender,$param)
{
$item=$param->getItem();
if($param->getCommandName()===self::CMD_MOVETO)
{
$stepIndex=$this->getActiveStepIndex();
$newStepIndex=TPropertyValue::ensureInteger($param->getCommandParameter());
$navParam=new TWizardNavigationEventParameter($stepIndex);
$navParam->setNextStepIndex($newStepIndex);
// if the button clicked causes validation which fails,
// by default we will cancel navigation to the new step
$button=$param->getCommandSource();
if($button->canGetProperty('CausesValidation') && $button->getCausesValidation() && ($page=$this->getPage())!==null && !$page->getIsValid())
$navParam->setCancelNavigation(true);
$this->_activeStepIndexSet=false;
$this->onSideBarButtonClick($navParam);
if(!$navParam->getCancelNavigation())
{
if(!$this->_activeStepIndexSet && $this->allowNavigationToStep($newStepIndex))
$this->setActiveStepIndex($newStepIndex);
}
else
$this->setActiveStepIndex($stepIndex);
}
}
/**
* Event handler for sidebar datalist's OnItemDataBound event.
* This method is used internally by wizard. It mainly configures
* the buttons in the sidebar datalist.
* @param mixed sender of the event
* @param TDataListItemEventParameter
*/
public function dataListItemDataBound($sender,$param)
{
$item=$param->getItem();
$itemType=$item->getItemType();
if($itemType==='Item' || $itemType==='AlternatingItem' || $itemType==='SelectedItem' || $itemType==='EditItem')
{
if(($button=$item->findControl(self::ID_SIDEBAR_BUTTON))!==null)
{
$step=$item->getDataItem();
if(($this->getStepType($step)==='Complete'))
$button->setEnabled(false);
if(($title=$step->getTitle())!=='')
$button->setText($title);
else
$button->setText($step->getID(false));
$index=$this->getWizardSteps()->indexOf($step);
$button->setCommandName(self::CMD_MOVETO);
$button->setCommandParameter("$index");
}
}
}
/**
* Creates wizard step content.
*/
protected function createStepContent()
{
foreach($this->getWizardSteps() as $step)
{
if($step instanceof TTemplatedWizardStep)
$step->ensureChildControls();
}
$multiView=$this->getMultiView();
$this->_stepContent=new TPanel;
$this->_stepContent->getControls()->add($multiView);
$multiView->setActiveViewIndex(0);
$this->getControls()->add($this->_stepContent);
}
/**
* Creates navigation panel.
*/
protected function createNavigation()
{
$this->_navigation=new TPanel;
$this->getControls()->add($this->_navigation);
$controls=$this->_navigation->getControls();
foreach($this->getWizardSteps() as $step)
{
if($step instanceof TTemplatedWizardStep)
{
$step->instantiateNavigationTemplate();
if(($panel=$step->getNavigationContainer())!==null)
$controls->add($panel);
}
}
$this->_startNavigation=$this->createStartNavigation();
$controls->add($this->_startNavigation);
$this->_stepNavigation=$this->createStepNavigation();
$controls->add($this->_stepNavigation);
$this->_finishNavigation=$this->createFinishNavigation();
$controls->add($this->_finishNavigation);
}
/**
* Creates start navigation panel.
*/
protected function createStartNavigation()
{
if(($template=$this->getStartNavigationTemplate())===null)
$template=new TWizardStartNavigationTemplate($this);
$navigation=new TWizardNavigationContainer;
$template->instantiateIn($navigation);
return $navigation;
}
/**
* Creates step navigation panel.
*/
protected function createStepNavigation()
{
if(($template=$this->getStepNavigationTemplate())===null)
$template=new TWizardStepNavigationTemplate($this);
$navigation=new TWizardNavigationContainer;
$template->instantiateIn($navigation);
return $navigation;
}
/**
* Creates finish navigation panel.
*/
protected function createFinishNavigation()
{
if(($template=$this->getFinishNavigationTemplate())===null)
$template=new TWizardFinishNavigationTemplate($this);
$navigation=new TWizardNavigationContainer;
$template->instantiateIn($navigation);
return $navigation;
}
/**
* Updates the sidebar datalist if any.
* This method is invoked when any wizard step is changed.
*/
public function wizardStepsChanged()
{
if($this->_sideBarDataList!==null)
{
$this->_sideBarDataList->setDataSource($this->getWizardSteps());
$this->_sideBarDataList->setSelectedIndex($this->getActiveStepIndex());
$this->_sideBarDataList->dataBind();
}
}
/**
* Determines the index of the previous step based on history.
* @param boolean whether the first item in the history stack should be popped
* up after calling this method.
*/
protected function getPreviousStepIndex($popStack)
{
$history=$this->getHistory();
if($history->getCount()>=0)
{
$activeStepIndex=$this->getActiveStepIndex();
$previousStepIndex=-1;
if($popStack)
{
$previousStepIndex=$history->pop();
if($activeStepIndex===$previousStepIndex && $history->getCount()>0)
$previousStepIndex=$history->pop();
}
else
{
$previousStepIndex=$history->peek();
if($activeStepIndex===$previousStepIndex && $history->getCount()>1)
{
$saveIndex=$history->pop();
$previousStepIndex=$history->peek();
$history->push($saveIndex);
}
}
return $activeStepIndex===$previousStepIndex ? -1 : $previousStepIndex;
}
else
return -1;
}
/**
* @return boolean whether navigation to the previous step is allowed
*/
protected function allowNavigationToPreviousStep()
{
if(($index=$this->getPreviousStepIndex(false))!==-1)
return $this->getWizardSteps()->itemAt($index)->getAllowReturn();
else
return false;
}
/**
* @param integer index of the step
* @return boolean whether navigation to the specified step is allowed
*/
protected function allowNavigationToStep($index)
{
if($this->getHistory()->contains($index))
return $this->getWizardSteps()->itemAt($index)->getAllowReturn();
else
return true;
}
/**
* Handles bubbled events.
* This method mainly translate certain command events into
* wizard-specific events.
* @param mixed sender of the original command event
* @param TEventParameter event parameter
*/
public function onBubbleEvent($sender,$param)
{
if($param instanceof TCommandEventParameter)
{
$command=$param->getCommandName();
if(strcasecmp($command,self::CMD_CANCEL)===0)
{
$this->onCancelButtonClick($param);
return true;
}
$type=$this->getStepType($this->getActiveStep());
$index=$this->getActiveStepIndex();
$navParam=new TWizardNavigationEventParameter($index);
$handled=false;
$movePrev=false;
$this->_activeStepIndexSet=false;
if(strcasecmp($command,self::CMD_NEXT)===0)
{
if($type!==self::ST_START && $type!==self::ST_STEP)
throw new TInvalidDataValueException('wizard_command_invalid',self::CMD_NEXT);
if($index<$this->getWizardSteps()->getCount()-1)
$navParam->setNextStepIndex($index+1);
$this->onNextButtonClick($navParam);
$handled=true;
}
else if(strcasecmp($command,self::CMD_PREVIOUS)===0)
{
if($type!==self::ST_FINISH && $type!==self::ST_STEP)
throw new TInvalidDataValueException('wizard_command_invalid',self::CMD_PREVIOUS);
$movePrev=true;
if(($prevIndex=$this->getPreviousStepIndex(false))>=0)
$navParam->setNextStepIndex($prevIndex);
$this->onPreviousButtonClick($navParam);
$handled=true;
}
else if(strcasecmp($command,self::CMD_COMPLETE)===0)
{
if($type!==self::ST_FINISH)
throw new TInvalidDataValueException('wizard_command_invalid',self::CMD_COMPLETE);
if($index<$this->getWizardSteps()->getCount()-1)
$navParam->setNextStepIndex($index+1);
$this->onFinishButtonClick($navParam);
$handled=true;
}
else if(strcasecmp($command,self::CMD_MOVETO)===0)
{
$navParam->setNextStepIndex(TPropertyValue::ensureInteger($param->getCommandParameter()));
$handled=true;
}
if($handled)
{
if(!$navParam->getCancelNavigation())
{
$nextStepIndex=$navParam->getNextStepIndex();
if(!$this->_activeStepIndexSet && $this->allowNavigationToStep($nextStepIndex))
{
if($movePrev)
$this->getPreviousStepIndex(true); // pop out the previous move from history
$this->setActiveStepIndex($nextStepIndex);
}
}
else
$this->setActiveStepIndex($index);
return true;
}
}
return false;
}
}
/**
* TWizardNavigationButtonStyle class.
* TWizardNavigationButtonStyle defines the style applied to a wizard navigation button.
* The button type can be specified via {@link setButtonType ButtonType}, which
* can be 'Button', 'Image' or 'Link'.
* If the button is an image button, {@link setImageUrl ImageUrl} will be
* used to load the image for the button.
* Otherwise, {@link setButtonText ButtonText} will be displayed as the button caption.
*
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardNavigationButtonStyle extends TStyle
{
private $_imageUrl=null;
private $_buttonText=null;
private $_buttonType=null;
/**
* Sets the style attributes to default values.
* This method overrides the parent implementation by
* resetting additional TWizardNavigationButtonStyle specific attributes.
*/
public function reset()
{
parent::reset();
$this->_imageUrl=null;
$this->_buttonText=null;
$this->_buttonType=null;
}
/**
* Copies the fields in a new style to this style.
* If a style field is set in the new style, the corresponding field
* in this style will be overwritten.
* @param TStyle the new style
*/
public function copyFrom($style)
{
parent::copyFrom($style);
if($style instanceof TWizardNavigationButtonStyle)
{
if($this->_imageUrl===null && $style->_imageUrl!==null)
$this->_imageUrl=$style->_imageUrl;
if($this->_buttonText===null && $style->_buttonText!==null)
$this->_buttonText=$style->_buttonText;
if($this->_buttonType===null && $style->_buttonType!==null)
$this->_buttonType=$style->_buttonType;
}
}
/**
* Merges the style with a new one.
* If a style field is not set in this style, it will be overwritten by
* the new one.
* @param TStyle the new style
*/
public function mergeWith($style)
{
parent::mergeWith($style);
if($style instanceof TWizardNavigationButtonStyle)
{
if($style->_imageUrl!==null)
$this->_imageUrl=$style->_imageUrl;
if($style->_buttonText!==null)
$this->_buttonText=$style->_buttonText;
if($style->_buttonType!==null)
$this->_buttonType=$style->_buttonType;
}
}
/**
* @return string image URL for the image button
*/
public function getImageUrl()
{
return $this->_imageUrl===null?'':$this->_imageUrl;
}
/**
* @param string image URL for the image button
*/
public function setImageUrl($value)
{
$this->_imageUrl=$value;
}
/**
* @return string button caption
*/
public function getButtonText()
{
return $this->_buttonText===null?'':$this->_buttonText;
}
/**
* @param string button caption
*/
public function setButtonText($value)
{
$this->_buttonText=$value;
}
/**
* @return string button type. Default to 'Button'.
*/
public function getButtonType()
{
return $this->_buttonType===null?'Button':$this->_buttonType;
}
/**
* @param string button type. Valid values include 'Button', 'Image', 'Link'.
*/
public function setButtonType($value)
{
$this->_buttonType=TPropertyValue::ensureEnum($value,'Button','Image','Link');
}
/**
* Applies this style to the specified button
* @param mixed button to be applied with this style
*/
public function apply($button)
{
if($button instanceof TImageButton)
{
if($button->getImageUrl()==='')
$button->setImageUrl($this->getImageUrl());
}
if($button->getText()==='')
$button->setText($this->getButtonText());
$button->getStyle()->mergeWith($this);
}
}
/**
* TWizardStep class.
*
* TWizardStep represents a wizard step. The wizard owning the step
* can be obtained by {@link getWizard Wizard}.
* To specify the type of the step, set {@link setStepType StepType};
* For step title, set {@link setTitle Title}. If a step can be re-visited,
* set {@link setAllowReturn AllowReturn} to true.
*
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardStep extends TView
{
private $_wizard;
/**
* @return TWizard the wizard owning this step
*/
public function getWizard()
{
return $this->_wizard;
}
/**
* Sets the wizard owning this step.
* This method is used internally by {@link TWizard}.
* @param TWizard the wizard owning this step
*/
public function setWizard($wizard)
{
$this->_wizard=$wizard;
}
/**
* @return string the title for this step.
*/
public function getTitle()
{
return $this->getViewState('Title','');
}
/**
* @param string the title for this step.
*/
public function setTitle($value)
{
$this->setViewState('Title',$value,'');
if($this->_wizard)
$this->_wizard->wizardStepsChanged();
}
/**
* @return boolean whether this step can be re-visited. Default to true.
*/
public function getAllowReturn()
{
return $this->getViewState('AllowReturn',true);
}
/**
* @param boolean whether this step can be re-visited.
*/
public function setAllowReturn($value)
{
$this->setViewState('AllowReturn',TPropertyValue::ensureBoolean($value),true);
}
/**
* @return string the wizard step type. Defaults to 'Auto'.
*/
public function getStepType()
{
return $this->getViewState('StepType',TWizard::ST_AUTO);
}
/**
* @param string the wizard step type. Valid values include 'Auto', 'Complete', 'Start', 'Step', 'Finish'.
*/
public function setStepType($type)
{
$type=TPropertyValue::ensureEnum($type,TWizard::ST_AUTO,TWizard::ST_COMPLETE,TWizard::ST_STEP,TWizard::ST_START,TWizard::ST_FINISH);
if($type!==$this->getStepType())
{
$this->setViewState('StepType',$type,TWizard::ST_AUTO);
if($this->_wizard)
$this->_wizard->wizardStepsChanged();
}
}
}
/**
* TCompleteWizardStep class.
*
* TCompleteWizardStep represents a wizard step of type 'Complete'.
*
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TCompleteWizardStep extends TWizardStep
{
/**
* @return string the wizard step type. Always 'Complete'.
*/
public function getStepType()
{
return 'Complete';
}
/**
* @param string the wizard step type.
* @throws TInvalidOperationException whenever this method is invoked.
*/
public function setStepType($value)
{
throw new TInvalidOperationException('completewizardstep_steptype_readonly');
}
}
/**
* TTemplatedWizardStep class.
*
* TTemplatedWizardStep represents a wizard step whose content and navigation
* can be customized using templates. To customize the step content, specify
* {@link setContentTemplate ContentTemplate}. To customize navigation specific
* to the step, specify {@link setNavigationTemplate NavigationTemplate}. Note,
* if the navigation template is not specified, default navigation will be used.
*
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TTemplatedWizardStep extends TWizardStep implements INamingContainer
{
/**
* @var ITemplate the template for displaying the navigation UI of a wizard step.
*/
private $_navigationTemplate=null;
/**
* @var ITemplate the template for displaying the content within the wizard step.
*/
private $_contentTemplate=null;
/**
* @var TWizardNavigationContainer
*/
private $_navigationContainer=null;
/**
* Forbids any body content.
* This method overrides the parent implementation and is
* invoked when template is being instantiated.
* @param mixed object instantiated in template
*/
public function addParsedObject($object)
{
}
/**
* Creates child controls.
* This method mainly instantiates the content template, if any.
*/
protected function createChildControls()
{
$this->getControls()->clear();
if($this->_contentTemplate)
$this->_contentTemplate->instantiateIn($this);
}
/**
* Ensures child controls are created.
* @param mixed event parameter
*/
public function onInit($param)
{
parent::onInit($param);
$this->ensureChildControls();
}
/**
* @return ITemplate the template for the content of the wizard step.
*/
public function getContentTemplate()
{
return $this->_contentTemplate;
}
/**
* @param ITemplate the template for the content of the wizard step.
*/
public function setContentTemplate($value)
{
$this->_contentTemplate=$value;
}
/**
* @return ITemplate the template for displaying the navigation UI of a wizard step. Defaults to null.
*/
public function getNavigationTemplate()
{
return $this->_navigationTemplate;
}
/**
* @param ITemplate the template for displaying the navigation UI of a wizard step.
*/
public function setNavigationTemplate($value)
{
$this->_navigationTemplate=$value;
}
/**
* @return TWizardNavigationContainer the control containing the navigation.
* It could be null if no navigation template is specified.
*/
public function getNavigationContainer()
{
return $this->_navigationContainer;
}
/**
* Instantiates the navigation template if any
*/
public function instantiateNavigationTemplate()
{
if(!$this->_navigationContainer && $this->_navigationTemplate)
{
$this->_navigationContainer=new TWizardNavigationContainer;
$this->_navigationTemplate->instantiateIn($this->_navigationContainer);
}
}
}
/**
* TWizardStepCollection class.
*
* TWizardStepCollection represents the collection of wizard steps owned
* by a {@link TWizard}.
*
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardStepCollection extends TList
{
/**
* @var TWizard
*/
private $_wizard;
/**
* Constructor.
* @param TWizard wizard that owns this collection
*/
public function __construct(TWizard $wizard)
{
$this->_wizard=$wizard;
}
/**
* Inserts an item at the specified position.
* This method overrides the parent implementation by checking if
* the item being added is a {@link TWizardStep}.
* @param integer the speicified position.
* @param mixed new item
*/
public function insertAt($index,$item)
{
if($item instanceof TWizardStep)
{
parent::insertAt($index,$item);
$this->_wizard->addedWizardStep($item);
}
else
throw new TInvalidDataTypeException('wizardstepcollection_wizardstepbase_required');
}
/**
* Removes an item at the specified position.
* @param integer the index of the item to be removed.
* @return mixed the removed item.
*/
public function removeAt($index)
{
$step=parent::removeAt($index);
$this->_wizard->removedWizardStep($step);
return $step;
}
}
/**
* TWizardNavigationContainer class.
*
* TWizardNavigationContainer represents a control containing
* a wizard navigation. The navigation may contain a few buttons, including
* {@link getPreviousButton PreviousButton}, {@link getNextButton NextButton},
* {@link getCancelButton CancelButton}, {@link getCompleteButton CompleteButton}.
*
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardNavigationContainer extends TControl implements INamingContainer
{
private $_previousButton=null;
private $_nextButton=null;
private $_cancelButton=null;
private $_completeButton=null;
/**
* @return mixed the previous button
*/
public function getPreviousButton()
{
return $this->_previousButton;
}
/**
* @param mixed the previous button
*/
public function setPreviousButton($value)
{
$this->_previousButton=$value;
}
/**
* @return mixed the next button
*/
public function getNextButton()
{
return $this->_nextButton;
}
/**
* @param mixed the next button
*/
public function setNextButton($value)
{
$this->_nextButton=$value;
}
/**
* @return mixed the cancel button
*/
public function getCancelButton()
{
return $this->_cancelButton;
}
/**
* @param mixed the cancel button
*/
public function setCancelButton($value)
{
$this->_cancelButton=$value;
}
/**
* @return mixed the complete button
*/
public function getCompleteButton()
{
return $this->_completeButton;
}
/**
* @param mixed the complete button
*/
public function setCompleteButton($value)
{
$this->_completeButton=$value;
}
}
/**
* TWizardNavigationEventParameter class.
*
* TWizardNavigationEventParameter represents the parameter for
* {@link TWizard}'s navigation events.
*
* The index of the currently active step can be obtained from
* {@link getCurrentStepIndex CurrentStepIndex}, while the index
* of the candidate new step is in {@link getNextStepIndex NextStepIndex}.
* By modifying {@link setNextStepIndex NextStepIndex}, the new step
* can be changed to another one. If there is anything wrong with
* the navigation and it is not wanted, set {@link setCancelNavigation CancelNavigation}
* to true.
*
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardNavigationEventParameter extends TEventParameter
{
private $_cancel=false;
private $_currentStep;
private $_nextStep;
/**
* Constructor.
* @param integer current step index
*/
public function __construct($currentStep)
{
$this->_currentStep=$currentStep;
$this->_nextStep=$currentStep;
}
/**
* @return integer the zero-based index of the currently active step.
*/
public function getCurrentStepIndex()
{
return $this->_currentStep;
}
/**
* @return integer the zero-based index of the next step. Default to {@link getCurrentStepIndex CurrentStepIndex}.
*/
public function getNextStepIndex()
{
return $this->_nextStep;
}
/**
* @param integer the zero-based index of the next step.
*/
public function setNextStepIndex($index)
{
$this->_nextStep=TPropertyValue::ensureInteger($index);
}
/**
* @return boolean whether navigation to the next step should be canceled. Default to false.
*/
public function getCancelNavigation()
{
return $this->_cancel;
}
/**
* @param boolean whether navigation to the next step should be canceled.
*/
public function setCancelNavigation($value)
{
$this->_cancel=TPropertyValue::ensureBoolean($value);
}
}
/**
* TWizardSideBarTemplate class.
* TWizardSideBarTemplate is the default template for wizard sidebar.
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardSideBarTemplate extends TComponent implements ITemplate
{
/**
* Instantiates the template.
* It creates a {@link TDataList} control.
* @param TControl parent to hold the content within the template
*/
public function instantiateIn($parent)
{
$dataList=new TDataList;
$dataList->setID(TWizard::ID_SIDEBAR_LIST);
$dataList->getSelectedItemStyle()->getFont()->setBold(true);
$dataList->setItemTemplate(new TWizardSideBarListItemTemplate);
$parent->getControls()->add($dataList);
}
}
/**
* TWizardSideBarListItemTemplate class.
* TWizardSideBarListItemTemplate is the default template for each item in the sidebar datalist.
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardSideBarListItemTemplate extends TComponent implements ITemplate
{
/**
* Instantiates the template.
* It creates a {@link TLinkButton}.
* @param TControl parent to hold the content within the template
*/
public function instantiateIn($parent)
{
$button=new TLinkButton;
$button->setID(TWizard::ID_SIDEBAR_BUTTON);
$parent->getControls()->add($button);
}
}
/**
* TWizardNavigationTemplate class.
* TWizardNavigationTemplate is the base class for various navigation templates.
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardNavigationTemplate extends TComponent implements ITemplate
{
private $_wizard;
/**
* Constructor.
* @param TWizard the wizard owning this template
*/
public function __construct($wizard)
{
$this->_wizard=$wizard;
}
/**
* @return TWizard the wizard owning this template
*/
public function getWizard()
{
return $this->_wizard;
}
/**
* Instantiates the template.
* Derived classes should override this method.
* @param TControl parent to hold the content within the template
*/
public function instantiateIn($parent)
{
}
/**
* Creates a navigation button.
* It creates a {@link TButton}, {@link TLinkButton}, or {@link TImageButton},
* depending on the given parameters.
* @param TWizardNavigationButtonStyle button style
* @param boolean whether the button should cause validation
* @param string command name for the button's OnCommand event
*/
protected function createNavigationButton($buttonStyle,$causesValidation,$commandName)
{
switch($buttonStyle->getButtonType())
{
case 'Button':
$button=new TButton;
break;
case 'Link' :
$button=new TLinkButton;
break;
case 'Image' :
$button=new TImageButton;
$button->setImageUrl($buttonStyle->getImageUrl());
break;
default:
throw new TInvalidDataValueException('wizard_buttontype_unknown',$buttonStyle->getButtonType());
}
$button->setText($buttonStyle->getButtonText());
$button->setCausesValidation($causesValidation);
$button->setCommandName($commandName);
return $button;
}
}
/**
* TWizardStartNavigationTemplate class.
* TWizardStartNavigationTemplate is the template used as default wizard start navigation panel.
* It consists of two buttons, Next and Cancel.
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardStartNavigationTemplate extends TWizardNavigationTemplate
{
/**
* Instantiates the template.
* @param TControl parent to hold the content within the template
*/
public function instantiateIn($parent)
{
$nextButton=$this->createNavigationButton($this->getWizard()->getStartNextButtonStyle(),true,TWizard::CMD_NEXT);
$cancelButton=$this->createNavigationButton($this->getWizard()->getCancelButtonStyle(),false,TWizard::CMD_CANCEL);
$controls=$parent->getControls();
$controls->add($nextButton);
$controls->add("\n");
$controls->add($cancelButton);
$parent->setNextButton($nextButton);
$parent->setCancelButton($cancelButton);
}
}
/**
* TWizardFinishNavigationTemplate class.
* TWizardFinishNavigationTemplate is the template used as default wizard finish navigation panel.
* It consists of three buttons, Previous, Complete and Cancel.
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardFinishNavigationTemplate extends TWizardNavigationTemplate
{
/**
* Instantiates the template.
* @param TControl parent to hold the content within the template
*/
public function instantiateIn($parent)
{
$previousButton=$this->createNavigationButton($this->getWizard()->getFinishPreviousButtonStyle(),false,TWizard::CMD_PREVIOUS);
$completeButton=$this->createNavigationButton($this->getWizard()->getFinishCompleteButtonStyle(),true,TWizard::CMD_COMPLETE);
$cancelButton=$this->createNavigationButton($this->getWizard()->getCancelButtonStyle(),false,TWizard::CMD_CANCEL);
$controls=$parent->getControls();
$controls->add($previousButton);
$controls->add("\n");
$controls->add($completeButton);
$controls->add("\n");
$controls->add($cancelButton);
$parent->setPreviousButton($previousButton);
$parent->setCompleteButton($completeButton);
$parent->setCancelButton($cancelButton);
}
}
/**
* TWizardStepNavigationTemplate class.
* TWizardStepNavigationTemplate is the template used as default wizard step navigation panel.
* It consists of three buttons, Previous, Next and Cancel.
* @author Qiang Xue
* @version $Revision: $ $Date: $
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TWizardStepNavigationTemplate extends TWizardNavigationTemplate
{
/**
* Instantiates the template.
* @param TControl parent to hold the content within the template
*/
public function instantiateIn($parent)
{
$previousButton=$this->createNavigationButton($this->getWizard()->getStepPreviousButtonStyle(),false,TWizard::CMD_PREVIOUS);
$nextButton=$this->createNavigationButton($this->getWizard()->getStepNextButtonStyle(),true,TWizard::CMD_NEXT);
$cancelButton=$this->createNavigationButton($this->getWizard()->getCancelButtonStyle(),false,TWizard::CMD_CANCEL);
$controls=$parent->getControls();
$controls->add($previousButton);
$controls->add("\n");
$controls->add($nextButton);
$controls->add("\n");
$controls->add($cancelButton);
$parent->setPreviousButton($previousButton);
$parent->setNextButton($nextButton);
$parent->setCancelButton($cancelButton);
}
}
?>