* @version $Revision: 1.8 $ $Date: 2005/12/17 06:11:28 $ * @package System.Web.UI.WebControls */ /** * TWizard splits a large form and present the user with a series * of smaller form to complete. The TWizard is analogous to the * installation wizard commonly used to install software in Windows. * * TWizard centralizes the required events to manipulate the flow of * the form. It also renders the appropriate step along with the navigation * elements. The wizard allows the steps to be presented linearly or otherwise * in a nonlinear fashion. That is, the forms can be filled sequentially or * if permitted allowed the user to choose which ever step he/she wishes. * In addition, the steps can be programmed to be skipped or repeated. * * A simple example of 3 steps. * * * * Full name: * * * * Telephone Number: * * Email: * * * * * * * * * *
Name:<%= $this->Page->ContactWizard->Name->Text %>
Phone:<%= $this->Page->ContactWizard->Phone->Text %>
Email:<%= $this->Page->ContactWizard->Email->Text %>
*
*
*
* * TWizard also intercepts the following bubbled events. E.g TButton * has CommandName and CommandParameter properties that bubbles as * "OnBubbleEvent". The following are the supported bubble event names * and how TWizard handles them. * * Bubble Events * - next, TWizard fires OnNextCommand event. * - previous, TWizard fires OnPreviousCommand event. * - finish, TWizard fires OnFinishCommand event. * - cancel, TWizard fires OnCancelCommand event. * - jumpto, TWizard fires OnJumpToCommand event. * jumpto requires a parameter, the destination step. * * E.g. anywhere within the TWizard, a button like the following * * when click will bubble to TWizard and in turn fires the OnJumpToCommand * with parameter value of "2". * * Namespace: System.Web.UI.WebControls * * Properties * - ActiveStep, TWizardStep, *
Gets the current active step. * - ActiveStepIndex, integer, *
Gets or sets the active step specified by a zero-starting index. * - DisplaySideBar, boolean *
isSideBarVisible or setDisplaySideBar, show or hides the side bar. * - FinishStepButtonText, string *
Gets or sets the string for the "Finish" button. * - NextStepButtonText, string *
Gets or sets the string for the "Next" button. * - PreviousStepButtonText, string *
Gets or sets the string for the "Previous" button. * - CancelButtonText, string *
Gets or sets the string for the "Cancel" button. * * Events * - OnStepChanged Occurs when the step is changed. * - OnCancelCommand Occurs when the "Cancel" button is pressed. * - OnFinishCommand Occurs when the "Finish" button is pressed. * - OnNextCommand Occurs when the "Next" button is pressed. * - OnPreviousCommand Occurs when the "Previous" button is pressed. * - OnJumpToCommand Occurs when the "JumpTo" button is pressed. * * @author Xiang Wei Zhuo * @version v1.0, last update on Sat Dec 11 15:25:11 EST 2004 * @package System.Web.UI.WebControls */ class TWizard extends TPanel { /** * The command name for the OnNextCommand. * @var string */ const CMD_NEXT = 'next'; /** * The command name for the OnPreviousCommand. * @var string */ const CMD_PREVIOUS = 'previous'; /** * The command name for the OnFinishCommand. * @var string */ const CMD_FINISH = 'finish'; /** * The command name for the OnCancelCommand. * @var string */ const CMD_CANCEL = 'cancel'; /** * The command name for the OnJumpToCommand. * @var string */ const CMD_JUMP = 'jumpto'; /** * A list of steps. * @var array */ protected $steps=array(); /** * A list of navigation templates, including built-in defaults. * @var array */ protected $navigation = array(); /** * A list of links for the side bar. * @var array */ protected $sidebarLinks = array(); /** * Set the Finish button text. * @param string button text */ public function setFinishStepButtonText($value) { $this->setViewState('FinishStepButtonText', $value, 'Finish'); } /** * Get the Finish button text. * @return string button text. */ public function getFinishStepButtonText() { return $this->getViewState('FinishStepButtonText', 'Finish'); } /** * Set the Next button text. * @param string button text */ public function setNextStepButtonText($value) { $this->setViewState('NextStepButtonText', $value, 'Next >'); } /** * Get the Next button text. * @return string button text. */ public function getNextStepButtonText() { return $this->getViewState('NextStepButtonText', 'Next >'); } /** * Set the Previous button text. * @param string button text */ public function setPreviousStepButtonText($value) { $this->setViewState('PreviousStepButtonText',$value, '< Back'); } /** * Get the Previous button text. * @return string button text. */ public function getPreviousStepButtonText() { return $this->getViewState('PreviousStepButtonText', '< Back'); } /** * Set the Cancel button text. * @param string button text */ public function setCancelButtonText($value) { $this->setViewState('CancelButtonText', $value, 'Cancel'); } /** * Get the Cancel button text. * @return string button text. */ public function getCancelButtonText() { return $this->getViewState('CancelButtonText', 'Cancel'); } /** * Show or hide the side bar. * @param boolean true to show the side bar, false hides it. */ public function setDisplaySideBar($value) { $this->setViewState('DisplaySideBar',$value,true); } /** * Determine if the side bar's visibility. * @return boolean true if visible, false otherwise. */ public function isSideBarVisible() { return $this->getViewState('DisplaySideBar',true); } /** * Get the current step. null if the ActiveStepIndex is not valid. * @return TWizardStep */ public function getActiveStep() { $index = $this->getActiveStepIndex(); if(isset($this->steps[$index])) return $this->steps[$index]; } /** * Set the active step index. This determines which step to show. * @param int the current step to show. */ public function setActiveStepIndex($index) { $this->setViewState('ActiveStepIndex',$index,0); } /** * Get the current step index. * @return int current step index. */ public function getActiveStepIndex() { return $this->getViewState('ActiveStepIndex', 0); } /** * Override the parent implementation. * It adds any components that are instance of TWizardStep or TWizardTemplate * as a child and body of the TWizard. Other components are handled by the parent. * By adding components as child of TWizard, these component's parent * is the TWizard. * @param object a component object. * @param object the template owner object */ public function addParsedObject($object,$context) { if($object instanceof TWizardStep) { $object->setVisible(false); $this->steps[] = $object; $this->addChild($object); $this->addBody($object); } else if ($object instanceof TWizardTemplate) { $object->setVisible(false); $this->navigation[$object->Type][] = $object; $this->addChild($object); $this->addBody($object); } else parent::addParsedObject($object,$context); } /** * Initalize and add the default navigation templates. Add the side bar * if required. * @param TEventParameter event parameter to be passed to the event handlers */ protected function onLoad($param) { parent::onLoad($param); $this->addNavigationButtons(); if($this->isSideBarVisible()) $this->addNavigationSideBar(); } /** * Determins which wizard step to show and appropriate navigation elements. * @param TEventParameter event parameter to be passed to the event handlers */ protected function onPreRender($param) { parent::onPreRender($param); $index = $this->getActiveStepIndex(); $totalSteps = count($this->steps); //show the current step for($i = 0; $i < $totalSteps; $i++) $this->steps[$i]->setVisible($i == $index); //determine which link is active for($i = 0; $i < count($this->sidebarLinks); $i++) $this->sidebarLinks[$i]->CssClass= ($i == $index)?'active':''; //hide all the navigations first. foreach($this->navigation as $navigation) { foreach($navigation as $nav) $nav->setVisible(false); } $final = $this->steps[$index]->Type == TWizardStep::TYPE_FINAL; //if it is not the final step if(!$final && $this->isSideBarVisible()) $this->showNavigation(TWizardTemplate::ID_SIDEBAR); $finishStep = $index == $totalSteps-1; $finishStep = $finishStep || (isset($this->steps[$index+1]) && $this->steps[$index+1]->Type == TWizardStep::TYPE_FINAL); //now show the appropriate navigation elements. if($index == 0) $this->showNavigation(TWizardTemplate::ID_START); else if($final) ; //skip it else if($finishStep) $this->showNavigation(TWizardTemplate::ID_FINISH); else $this->showNavigation(TWizardTemplate::ID_STEP); } /** * Show of the navigation elements for a particular type. * @param string navigation type. */ private function showNavigation($index) { if(!isset($this->navigation[$index])) return; foreach($this->navigation[$index] as $nav) { $nav->setVisible(true); $nav->dataBind(); } } /** * Construct the default navigation elements for the wizard. * The default navigations are only added if the template for that * particular navigation type is not customized. */ private function addNavigationButtons() { //create the 3 navigation components $start = $this->createComponent('TPanel',TWizardTemplate::ID_START); $start->CssClass = 'navigation'; $step = $this->createComponent('TPanel',TWizardTemplate::ID_STEP); $step->CssClass = 'navigation'; $finish = $this->createComponent('TPanel',TWizardTemplate::ID_FINISH); $finish->CssClass = 'navigation'; $previousButton = $this->createComponent('TButton'); $previousButton->setText($this->getPreviousStepButtonText()); $previousButton->setCommandName(self::CMD_PREVIOUS); $previousButton->setCausesValidation(false); $finishButton = $this->createComponent('TButton'); $finishButton->setText($this->getFinishStepButtonText()); $finishButton->setCommandName(self::CMD_FINISH); $nextButton = $this->createComponent('TButton'); $nextButton->setText($this->getNextStepButtonText()); $nextButton->setCommandName(self::CMD_NEXT); $hiddenButton = $this->createComponent('TButton'); $hiddenButton->setCommandName(self::CMD_NEXT); $hiddenButton->setStyle(array('display'=>'none')); $cancelButton = $this->createComponent('TButton'); $cancelButton->setText($this->getCancelButtonText()); $cancelButton->setCommandName(self::CMD_CANCEL); $cancelButton->CssClass='Cancel'; $cancelButton->setCausesValidation(false); if(!isset($this->navigation[TWizardTemplate::ID_START])) { $start->addBody($nextButton); $start->addBody($cancelButton); $this->addBody($start); $this->navigation[TWizardTemplate::ID_START][] = $start; } if(!isset($this->navigation[TWizardTemplate::ID_STEP])) { $step->addBody($hiddenButton); $step->addBody($previousButton); $step->addBody($nextButton); $step->addBody($cancelButton); $this->addBody($step); $this->navigation[TWizardTemplate::ID_STEP][] = $step; } if(!isset($this->navigation[TWizardTemplate::ID_FINISH])) { $finish->addBody($previousButton); $finish->addBody($finishButton); $finish->addBody($cancelButton); $this->addBody($finish); $this->navigation[TWizardTemplate::ID_FINISH][] = $finish; } } /** * Add the navigation side bar, a list of links to each step. * The default navigation is added only if the templates for * side bar are not present in the TWizard. */ private function addNavigationSideBar() { if(isset($this->navigation[TWizardTemplate::ID_SIDEBAR])) return; $total = count($this->steps); $current = $this->getActiveStepIndex(); $sidebar = $this->createComponent('TPanel',TWizardTemplate::ID_SIDEBAR); $sidebar->CssClass = 'sidebar'; if($total > 0) $sidebar->addBody("\n"); $this->addBody($sidebar); $this->navigation[TWizardTemplate::ID_SIDEBAR][] = $sidebar; } /** * This method responds to a bubbled event. It will capture the event * and fire the appropriate events, e.g. OnNextCommand if the parameter * event name is "next". After the command event, a step changed event * (OnStepChanged) is fire unless the event parameter variable $cancel * is set to true. * @param TComponent sender of the event * @param TEventParameter event parameters */ protected function onBubbleEvent($sender,$param) { //if false on validation, do nothing. if (!$this->Page->isValid()) return; $event = new TWizardCommandEventParameter(); $event->currentStepIndex = $this->getActiveStepIndex(); $event->nextStepIndex = $event->currentStepIndex; switch($param->name) { case self::CMD_NEXT: $event->nextStepIndex++; $this->raiseEvent('OnNextCommand',$this,$event); if(!$event->cancel) { $this->setActiveStepIndex($event->nextStepIndex); $this->raiseEvent('OnStepChanged',$this,$event); } break; case self::CMD_PREVIOUS: $event->nextStepIndex--; $this->raiseEvent('OnPreviousCommand',$this,$event); if(!$event->cancel) { $this->setActiveStepIndex($event->nextStepIndex); $this->raiseEvent('OnStepChanged',$this,$event); } break; case self::CMD_FINISH: if(isset($this->steps[$event->nextStepIndex+1])) $event->nextStepIndex++; $this->raiseEvent('OnFinishCommand',$this,$event); if(!$event->cancel) { $this->setActiveStepIndex($event->nextStepIndex); $this->raiseEvent('OnStepChanged',$this,$event); } break; case self::CMD_CANCEL: $event->cancel = true; $this->raiseEvent('OnCancelCommand',$this,$event); break; case self::CMD_JUMP: $event->nextStepIndex = $param->parameter; $this->raiseEvent('OnJumpToCommand',$this,$event); if(!$event->cancel) { $this->setActiveStepIndex($event->nextStepIndex); $this->raiseEvent('OnStepChanged',$this,$event); } break; } } } /** * TWizard command event parameter. * * This is passed as the parameter to all event orginating from TWizard. * If the event was a particular OnXXXXCommand, the variable $cancel * determine if the step will be changed. e.g in handling the "next" command * setting the parameter, $param->cancel = true will not result in a step change. * * The parameter also contains the current step index, and the next step index. * * @author Xiang Wei Zhuo * @version v1.0, last update on Sat Jan 22 13:59:56 EST 2005 * @package System.Web.UI.WebControls */ class TWizardCommandEventParameter extends TEventParameter { public $currentStepIndex = null; public $nextStepIndex = null; public $cancel = false; } ?>