Home  >  

Calendar Component in ActionScript 3 Part 2

Author photo
AddThis Social Bookmark Button

In my previous entry I discussed including and implementing the Calendar component in a new project. In this next entry I'm going to explore the Calendar class. The basic idea for the Calendar class is to assemble a collection of days, abstracted from the actual implementation of the days as much as possible. The initial design I created for this component had the Calendar and Day classes be simply abstract classes, but after awhile I felt it was more useful making them base classes so that the component could be used as is, by default, and if you wanted custom functionality you could simply extend the Day or even the Calendar to do what you wished.

With that in mind, many of the private variables are created with initial values - the default Day height and width, the background colors and even the starting X and Y positions - and the constructor even sets today's date as the default.

private var _currDate:Date;
private var _currMonth:Number;
private var _dayList:Array
private static var _dayIDSequence:Number = 0;
		
private var _dayHeight:Number = 50;
private var _dayWidth:Number = 50;
private var _startX:Number = 10;
private var _startY:Number = 10;
		
private const WEEKDAYCOUNT:Number = 7;

		
private var _bgColor:uint      = 0xCCCCCC;
private var _borderColor:uint  = 0x666666;
private var _borderSize:uint   = 1;
        
private var _xTween:Tween;
private var _yTween:Tween;
        
        
public function Calendar(month:Number=0)
{
  _currDate = new Date();
  _currMonth = month
  _dayList = new Array()
}

Next if we follow the trail of implementation that we saw last article, once the Calendar object has been instantiated and added to the stage, we call drawMonth and pass in the month number and two Day objects.

public function drawMonth(tempMonth:Number,tempDay:Day, backDay:Day):void{
 var currentDay:Number = 1
 var dayStepper:Number = 0
 var tempDate:Date = new Date(tempMonth + "/"+currentDay+"/" + new Date().getFullYear());
 var tempMonthChecker:Number = tempDate.getMonth()

This is the main loop for drawCalendar - it's engine if you will. Essentially it will continue to loop as long as the tempDate's month is the same month that the calendar is supposed to be drawing. Each pass through the loop increments tempDate by a day.

while(tempDate.getMonth() + 1 == tempMonth){				
  tempDate = new Date(tempMonth + "/"+currentDay+"/" + new Date().getFullYear());
  tempMonthChecker = tempDate.getMonth()

Before we do anything we check to see what the Day of the week is, if it's Sunday we reset our _startX variable which we'll be incrementing by however wide the Day object is. Resetting it brings it back to the left to start a new row of Days.

 if(tempDate.getDay() == 0){ _startX = 10}	

Next we check to see what day of the week we are on, and how many day iterations into the month we are. Essentially this check is to see if the first of the month lands on a Sunday or not, and if it doesn't it must then back-fill the week that is currently being drawn with empty days. The restingX and restingY are mementos to be able to consistently revert the Day to its original location when/if we resize the day on a Click event


 if(tempDate.getDay() > 0 && currentDay == 1 )
 {
   for(var x:Number = 0;x<tempDate.getDay(); x++)
   {
    backDay = createDay(backDay, tempDate,"","",x)
    backDay.restingX = backDay.x = _startX
    backDay.restingY = backDay.y = _startY
    _startX += _dayWidth
    addChild(backDay);
    dayStepper++
    }
  }

Next we get to the logic that draws out the days of the month. Its the same as the logic that back-filled the empty days for the previous month above, except that we now pass date information into the Day constructor - note for your own implementation you could pass previous month information into the empty back-filled days to have rolling weeks?).

				
 if(tempDate.getMonth() + 1 == tempMonth){
  tempDay = createDay(tempDay, tempDate, "",currentDay.toString(),tempDate.getDay())
  tempDay.restingX = tempDay.x = _startX
  tempDay.restingY = tempDay.y = _startY
  _startX += _dayWidth
  addChild(tempDay);
  dayStepper++
  if(dayStepper % WEEKDAYCOUNT == 0){_startY += _dayHeight}
  currentDay++

Finally here is the else to the if statement from above that checks if we are still in the current month. If we are not in the current month, but we still have days of the week left to draw we then front-fill the current week with empty days.

					
 }else{
   for(var y:Number = tempDate.getDay(); y<WEEKDAYCOUNT;y++)
   {
    backDay = createDay(backDay, tempDate,"","",x)
    backDay.restingX = backDay.x = _startX
    backDay.restingY = backDay.y = _startY
    _startX += _dayWidth
    addChild(backDay);
    }
  }
}
}

In the next entry we'll discuss the parts of the Calendar class that draw and tween the Day objects, as well as the guts of the Day class itself.

Read more from Tom Barker. Tom Barker's Atom feed

Comments

2 Comments

MySchizoBuddy said:

will it include a discussion about recurring events?

Tom Barker said:

Not really, the component is the drawing engine. The days can be extended to do interesting things, like read in a feed to populate calendar events or populate tv listing information. One of the things I'm going to talk about next article are some of the ways to expand the scope of the component, and I've put stub code in the project to do just that.

Leave a comment


Tag Cloud

iPad

What's your take on the iPad? (Putting aside the Flash/iPad flame war)

Answer

Latest Features

Recommended for You

@InsideRIA on Twitter

Archives

  • Or, visit our complete archive.  

About This Site

Welcome to the premiere community site for all things RIA sponsored by O'Reilly Media and Adobe Systems Incorporated.