Avg. Rating 5.0
Tags:



Problem

This Workflow component can be handy in situation where we want to show logical steps to be followed to complete the process. For example Filling up a form etc.

Solution

This Workflow component can be handy in situation where we want to show logical steps to be followed to complete the process. For example Filling up a form etc.

Detailed explanation

<--------- WorkFlowNavigator------>

package mittal.components
{
import flash.events.Event;
import flash.events.MouseEvent;

import mittal.events.WorkFlowEvent;
import mittal.skins.WorkFlowNavigatorSkin;
import mittal.valueObjects.WorkFlowItem;

import mx.collections.ArrayCollection;
import mx.collections.IList;
import mx.controls.Alert;
import mx.core.IFactory;

import spark.components.Button;
import spark.components.HGroup;
import spark.components.supportClasses.SkinnableComponent;

//--------------------------------------
//  Events
//--------------------------------------
/**
*  Dispatched when the data provider changes.
*
*  @eventType mittal.events.WorkFlowEvent.WORKFLOW_DATA_CHANGED
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
[Event(name="workFlowDataProviderChanged", type="mittal.events.WorkFlowEvent")]
/**
*  Dispatched when the selected index changes.
*
*  @eventType mittal.events.WorkFlowEvent.SELECTED_INDEX_CHANGED
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
[Event(name="selectedIndexChanged", type="mittal.events.WorkFlowEvent")]
/**
*  Dispatched when the next button is clicked.
*
*  @eventType mittal.events.WorkFlowEvent.WORKFLOW_NEXT_CLICK
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
[Event(name="nextClicked", type="mittal.events.WorkFlowEvent")]
/**
*  Dispatched when the previous button is clicked.
*
*  @eventType mittal.events.WorkFlowEvent.WORKFLOW_PREVIOUS_CLICK
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
[Event(name="prevClicked", type="mittal.events.WorkFlowEvent")]
/**
*  Dispatched when the work flow item is clicked by user.
*
*  @eventType mittal.events.WorkFlowEvent.WORKFLOW_ITEM_SELECTED_BY_USER
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
[Event(name="workFlowItemClicked", type="mittal.events.WorkFlowEvent")]

/**
*  The WorkFlowNavigator component displays a list of workflow items.
*  Its functionality is similar to the standard work flow component.
*  Based on the items in data provider it creates a number of work-flow items
*  and the first and last items will have different representations.
*  This component is based upon SkinnableComponent and overrides a number of methods.
*  This class also provides implementation of getCurrentSkinState() method to retrun proper value to its skin class.
*  
*  There will not be any scrollbar so proper width and height must be selected. 
* 
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
public class WorkFlowNavigator extends SkinnableComponent
{
//--------------------------------------------------------------------------
//
//  Class constants
//
//--------------------------------------------------------------------------

/**
*  Static constant representing the value "no selection".
* 
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
public static const NO_SELECTION:int = -1;
private static const DEFAULT_HEIGHT :Number = 200;
private static const DEFAULT_WIDTH :Number = 200;
public static const FIRST_ITEM:int = 0;
private var LAST_ITEM:int;

[SkinPart(required="true", type="mittal.components.WorkFlowButton")] 
/** * A dynamic skin part that defines a WorkFlow Item */ 
public var workFlowButton:IFactory;

[SkinPart(required="false")]
public var nextButton:Button;
[SkinPart(required="false")]
public var previousButton:Button;
[SkinPart(required="true")]
public var workFlowBar:HGroup;

//--------------------------------------------------------------------------
//
//  Constructor
//
//--------------------------------------------------------------------------

public function WorkFlowNavigator()
{
super();
addEventhandlers();
setStyle("skinClass",mittal.skins.WorkFlowNavigatorSkin);
}

//--------------------------------------------------------------------------
//
//  Properties
//
//--------------------------------------------------------------------------

/** 
*  @private
*  Flag that is set when the selectedIndex has been adjusted due to
*  user interaction or next/prev button click. 
*  This flag is cleared in commitProperties().
*/
private var selectedIndexChanged:Boolean =  false;
/**
*  The 0-based index of the selected item, or -1 if no item is selected.
*  Setting the <code>selectedIndex</code> property deselects the currently selected
*  item and selects the data item at the specified index.
*
*  <p>The value is always between -1 and (<code>dataProvider.length</code> - 1). 
*
*  @default -1
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
private var _selectedIndex:int = NO_SELECTION;

[Bindable("selectedIndexChanged")]
public function get selectedIndex():int
{
return _selectedIndex;
}
/**
*  @private
*/ 
public function set selectedIndex(value:int):void
{
if(value == _selectedIndex)
return;

_selectedIndex = value;
selectedIndexChanged = true;
invalidateProperties();
}
//----------------------------------
//  hovered
//----------------------------------

/**
*  @private
*  Storage for the hovered property 
*/
private var _hovered:Boolean = false;    

/**
*  Indicates whether the mouse pointer is over the button.
*  Used to determine the skin state.
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/ 
protected function get hovered():Boolean
{
return _hovered;
}

/**
*  @private
*/ 
protected function set hovered(value:Boolean):void
{
if (value == _hovered)
return;

_hovered = value;
invalidateSkinState();
}
/**
*  @private
*/
private var dataProviderChanged:Boolean;
/**
*  @private
*/
private var doingWholesaleChanges:Boolean = false;

//----------------------------------
//  dataProvider
//----------------------------------

private var _dataProvider:*;

[Bindable("workFlowDataProviderChanged")]
public function get dataProvider():*
{
return _dataProvider;
}
public function set dataProvider(value:*):void
{
if(_dataProvider == value)
return;

_dataProvider = value;
dataProviderChanged = true;
invalidateProperties();
}

//--------------------------------------------------------------------------
//
//  Methods
//
//--------------------------------------------------------------------------

private function nextButtonHandler(event:MouseEvent):void {
if(selectedIndex < (workFlowBar.numElements -1))
selectedIndex++;
dispatchEvent(new WorkFlowEvent(WorkFlowEvent.WORKFLOW_NEXT_CLICK));
}
private function previousButtonHandler(event:MouseEvent):void {
if(selectedIndex > 0)
selectedIndex--;
dispatchEvent(new WorkFlowEvent(WorkFlowEvent.WORKFLOW_PREVIOUS_CLICK));
}
/**
*  This method  will deselect all the button except the one clicked by the user.
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
private function updateSelectedWorkFlowItem(btnIndex:uint):void
{
//Enable the selected one and disable the others.
var totalWorkFlowItems:int = workFlowBar.numElements;
var workFlowItem:WorkFlowButton;
for (var i:int = 0; i<totalWorkFlowItems; i++)
{
workFlowItem = workFlowBar.getElementAt(i) as WorkFlowButton;
workFlowItem.isDown = true;
workFlowItem.invalidateSkinState();
}
(workFlowBar.getElementAt(btnIndex) as WorkFlowButton).isDown = false;
}
/**
*  When user clicks on workflowItem the selectedIndex is updated and then same event is 
*  forwarded to the user.
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
private function workflowItemManualSelectionHandler(event:WorkFlowEvent):void
{
selectedIndex = (event.buttonIndex != -1)?(event.buttonIndex):0;
dispatchEvent(event.clone());
}
/**
*  This method mainly converts the item to workflow item and then calls up addProperWorkFlowItem to add this item.
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
protected function createAndAddProperWorkFlowItems(item:*, index:int):void
{
var workFlowItem:WorkFlowItem;

if(item is WorkFlowItem)
{
addProperWorkFlowItem(item, index);
}
else if(item is String)
{
workFlowItem = new WorkFlowItem();
workFlowItem.label = item;
workFlowItem.id = "11";
addProperWorkFlowItem(workFlowItem, index);
}
}
/**
*  This method mainly does the actual insertion of work flow item.
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
protected function addProperWorkFlowItem(item:WorkFlowItem, index:int):void
{
var workFlowItem :WorkFlowButton = createDynamicPartInstance("workFlowButton")as WorkFlowButton;
workFlowItem.label = item.label;
workFlowItem.id = item.id;
workFlowItem.btnIndex = index;
workFlowItem.toolTip = item.label;

if(index == FIRST_ITEM)
{
workFlowItem.setStyle("skinClass",mittal.skins.FirstButtonSkin);
}
else if (index == LAST_ITEM)
{
workFlowItem.setStyle("skinClass",mittal.skins.LastButtonSkin);
}
else
{
workFlowItem.setStyle("skinClass",mittal.skins.MiddleButtonSkin);
}
workFlowBar.addElement(workFlowItem);
}
/**
*  This method is called upon when dataprovider changes. This function will remove all previous items and
*  insert new items.
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
protected function refreshWorkFlowItems(itemsCollection:ArrayCollection):void
{
var itemsCount:int = itemsCollection.length;
if(itemsCount > 2)
{
for(var index:int = 0; index<itemsCount; index++)
{
createAndAddProperWorkFlowItems(itemsCollection.getItemAt(index),index);
}
}
else
Alert.show("Please provide atleast 3 items.","Error in Usage");
}
/**
*  This method should be used to perform all clean up operations.
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
protected function destroyWorkFlow():void
{
removeEventHandlers();
}
/**
*  This method handles the mouse events, calls the <code>clickHandler</code> method 
*  where appropriate and updates the <code>hovered</code> and
*  <code>mouseCaptured</code> properties.
*
*  <p>This method gets called to handle <code>MouseEvent.ROLL_OVER</code>, 
*  <code>MouseEvent.ROLL_OUT</code>, <code>MouseEvent.MOUSE_DOWN</code>, 
*  <code>MouseEvent.MOUSE_UP</code>, and <code>MouseEvent.CLICK</code> events.</p>
*
*  @param event The Event object associated with the event.
*  
*  @langversion 3.0
*  @playerversion Flash 10
*  @playerversion AIR 1.5
*  @productversion Flex 4
*/
protected function mouseEventHandler(event:Event):void
{
var mouseEvent:MouseEvent = event as MouseEvent;
switch (event.type)
{
case MouseEvent.ROLL_OVER:
{
hovered = true;
break;
}

case MouseEvent.ROLL_OUT:
{
hovered = false;
break;
}
}
}
/**
*  @private
*/
private function addEventhandlers():void
{
addEventListener(MouseEvent.ROLL_OVER, mouseEventHandler);
addEventListener(MouseEvent.ROLL_OUT, mouseEventHandler);
}
/**
*  @private
*/
private function removeEventHandlers():void
{
removeEventListener(MouseEvent.ROLL_OVER, mouseEventHandler);
removeEventListener(MouseEvent.ROLL_OUT, mouseEventHandler);
}

//--------------------------------------------------------------------------
//
//  Overridden Methods
//
//--------------------------------------------------------------------------
/**
*  @private
*/
override protected function measure():void
{
super.measure();
measuredMinHeight = measuredHeight = DEFAULT_HEIGHT;
measuredMinWidth = measuredWidth = DEFAULT_WIDTH;
}
/**
*  @private
*/
override protected function commitProperties():void
{
if(selectedIndexChanged)
{
selectedIndexChanged = false;
updateSelectedWorkFlowItem(selectedIndex);
dispatchEvent(new WorkFlowEvent(WorkFlowEvent.SELECTED_INDEX_CHANGED));
}
if(dataProviderChanged)
{
dataProviderChanged = false;
LAST_ITEM = IList(dataProvider).length -1;
refreshWorkFlowItems(dataProvider);
dispatchEvent(new WorkFlowEvent(WorkFlowEvent.WORKFLOW_DATA_CHANGED));
}
super.commitProperties();
}
/**
*  @private
*/
override protected function partAdded(partName:String, instance:Object):void {
super.partAdded(partName, instance);

if (instance == nextButton) {
(instance as Button).addEventListener(MouseEvent.CLICK, nextButtonHandler);
}
if (instance == previousButton) {
(instance as Button).addEventListener(MouseEvent.CLICK, previousButtonHandler);
}
if(partName == 'workFlowButton'){
Button(instance).addEventListener(WorkFlowEvent.WORKFLOW_ITEM_SELECTED_BY_USER,workflowItemManualSelectionHandler);
}
}
/**
*  @private
*/
override protected function partRemoved(partName:String, instance:Object):void {
if (instance == nextButton) {
(instance as Button).removeEventListener(MouseEvent.CLICK, nextButtonHandler);
}
if (instance == previousButton) {
(instance as Button).removeEventListener(MouseEvent.CLICK, previousButtonHandler);
}
if(partName == 'workFlowButton'){
Button(instance).removeEventListener(WorkFlowEvent.WORKFLOW_ITEM_SELECTED_BY_USER,workflowItemManualSelectionHandler);
}
super.partRemoved(partName, instance);
}
/**
*  @private
*/
override protected function getCurrentSkinState():String
{
if (!enabled)
return "disabled";

if (hovered)
return "over";

return "up";
}

}
}
Report abuse

Related recipes