Archive

Archive for the ‘Flex’ Category

Global Error Handler in Flash

August 12th, 2009

Ever wanted to be able to have some kind of global error handler in your Flex/Flash application? I know I have, every time I’ve had to add try and catch all over the place “just in case” my app throws an error. Please, please, please go and vote this feature request up at Adobe Jira

Ability to intercept system error dialogs

This will go a long way in saving us all a lot of pain in error handling.

Gareth Errors, Flex, Framework , ,

My code is going to be in the Flex SDK

July 28th, 2009

A little while back Nate Beck and Marty Mickelson set up the Bug Quash event to promote users to give back to the Flex SDK that they all work with each day by submitting bug fixes. Just from working with Flex everyday, we’ve probably all come across at least one bug that had us beating our heads against the wall thinking that we were doing something wrong, when there was actually something a little wonky with the Flex SDK. As Flex is open source, it allows for anyone to submit a patch for review by Adobe, and, once you set up your local environment (and set up your sandbox account), there’s really no good excuse not to try to fix something. Plus, it helps you to understand the code you’re working with at a more fine grained level, rather than just taking for granted that Flex “just works”.

I attended the first BugQuash, but only late in the day, so I didn’t get to fix anything at the time. Still wanting to fix a bug, I decided I’d check out the bug listings of at the Adobe Bug System. As I’d worked with the date functions in Flex quite a bit for my Flex Date Utils library, I figured I’d try to find something to do with dates in the bug base. In checking through, I came across this little one. I wanted to take something that wouldn’t be too crazy to accomplish for my first fix, but was at least useful to add.

I submitted the first patch back in April (a month or so after the BugQuash finished). It took me a little while to get my environment set up (Nate gave a little video demonstration of how to set up your environment here so check it out if you’re thinking of contributing), but once I did, it was pretty painless. I got some feedback (I’m not sure whether it was a user or someone at Adobe) on the patch and made the suggested changes, resubmitted back in June, and today my patch just got approved :) Turnaround wasn’t too bad considering that Flex 4 is in beta along with Flash Builder, ColdFusion Builder, CF9, and everything else going on at Adobe lately.

Now I just have to figure out which one I want to work on next. Plus, check out my “Bug Quash Badge”…also created by Mr Beck. It links up to the JIRA and queries for the number of bugs you have “quashed”. Excellent!

Gareth Flex, code , , ,

Adding colspan to a datagrid

March 17th, 2009

Recently at my job, our User Interface guru came up with the design and interface that she wanted for our users. However, the design she came up with required adding a colspan to a datagrid. As many know who have tried it, this is not really a possibility right out of the box with a Flex DataGrid. It is apparently a possibility with the AdvancedDataGrid, but I have just never really liked the visuals of the datagrid, especially with how it outputs the rows of data…it seems very cluttered to me when grouping is added. Plus, I have a PagedArrayCollection that I wrote and use quite regularly, that (currently) does not play nicely with the AdvancedDataGrid (I think it has something to do with the grouping), and currently just works with the regular DataGrid. So, in order to accommodate the business and my PagedArrayCollection, rather than just have multiple rows of data in multiple columns, I came up with a solution to allow for the spanning of multiple columns, as many as is necessary.

I tried to figure out, visually and programmatically, I could mimic the HTML table colspan. My solution actually involves 2 datagrids + single datagrids as itemrenderers within the rows. As Flex recycles its itemrenderers, this appeared to be a pretty practical solution. My first datagrid is used solely for the headers. I made the height of the datagrid match the height of the headers of the first datagrid, so all that is visible is the headers themselves.

DataGrid Header

DataGrid Header

The code for this is as follows (notice the small height of the datagrid):

<mx:DataGrid id="headerDataGrid" x="70" y="40" width="780" height="23" dataProvider="{ dataProvider }">
	<mx:columns>
		<mx:DataGridColumn headerText="Name" dataField="name"/>
		<mx:DataGridColumn headerText="Location" dataField="location"/>
		<mx:DataGridColumn headerText="Exp" dataField="exp"/>
	</mx:columns>
</mx:DataGrid>

From here I created another datagrid, but this one contains only a single column. I also removed the headers from this datagrid as I will be using the datagrid headers from the previously created datagrid (headerDataGrid), so this one just looks like the rows from a datagrid.

DataGrid Body

DataGrid Body

Once I had these 2 datagrids, I put them right next to each other so it looks like they’re actually the same datagrid, but without vertical lines between the columns.

The code for the 2nd grid is:

<mx:DataGrid x="70" y="61" id="dgMain" width="780" height="444" showHeaders="false" dataProvider="{ dataProvider }" paddingTop="0" paddingBottom="0"
	variableRowHeight="true" selectable="true">
	<mx:columns>
		<mx:DataGridColumn headerText="All data" dataField="col1" itemRenderer="com.flexoop.utility.renderer.ColSpanRowRenderer" />
	</mx:columns>
</mx:DataGrid>

Both of these datagrids are bound to the same dataprovider. This makes manipulation of the arraycollection extremely simple. I had thought I would be writing my own sort and filter functions, overriding the headers, but I forgot that once these datagrids are bound to the same arraycollection, Flex automatically handles all of that and everything just works. Simple! :) The headertext and dataField are irrelevant in this datagrid as they will not be used. I set the variableRowHeight=”true” so the itemrenderer will show the multiple rows of data correctly.

As you can see from the above code, I created a ColSpanRowRenderer itemRenderer. This handles the final part of the colspanned datagrid…the actual colspan.

ColSpan Row Renderer

ColSpan Row Renderer

The code for this looks like:

<mx:DataGrid id="dgLocal" x="0" y="0" width="100%" showHeaders="false" height="23" dataProvider="{ data }" backgroundAlpha="0" selectable="false"
	borderSides="{ parentDocument.detailed ? 'bottom top' : 'bottom' }">
	<mx:columns>
		<mx:DataGridColumn headerText="Name" dataField="name" />
		<mx:DataGridColumn headerText="Location" dataField="location" />
		<mx:DataGridColumn headerText="Exp" dataField="exp" />
	</mx:columns>
</mx:DataGrid>
<mx:Text visible="{ parentDocument.detailed }" includeInLayout="{ parentDocument.detailed }"
	htmlText="This is where the detailed text will go.&lt;br /&gt;This is not formatted now but can be once it goes live" y="22" width="100%" />

This is all contained within a VBox with all padding set to zero to aid in visual layout, and to make it look like it is a row in the dgMainBody datagrid. The height of the datagrid forces it to just show the single row of data, with showHeaders=”false” again. I bind it to the “data” value that is passed in to the itemrenderer, then output the properties of that data object within the single row datagrid. I have a variable named “detailed” in the parentDocument (the page containing my header and main body datagrids). This allows me to show or hide the extra colspanned row of data. This was part of the requirement from the business, so I added it in. As the header, main body, and colspanrowrenderers all need to be tightly coupled, I was not so worried about referring to the “parentDocument”. Had this been something I was going to be moving around to other components, I would have tried to think of another solution. The “includeInLayout” attribute will completely remove the “Text” box from the view, so as not to take up any space when it is not visible. In order to prevent the user from selecting the single row datagrid item, I set ’selectable=”false”‘, then in the outer datagrid (dgMainBody), I set ’selectable=”true”‘. This will then allow the user to select the complete itemrenderer (both datagrid row and colspanned text field).

I had found that when detailed=’false’, the single datagrid rows did not alternate colors, which made sense as they were all the first row. In order to fix this problem, I set backgroundAlpha=”0″ in the colspanrowrenderer. This then used the colors of the dgMainBody datagrid for coloring the itemrenderer. The final visual part was setting the borderSides=”bottom” or “bottom top” depending on whether the view was detailed or not.

The final part of getting this to look and act like a regular datagrid was to adjust the column widths of all of the ColSpanRowRenderer rows when the header items were moved, as the rows are not actually linked directly back to the dgHeader. To catch these changes, I added a creationComplete=”init()” to the vbox in my ColSpanRowRenderer. Then in my init() function (along with a setColumnWidth function):

private function init():void {
	setColumnWidth();
	parentDocument.headerDataGrid.addEventListener( DataGridEvent.COLUMN_STRETCH, setColumnWidth );
}
private function setColumnWidth( event:DataGridEvent=null ):void {
	var _i:uint = 0;
	var _length:uint = parentDocument.headerDataGrid.columns.length;
	while ( _i < _length ) {
		dgLocal.columns[ _i ].width = parentDocument.headerDataGrid.columns[ _i ].width;
		_i++;
	}
}

At first, I was only changing the width of the column that was being stretched, but I found that the flash player must do some other computations on the other columns, so I just decided to loop over all of the columns and resize each one to match the header columns. I found that I had to add a ‘render=”setColumnWidth()”‘ also as some of my columns were a little screwy at times. This adds a slight adjustment after the page renders, but is not all that noticeable and fixes any column width issues I was having.

So the final product looks like this:

DataGrid With ColSpan

DataGrid With ColSpan

And code is DataGridColSpan.mxml and ColSpanRowRenderer.mxml

Hopefully I haven’t bored anyone to tears with my explanation, but I wanted to be sure that everyone understands my reasoning for doing everything that I did to the datagrids. Enjoy!

Gareth Component, Flex, code , , ,

Update to MenuItem class

February 24th, 2009

I have recently begun using my MenuItem and MenuItemWithChildren classes at my work, and have made a slight modification to the code to lessen some of the code writing required.

As I was using the menuItem class, I realized that when I selected the item, I was usually just calling some function based upon the label of that menu item. Using my updated MenuItem class, you can now pass in a function as one of the parameters.

My MenuItem class now looks like this:

package com.flexoop.utility {
 
	[Bindable]
	public class MenuItem {
 
		/***********************************
		 * properties
		 **********************************/
 
		private var _enabled:Boolean = true;
		private var _groupName:String = "";
		private var _icon:Class;
		private var _label:String = "";
		private var _menuHandler:Function;
		private var _toggled:Boolean = true;
		private var _type:String = "";
 
		/***********************************
		 * getters
		 **********************************/
 
		public function get enabled():Boolean {
			return this._enabled;
		}
 
		public function get groupName():String {
			return this._groupName;
		}
 
		public function get icon():Class {
			return this._icon;
		}
 
		public function get label():String {
			return this._label;
		}
 
		public function get menuHandler():Function {
			return this._menuHandler;
		}
 
		public function get toggled():Boolean {
			return this._toggled;
		}
 
		public function get type():String {
			return this._type;
		}
 
		/***********************************
		 * setters
		 **********************************/
 
		public function set enabled( value:Boolean ):void {
			this._enabled = value;
		}
 
		public function set groupName( value:String ):void {
			this._groupName = value;
		}
 
		public function set icon( value:Class ):void {
			this._icon = value;
		}
 
		public function set label( value:String ):void {
			this._label = value;
		}
 
		public function set menuHandler( value:Function ):void {
			this._menuHandler = value;
		}
 
		public function set toggled( value:Boolean ):void {
			this._toggled = value;
		}
 
		[Inspectable(enumeration=separator,check,radio,normal)]
		public function set type( value:String ):void {
			this._type = value;
		}
 
		public function MenuItem( label:String="", menuHandler:Function=null, enabled:Boolean=true, type:String="normal", toggled:Boolean=true, groupName:String="", icon:Class=null ) {
			this.enabled = enabled;
			this.groupName = groupName;
			this.icon = icon;
			this.label = label;
			this.menuHandler = menuHandler;
			this.toggled = toggled;
			this.type = type;
		}
 
	}
}

And similarly for the MenuItemWithChildren class:

package com.flexoop.utility {
 
	public class MenuItemWithChildren extends MenuItem {
 
		/***********************************
		 * properties
		 **********************************/
 
		private var _children:Array = [];
 
		/***********************************
		 * getters
		 **********************************/
 
		public function get children():Array {
			return this._children;
		}
 
		/***********************************
		 * setters
		 **********************************/
 
		public function set children( value:Array ):void {
			this._children = value;
		}
 
		public function MenuItemWithChildren( label:String="", menuHandler:Function=null, enabled:Boolean=true, type:String="normal", toggled:Boolean=true, groupName:String="", icon:Class=null ) {
			super( label, menuHandler, enabled, type, toggled, groupName, icon );
		}
 
	}
}

The 2nd parameter is now the menuHandler function. So in order to use this, you could set up something like this:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" xmlns:flexoop="com.flexoop.utility.*">
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
 
			import mx.events.MenuEvent;
			import mx.controls.Alert;
 
			import com.flexoop.utility.MenuItemWithChildren;
			import com.flexoop.utility.MenuItem;
 
			[Bindable] private var menuData:ArrayCollection = new ArrayCollection;
 
			public function init():void {
				var menuItem:MenuItemWithChildren = new MenuItemWithChildren( "test 1", showMe );
				menuItem.children.push( new MenuItem( "test 4", showMe ) );
				menuItem.children.push( new MenuItem( "test 5", showMe ) );
				menuData.addItem( menuItem );
				menuData.addItem( new MenuItem( "test2", showMe ) );
				menuData.addItem( new MenuItem( "test3", showMe ) );
				mb.dataProvider = menuData;
 
			}
 
			private function menuItemHandler( event:MenuEvent ):void {
				( event.item as MenuItem ).menuHandler();
			}
 
			private function showMe():void {
				Alert.show( 'this was fired from my menuItem' );
			}
 
		]]>
	</mx:Script>
	<mx:VBox>
		<mx:ApplicationControlBar id="acb">
			<mx:MenuBar id="mb" dataProvider="{ menuData }" click="menuItemHandler( event )" />
		</mx:ApplicationControlBar>
	</mx:VBox>
</mx:Application>

(I didn’t get a chance to test the above example code so, if anyone finds that something doesn’t work correctly, feel free to ping me about it and I’ll try to get it working properly). It’s a somewhat basic example as all items point to the same function, but it would be very simple to alter this so each menuItem points to a separate method instead, or pass a certain value to the function to display.

Gareth Component, Flex, code , , ,

wmode – one little attribute makes all the difference

February 3rd, 2009

At my work, the business wanted a right click menu that did not have all of the default “Flash” items in it. Now, you can edit the context menu so that it hides *most* of the Flash options, but not all of them. I found a right click someone wrote that uses Javascript to intercept the right click event from the mouse before it propagates to the Flash swf. I created a right click class (I may show that class at some point) that handles the resulting event that Javascript passes and generates the menu options to the user. However, for some reason (although I was using what I thought was identical code to another page a co-worker wrote), I wasn’t able to get the right click to work. It kept showing the regular context menu. After puzzling over the code for about an hour, I then went digging through the html page. After comparing the code for a few minutes, I came across the “wmode=’transparent’” attribute added to the swf creation. “Of course”, I said to myself. The right click was not able to be intercepted by the page before it got to the swf, as the right click was always hitting the swf first. By setting the wmode to transparent (I’m guessing here slightly), gets caught by the page, rather than the swf. The Javascript can then fire off a callback event to the Flex/Flash swf, which then makes everything work great. Such a simple little attribute that is so vitally important.

Gareth Flex, code , , , ,

Frameworks Galore

January 19th, 2009

Well, not too many, but I would say just enough to ease the use of the Flex framework itself, and deciding how best to lay out your code. Up to this point, I have not tried to use a framework for my code, mainly because I did not really see the need for one. I had my own basic structure that I used for all of my code and tried to stick with that when methodology when creating/laying out my projects. At my last job, my co-worker and I were of a pretty similar mindset, so it was pretty simple to not stray too far from each other’s best programming practices.

At my current employer we have been transitioning from a ColdFusion front and back end to a ColdFusion back end and Flex on the client. We have a relatively small team, with varied knowledge of Flex and OOP, but everyone is willing to learn, and seems to do so pretty quickly. With this in mind, we thought that a framework may assist those without the in depth Flex knowledge to come up to speed a little quicker by not having to wonder where to place certain components that they end up building, and can use the other code they find for groundwork. This combined with the fact that even though the group is small, frameworks do seem to facilitate easier code reuse, and take the guesswork out of best practices. Also, due to time constraints, our most recent project turned into a somewhat procedural behemoth of an application, that now is in need of some refactoring, and a framework would certainly help by easing how to split everything up.

I started to get the urge to look into frameworks again after reading FrameworkQuest 2008 over at insiderRIA.com. Tony Hillerson did a great job of presenting all of the various frameworks, in a very unbiased fashion, I thought. I figured, rather than just taking his word for it, I would dive into the frameworks myself and take a small project I created using my usual code structure and break that out using a framework. Nothing helps to send the message home than to write it yourself.

The 4 frameworks I decided to implement were:
my own
Cairngorm
Mate
and Swiz
I had ruled out PureMVC from my list of frameworks, mostly because I felt that if I was going to use a non-standard framework, that I wanted something that would make my life easier, and, at first glance, while it seemed to be quite powerful, PureMVC seemed to a little too abstract for what I needed it for (especially for those just getting into Flex).

Over the next couple of weeks, I’ll post my trials and tribulations with each framework as I went through it, how I dealt with the problems I came across, and my humble reasoning for the framework I chose. Hopefully it will give others insight into the frameworks (for those of us who have never used them before), and if others are actually reading this blog, will help out by commenting on things that I’m either doing incorrectly, or could be done easier.

Gareth Flex, Framework, code , , , ,

Problem solved transferring typed objects to Flex

January 14th, 2009

I really do like using the struct method of transferring typed objects from ColdFusion to Flex. However, today I ran into an issue when passing them to Flex from ColdFusion.

I had been following along with Dan Vega’s posts on RocketFM, and I decided to download the code and tinker with it (as all good little programmers should :) ). I had added a FileInfo VO to Flex and one to ColdFusion. Then within the FileManager object, I was returning the newly typed object ( temp['__type__'] = “RocketFM.src.org.vega.FileInfo”; ). However, every time I returned the the data, I kept getting a plain, ol’ generic object. On to the debug steps:

I had recently removed my CF7 install, so I thought that maybe that had messed something up within my CF8 install. I restarted my CF instance ( a couple of times in the end), turned various settings on and off, all to no avail. I tried changing where I was pointing my CFC and my aliasing of them, but everything seemed to be correct there also. I then fired up an old project that I had previously used that I knew was returning typed objects. I ran it through the debugger, and lo and behold…typed objects still. So, I ruled out CF as being the problem (I’m using the same instance across all of my projects…not the best method, but until I get more than 5 different CF projects I’m working on, I should be ok)

I then decided it must be something on the Flex side of things. I got distracted with something else, and just as my mind had begun to relax, the solution hit me…I haven’t included the FileInfo class in my project anywhere (queue head slapping moment). Flex only includes classes that are referenced somewhere in the project, even though the VO was included in the project directory structure, I was not referencing it anywhere in the code (as all I cared about at first was that the data would be returned as typed objects). I then added the import statement and created a private variable that would all me to just reference the VO in Flex. Once this had been added, the typed objects were returning like champs back to the Flex project. A somewhat simple solution in the end, but unless you’re actually thinking about it, very easy to overlook as well.

Gareth ColdFusion, Flex, code , , , ,

Flex Date Utils – daysInYear, isLeapYear

January 4th, 2009

These are the final 2 methods in my DateUtils Class of the FlexDateUtils library. I’ve got a Business class, a Holiday class and a DaylightSavingTimeUS class that are all included in the FlexDateUtils library, and I may go over those in the future, but not right now.

/**
 * Gets the number of days in the year
 * 
 * @param date	The date to check
 * 
 * @return		The total number of days in the year
 */
public static function daysInYear( date:Date ):Number {
	return DateUtils.dateDiff(
				DateUtils.DAY_OF_MONTH,
				new Date( date.fullYear, DateUtils.monthAsNumber( DateUtils.JANUARY ), 1 ),
				DateUtils.dateAdd( DateUtils.YEAR, 1, new Date( date.fullYear, DateUtils.monthAsNumber( DateUtils.JANUARY ), 1 ) ) );
}

Very straight forward method. This calculates how many days are in the year that is passed in. Essentially I’m doing a date difference between the first of January of the requested year, and the first of January of the next year. The method returns the number of days for that year.

So in order to use this method, first import the package

import com.flexoop.utilities.dateutils.DateUtils;

and then:

private var _total:Number = DateUtils.daysInYear( new Date( 2009, DateUtils.monthAsNumber( DateUtils.JANUARY ) ) );

This would return 365.

/**
 * Determines whether the year is a leap year or not
 * 
 * @param date	The date to check
 * 
 * @return		<code>true</code> means it is a leap year, <code>false</code> means it is not a leap year.
 */
public static function isLeapYear( date:Date ):Boolean {
	return daysInYear( date ) > 365;
}

Another very straight forward method. It accepts a date and determines if the year is a leap year.

So in order to use this method, first import the package

import com.flexoop.utilities.dateutils.DateUtils;

and then:

private var _isLeapYear:Boolean = DateUtils.isLeapYear( new Date( 2009, DateUtils.monthAsNumber( DateUtils.JANUARY ) ) );

This would return false as 2009 is not a leap year.

All methods in this series are describing code in the FlexDateUtils package I put on Google code.

I hope that this wasn’t too dry a topic for everyone that followed along. I just get excited when I’m describing code I have written and as much as my wife looks like she’s interested in what I’m saying, I see her eyes glazing over every now and then :) , and I hope that others find new code as interesting as I do. I wanted to make sure I got descriptions of everything in the DateUtils library to make it easier for anyone trying to figure out a use for it. I think I’ll leave the library descriptions alone and go back to posting solutions to problems I’ve faced at work/home or interesting tidbits I’ve come across. Perhaps I can revisit any new items I add in the future.

Gareth Flex, FlexDateUtils, code, library , ,

Flex Date Utils – totalDayOfWeekInMonth, monthAsNumber

January 3rd, 2009

These 2 methods are quite useful. I use monthAsNumber quite frequently throughout the DateUtils library as it prevents any confusion about which month I am referencing (using the constants for a month rather than the numeric version, which in Flex and many programming languages is 0-11 rather than 1-12)

/**
 * Gets the total number of dayOfWeek in the month
 * 
 * @param strDayOfWeek	The day of week to check
 * @param date			The date containing the month and year
 * 
 * @return				The number of <code>strDayOfWeek</code> in that month and year
 */
public static function totalDayOfWeekInMonth( strDayOfWeek:String, date:Date ):Number {
	var _startDate:Date = DateUtils.dayOfWeekIterationOfMonth( 1, strDayOfWeek, date );
	var _totalDays:Number = DateUtils.dateDiff( DateUtils.DAY_OF_MONTH, _startDate, new Date( date.fullYear, date.month, DateUtils.daysInMonth( date ) ) );
	// have to add 1 because have to include first day that is found i.e. if wed is on 2nd of 31 day month, would total 5, of if wed on 6th, would total 4
	return Math.floor( _totalDays / 7 ) + 1;
}

This method calculates the total number of a specific day of the week for a specified month. The method accepts dayOfWeek as a string (use one the constants to make this easier) and a date containing the month and year requested. It then returns a number with the total number of that day of the week for that month.

So in order to use this method, first import the package

import com.flexoop.utilities.dateutils.DateUtils;

and then:

private var _total:Number = DateUtils.totalDayOfWeekInMonth( DateUtils.Wednesday, new Date( 2009, DateUtils.monthAsNumber( JANUARY ) ) );

which would return 4, as there are 4 Wednesdays in January 2009

/**
 * Formats a month to the numeric version of the month
 * 
 * @param strMonth	The month to convert
 * 
 * @return			A formatted month or -1 if month not found
 */
public static function monthAsNumber( strMonth:String ):Number {
	return ( objMonth[ strMonth ] >= 0 ) ? objMonth[ strMonth ] : -1;
}

This method takes a string version of the month, and then converts it to the numeric version of that month. I use objMonth[ strMonth ] >= 0 rather than just objMonth[ strMonth ], as 0 is also “false” and was returning -1 instead of 0 (for January). This is quite a useful method for me, and, even though it is more typing, I feel it makes more sense to someone skimming/reading the code, which prevents headaches in the future. I even found one example I gave that was using 1, when I actually meant 0, for January, so I altered the example to use this method to remove all confusion.

All methods in this series are describing code in the FlexDateUtils package I put on Google code.

Gareth Flex, FlexDateUtils, code, library , ,

Flex Date Utils – dayOfWeekIterationOfMonth

January 2nd, 2009

This one is fairly complex, but quite useful, so I’m just going to demo one method today.

/**
 * Gets the Xth day of the month.
 * e.g. get the 3rd Wednesday of the month
 * 
 * @param iteration		The iteration of the month to get e.g. 4th or Last
 * @param strDayOfWeek	The day of the week as a string
 * @param date			The date containing the month and year
 * 
 * @return				The date of the xth dayOfWeek of the month 
 */
public static function dayOfWeekIterationOfMonth( iteration:Number, strDayOfWeek:String, date:Date ):Date {
	// get the numeric day of the week for the requested day
	var _dayOfWeek:Number = dayOfWeekAsNumber( strDayOfWeek );
	// get the date for the first of the month
	var _firstOfMonth:Date = new Date( date.fullYear, date.month, 1 );
	// calculate how many days to add to get to the requested day from the first of the month
	var _daysToAdd:Number = _dayOfWeek - DateUtils.dayOfWeek( _firstOfMonth );
	// if dayOfWeek is before the first of the month, get the dayOfWeek for the following week
	if ( _daysToAdd < 0 ) {
		_daysToAdd += 7;
	}
	// set the date to the first day of the week for the requested date
	var _firstDayOfWeekOfMonth:Date = DateUtils.dateAdd( DateUtils.DAY_OF_MONTH, _daysToAdd, _firstOfMonth );
	// return the date if iteration is 1
	if ( iteration == 1 ) {
		return _firstDayOfWeekOfMonth;
	} else {
		// if requesting an iteration that is more than is in that month or requesting the last day of week of month
		// return last date for that day of week of month
		if ( ( DateUtils.totalDayOfWeekInMonth( strDayOfWeek, date ) < iteration ) || ( iteration == DateUtils.LAST ) ) {
			iteration = DateUtils.totalDayOfWeekInMonth( strDayOfWeek, date );
		}
		// subtract 1 as it starts from the first dayOfWeek of month
		return DateUtils.dateAdd( DateUtils.WEEK, iteration - 1, _firstDayOfWeekOfMonth );
	}
}

The name is a little cryptic, but it returns the total number of a day of the week in a specified month. I heavily commented this method in order to be less confusing for anyone who might be trying to decipher what is going on, so I won’t go over what is being done within the method. The method accepts 3 parameters: iteration which represents which dayofweek for a month to get, 1, 2, 3, 4, 5, or LAST (if using the constant), the string representation of the day of the week, and the date containing the month and year to query. It returns the date for the specified iteration.

To implement, first import the package:

import com.flexoop.utilities.dateutils.DateUtils;

then:

private var _dateOfIteration:Date = DateUtils.dayOfWeekIterationOfMonth( 3, DateUtils.TUESDAY, new Date( 2008, DateUtils.monthAsNumber( DateUtils.MAY ) ) );

This will return May 20th, 2008, the 3rd Tuesday in May.

All methods in this series are describing code in the FlexDateUtils package I put on Google code.

Gareth Flex, FlexDateUtils, code, library , ,