Monday, March 23, 2009

Assignment : Interactive dynamic tabbed menu



We had to design a tabbed menu keeping following things in mind.
  • Trace the design close to the layout shown in reference.
  • Menu will be created dynamically from an external XML file and will accept all data like number of tabs and label for each tab etc from XML.
  • Each tab should adjust its width automatically as per the label’s size.
  • If tabs are taking more space than the defined width, it should display two small arrows on both the sides allowing scroll/pan the menu.
  • Selected menu should be highlighted as shown in reference.
  • Please call a function by passing some id for each tabs, for example call showSection(id:Number).
  • Use ActionScript 3.0
I just tried it creating a rough class. It may be helpful to anyone learning AS3.0.
Here I am making one "TabControls" class of which objects could be created. I am using some graphics from library. So i am attaching one fla below which carries all the required symbols.


The designed class also takes one parameter for maskWidth. It limits the width to which the tab control would be visible.
something like

var myTab:TabControls = new TabControls(500); addChild(myTab);

Lets take a look @ the code of the class.

TabControls.as

package
{
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.utils.Timer;
import flash.events.TimerEvent;

public class TabControls extends Sprite
{
private var _urlReq:URLRequest;
private var _urlLoad:URLLoader;
private var _noOfTabs:Number;
private var _externalXML:XML;
private var _tabArray:Array = new Array();
private var _objtab:Array = new Array;
private var _gridX:Number = 50;
private var _gridY:Number = 100;
private var _tabClip:MovieClip = new MovieClip();
private var _clickColorCode:uint = 0xff0000;
private var _defaultColorCode:uint = 0x666666;

private var _maskBground:Sprite = new Sprite();
private var _maskw:Number;
private var _maskh:Number = 28;

private var _leftArrow:leftarw = new leftarw();
private var _rightArrow:rightarw = new rightarw();

private var myTf:TextField = new TextField();
private var _myTimer:Timer;
private var _moveDirection:String;

public function TabControls (maskwidth:Number)
{
_maskw = maskwidth;
init ();
}
public function init ()
{
_urlReq = new URLRequest("tabData.xml");
_urlLoad = new URLLoader(_urlReq);
_urlLoad.addEventListener (Event.COMPLETE,onComplete);
addChild (myTf);
_myTimer = new Timer(100, 0);
_myTimer.addEventListener("timer", timerHandler);
}
public function onComplete (e:Event):void
{
_externalXML = new XML(_urlLoad.data);
_noOfTabs = _externalXML.tabDesc.attribute("nooftabs");
for (var k=0; k<_externalxml.tabs.length(); xx="0;" mousechildren =" false;" buttonmode="true;" name = "tab" text =" _tabArray[xx];" wordwrap="false;" autosize =" TextFieldAutoSize.LEFT;" width =" tabObj.tabText.textWidth" tempx =" 0;" tempy =" _gridY;" jj="0;" x =" tempX;" y =" tempY;" x =" _gridX" uint =" _tabClip.numChildren" ii="0;" colortransform =" _objtab[ii].tabBg.bgColor.transform.colorTransform;" color =" _defaultColorCode;" colortransform =" newColorTransform1;" colortransform =" _objtab[clickCode].tabBg.bgColor.transform.colorTransform;" color =" _clickColorCode;" colortransform =" newColorTransform;" x =" _gridX-2;" y =" _gridY-2;" mask =" _maskBground;" buttonmode =" true;" buttonmode =" true;" x =" _maskBground.x" y =" _maskBground.y" x =" _maskBground.x+_maskBground.width" y =" _maskBground.y" x =" _maskBground.x" y =" _maskBground.y" _movedirection = "right" _movedirection = "left" autosize =" TextFieldAutoSize.LEFT;" text =" _tabArray[id];" _movedirection ="="" x =" _tabClip.x" _movedirection ="=""> (_maskBground.width-_tabClip.width+_gridX))
{
_tabClip.x = _tabClip.x - 10;
}
}
}
}
}


he constructor of the class transfers the parameter for maskwidth to a local private var.
As you can notice the init() method of the class is loading all the XML and then latter "onComplete" event method is used to populate the array with values reading it from the XML.

The method "generateTabs()" create instance of "tabBox" a linked class found in the library of the fla linked above in article.

public function generateTabs()
{
for(var xx=0;xx<_tabarray.length;xx++)
{
_objtab[xx] = new tabBox();
_objtab[xx].name = "tab"+xx;
_objtab[xx].tabText.text = _tabArray[xx];
formatTab(_objtab[xx]);
}
addTabs();
}

The method "formatTab()" was required so that the width of the tabs could be dynamically be controlled.

tabObj.tabText.autoSize = TextFieldAutoSize.LEFT;

The autosizing code and then calculating it with the background clip allows us the reach the goal.
Finally "addTabs()" method allows us to add the tabs..on the stage.

The method arranges in such a way that it views as tabs. The "addMasktoTabs()" method has been added to limit the view area of the tabControl. It uses the same "maskwidth" parameter which we passed to the constructor of the class.

One very important method is "onRollTab()"

public function onRollTab(e:MouseEvent):void
{
var topPosition:uint = _tabClip.numChildren - 1;
_tabClip.setChildIndex(_objtab[e.currentTarget.name.substr(3,2)], topPosition);
}

This method is basically doing the depth management of the tabs. It is checking all the childs in the MovieClip container "_tabClip" and then swapping the rolledover tab to highest index.

All associated files can be downloaded from below link.


-Nitin

2 comments:

Nitin Goyal said...

its fine!!

but we can change it.. like this..

if we rolllover then also its color shud change or some alpha shud change..

Nitin Goyal said...

also if we do it using the complete MVC pattern. having different classes and interfaces then it will be much better

the code anagement wll be gr8 in that

here its lookig somewht cumbersome

Using FormBuilder, Validators & FormGroup in Angular 2 to post data to Node server (node.js)

This blog explains usage of  FormBuilder , Validators , FormGroup classes in Angular 2 projects. In this post we will create HTML form a...