Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Adobe AIR Development

Reply
Contributor
Posts: 10
Registered: ‎12-07-2010
My Device: Not Specified

SimpleDatePicker Class

[ Edited ]

Morning all,

 

Started a registration page this morning had need for a date picker with a few more rules then the one supplied in the code samples with an easier Implementation. Hashed together a quick class, it's dirty and not good for much else other than rapid prototyping but it works and it's quick. Ran into a few behaviour issues with the picker class so my class contains a dirty workaround which is poorly commented.

 

Implementation:

 

 

var datePicker:SimpleDatePicker = new SimpleDatePicker(400, 50, SimpleDatePicker.CURRENT, 1990, 2030);
				datePicker.drawSimpleDatePicker();
				
			addChild(datePicker);
			
			trace(datePicker.date);
			
			removeChild(datePicker);
			
			datePicker.dispose();
			datePicker = null;

 

 

Class:

 

 

package com
{
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import qnx.ui.data.DataProvider;
	import qnx.ui.picker.Picker;
	
	public class SimpleDatePicker extends Sprite
	{
		public static const BEGINNING:String = "beginning";
		public static const MIDDLE:String = "middle";
		public static const END:String = "end";
		public static const CURRENT:String = "current";
		
		private static const DAY_COUNT_1:int = 30;
		private static const DAY_COUNT_2:int = 31;
		private static const DAY_COUNT_3:int = 28; //DAY_COUNT_3:int = 29; //Leap Years.
	
		private static const MED_PICKER_WIDTH:int = 250;
		private static const MIN_PICKER_WIDTH:int = 200;
		private static const MIN_PICKER_HEIGHT:int = 40;
		
		private static const YEAR_RANGE:int = 120;
		
		private static const MONTHS_LONG_NAMES:Array = new Array({label: "January"}, {label: "February"}, {label: "March"}, {label: "April"}, {label: "May"}, {label: "June"}, {label: "July"}, {label: "August"}, {label: "September"}, {label: "October"}, {label: "November"}, {label: "December"});
		private static const MONTHS_SHORT_NAMES:Array = new Array({label: "Jan"}, {label: "Feb"}, {label: "Mar"}, {label: "Apr"}, {label: "May"}, {label: "Jun"}, {label: "Jul"}, {label: "Aug"}, {label: "Sep"}, {label: "Oct"}, {label: "Nov"}, {label: "Dec"});
		
		private var months:Array = MONTHS_LONG_NAMES;
		private var days:Array = new Array();
		private var years:Array = new Array();
	
		private var picker:Picker;
		private var pickerWidth:int = MIN_PICKER_WIDTH;
		private var pickerHeight:int = MIN_PICKER_HEIGHT;
		private var pickerPosition:String = MIDDLE;
		
		private var dayDataProvider:DataProvider;
		private var monthDataProvider:DataProvider;
		private var yearDataProvider:DataProvider;
		private var dateDataProvier:DataProvider;
		
		private var dateMinYear:int = 0;
		private var dateMaxYear:int = 0;
		
		public function SimpleDatePicker(width:int, height:int, datePickerInitPosition:String = MIDDLE, minYear:int = 0, maxYear:int = 0)
		{
			if(width > MIN_PICKER_WIDTH) pickerWidth = width;
			if(height > MIN_PICKER_HEIGHT) pickerHeight = height;
			
			if(pickerWidth < MED_PICKER_WIDTH)
			{
				months = MONTHS_SHORT_NAMES;
			}
			else
			{
				months = MONTHS_LONG_NAMES;
			}
			
			if(datePickerInitPosition != MIDDLE) pickerPosition = datePickerInitPosition;
			if(minYear != 0)dateMinYear = minYear;
			if(maxYear != 0)dateMaxYear = maxYear;
		}
		public function drawSimpleDatePicker():void
		{
			initEvents();
			init();
		}
		private function initEvents():void
		{
			this.addEventListener(Event.ADDED_TO_STAGE, eventHandler, false, 0, true); //Dirty, dirty workaround begins.
			this.addEventListener(Event.REMOVED_FROM_STAGE, eventHandler, false, 0, true);
		}
		private function init():void
		{
			for (var i:int = 0; i < DAY_COUNT_2; i++)
			{
				var day:int = (i + 1);
				days.push({label: day.toString()});
			} 	
		
			var date:Date = new Date();
			
			if(dateMinYear == 0 && dateMaxYear == 0)
			{
				date.fullYear = (date.fullYear - YEAR_RANGE);
				
				dateMinYear = date.getFullYear();
				
				date = new Date();
				date.fullYear = (date.fullYear + YEAR_RANGE);
					
				dateMaxYear = date.getFullYear();
			}
			
			for (var l:int = dateMinYear; l < (dateMaxYear + 1); l++)
			{
				var year:int = l;
				years.push({label: year.toString()});
			}
		
			dayDataProvider = new DataProvider(days);
			monthDataProvider = new DataProvider(months);
			yearDataProvider = new DataProvider(years);
			dateDataProvier = new DataProvider(new Array(dayDataProvider, monthDataProvider, yearDataProvider));
			
			var pickerYearIndex:int; 
			var pickerMonthIndex:int = 0;
			var pickerDayIndex:int = 0;
			
			switch(pickerPosition)
			{
				case BEGINNING:
					
					pickerYearIndex = 0;
					
					break;
				
				case MIDDLE:
					
					pickerYearIndex = Math.floor(((dateMaxYear - dateMinYear) * 0.5));
					
					break;
				
				case END:
					
					pickerYearIndex = (years.length - 1);
					
					break;
				
				case CURRENT:
					
					date = new Date();
				
					if(date.getFullYear() > dateMaxYear)
					{
						pickerYearIndex = (years.length - 1);
						pickerMonthIndex = (months.length - 1);
						pickerDayIndex = (days.length - 1);
					}
					else
					{
						pickerYearIndex = (dateMaxYear - date.getFullYear());
						pickerMonthIndex = date.month;
						pickerDayIndex = date.date;
					}
				
					break;
			}
		
			picker = new Picker();
			picker.width = pickerWidth;
			picker.height = pickerHeight;
			picker.dataProvider = dateDataProvier;
			picker.addEventListener(Event.SELECT, eventHandler, false, 0, true);
			picker.selectedIndices = [pickerDayIndex, pickerMonthIndex, pickerYearIndex];
				
			addChild(picker);
		}
		private function eventHandler(event:Event):void
		{
			switch(event.type)
			{
				case Event.SELECT:
					
					var pickerIndices:Array = picker.selectedIndices;
					var month:int = (pickerIndices[1] + 1);
					var numOfDays:int;
					
					switch(month)
					{
						case 4:
						case 6:
						case 9:
						case 11:
							
							numOfDays = DAY_COUNT_1;
							
							break;
						
						case 2:
							
							numOfDays = DAY_COUNT_3;
							
							break;
						
						default:
							
							numOfDays = DAY_COUNT_2;
							
							break;
					}
					
					if(days.length != numOfDays) updateDays(numOfDays);
					
					break;
				
				case Event.ADDED_TO_STAGE: //More dirty workaround.
					
					this.removeEventListener(Event.ADDED_TO_STAGE, eventHandler);
					this.addEventListener(Event.REMOVED_FROM_STAGE, eventHandler, false, 0, true);
					this.stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler, false, 0, true);
					
					break;
				
				case Event.REMOVED_FROM_STAGE:
					
					this.removeEventListener(Event.REMOVED_FROM_STAGE, eventHandler);
					this.stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler);
			
					break;
			}
		}
		private function mouseEventHandler(event:MouseEvent):void //Extra dirty workaround.
		{
			if(event.target != this)
			{
				if(picker.isOpen == true) picker.isOpen = false;
			}
		}
		private function updateDays(numOfDays:int):void
		{
			var tempDays:Array = new Array();
			
			for(var i:int = 0; i < numOfDays; i++)
			{
				var day:int = (i + 1);
				tempDays.push({label: day.toString()});
			}
			
			days = tempDays;
			
			dayDataProvider.setItems(days);
			dateDataProvier.updateItemAt(dayDataProvider, 0);
			
			picker.isOpen = true;
			
			/**
			 * The thing is when you update an item in one of the pickers dataProviders it will close the picker on stage, you can then get around this by setting the isOpen setter to true. 
			 * Problem is it will stay that way. 
			 * Frustration.
			 * Dodgey Stage Listener workaround ensues. See line 47, 118, 134 for details.
			 **/
		}
		public function get date():Date
		{
			var returnDate:Date = new Date();
			var yearsIndex:int = picker.selectedIndices[2];
			var yearsObject:Object = years[yearsIndex];
			var yearsString:String = yearsObject.label;
			
			//var year:int = int(years[picker.selectedIndices[2]].label);
			
			var year:int = int(yearsString);
			var month:int = picker.selectedIndices[1];
			var date:int = (picker.selectedIndices[0] + 1);
			
			returnDate.fullYear = year;
			returnDate.month = month;
			returnDate.date = date;
		
			return returnDate;
		}
		public function dispose():void
		{
			while(this.numChildren > 0) this.removeChildAt(0);
			
			months = null;
			days = null;
			years = null;
			
			dayDataProvider = null;
			monthDataProvider = null;
			yearDataProvider = null;
			dateDataProvier = null;
			
			pickerPosition = null;
			
			picker.removeEventListener(Event.SELECT, eventHandler);
			picker.destroy();
			picker = null;
		}
	}
}

 

 

 

Feel free to do what ever you want with it, I hope it helps speed up rough prototyping for a few of you. I'll revisit it and create/release a decent date picker when I optimise my app at a later date.

 

Sam

Developer
Posts: 6,541
Registered: ‎10-27-2010
My Device: HTC One, PlayBook, LE Z10, DE Q10
My Carrier: Verizon

Re: SimpleDatePicker Class

Thanks for your contribution.