Permalink
Browse files

Merge pull request #363 from samsoir/master

Refactored iOS DatePicker plugin
  • Loading branch information...
2 parents bb7338d + 76a724e commit d07bc00fc3ce05df85dafd25bd1da8108e521fa9 @shazron shazron committed Feb 22, 2012
Showing with 178 additions and 56 deletions.
  1. +8 −3 iPhone/DatePicker/DatePicker.h
  2. +13 −2 iPhone/DatePicker/DatePicker.js
  3. +157 −51 iPhone/DatePicker/DatePicker.m
@@ -9,16 +9,21 @@
#import "PGPlugin.h"
#endif
+#ifndef k_DATEPICKER_DATETIME_FORMAT
+#define k_DATEPICKER_DATETIME_FORMAT @"yyyy-MM-dd'T'HH:mm:ss'Z'"
+#endif
-@interface DatePicker : PGPlugin {
- UIActionSheet *datePickerSheet;
- UIDatePicker *datePicker;
+@interface DatePicker : PGPlugin <UIActionSheetDelegate> {
+ UIActionSheet *_datePickerSheet;
+ UIDatePicker *_datePicker;
+ NSDateFormatter *_isoDateFormatter;
BOOL isVisible;
}
@property (nonatomic, retain) UIActionSheet* datePickerSheet;
@property (nonatomic, retain) UIDatePicker* datePicker;
+@property (nonatomic, retain) NSDateFormatter* isoDateFormatter;
//- (void) prepare:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
@@ -15,11 +15,22 @@ if (typeof PhoneGap !== "undefined") {
* show - true to show the ad, false to hide the ad
*/
DatePicker.prototype.show = function(options, cb) {
+ var padDate = function(date) {
+ if (date.length == 1) {
+ return ("0" + date);
+ }
+ return date;
+ };
+
if (options.date) {
- options.date = (options.date.getMonth()+1)+"/"+(options.date.getDate())+"/"+(options.date.getFullYear());
+ options.date = options.date.getFullYear() + "-" +
+ padDate(options.date.getMonth()+1) + "-" +
+ padDate(options.date.getDate()) +
+ "T" + padDate(options.date.getHours()) + ":" +
+ padDate(options.date.getMinutes()) + ":00Z";
}
var defaults = {
- mode: '',
+ mode: 'datetime',
date: '',
allowOldDates: true
}
@@ -1,79 +1,185 @@
// Phonegap DatePicker Plugin
// Copyright (c) Greg Allen 2011
// MIT Licensed
+//
+// Additional refactoring by Sam de Freyssinet
#import "DatePicker.h"
+@interface DatePicker (Private)
+// Initialize the UIActionSheet with ID <UIActionSheetDelegate> delegate UIDatePicker datePicker (UISegmentedControl)closeButton
+- (void)initActionSheet:(id <UIActionSheetDelegate>)delegateOrNil datePicker:(UIDatePicker *)datePicker closeButton:(UISegmentedControl *)closeButton;
+
+// Creates the NSDateFormatter with NSString format and NSTimeZone timezone
+- (NSDateFormatter *)createISODateFormatter:(NSString *)format timezone:(NSTimeZone *)timezone;
+
+// Creates the UIDatePicker with NSMutableDictionary options
+- (UIDatePicker *)createDatePicker:(CGRect)pickerFrame;
+
+// Creates the UISegmentedControl with UIView parentView, NSString title, ID target and SEL action
+- (UISegmentedControl *)createActionSheetCloseButton:(NSString *)title target:(id)target action:(SEL)action;
+
+// Configures the UIDatePicker with the NSMutableDictionary options
+- (void)configureDatePicker:(NSMutableDictionary *)optionsOrNil;
+
+@end
@implementation DatePicker
-@synthesize datePickerSheet;
-@synthesize datePicker;
+@synthesize datePickerSheet = _datePickerSheet;
+@synthesize datePicker = _datePicker;
+@synthesize isoDateFormatter = _isoDateFormatter;
+
+#pragma mark - Public Methods
+
+- (PGPlugin *)initWithWebView:(UIWebView *)theWebView
+{
+ self = (DatePicker *)[super initWithWebView:theWebView];
+
+ if (self)
+ {
+ UIDatePicker *userDatePicker = [self createDatePicker:CGRectMake(0, 40, 0, 0)];
+ UISegmentedControl *datePickerCloseButton = [self createActionSheetCloseButton:@"Close" target:self action:@selector(dismissActionSheet:)];
+ NSDateFormatter *isoTimeFormatter = [self createISODateFormatter:k_DATEPICKER_DATETIME_FORMAT timezone:[NSTimeZone defaultTimeZone]];
+ self.datePicker = userDatePicker;
+ self.isoDateFormatter = isoTimeFormatter;
-#pragma mark -
-#pragma mark Public Methods
+ [self initActionSheet:self datePicker:userDatePicker closeButton:datePickerCloseButton];
+ }
+ return self;
+}
-- (void) show:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+- (void)show:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
- if (isVisible)
- return;
- NSString *mode = [options objectForKey:@"mode"];
- NSString *dateString = [options objectForKey:@"date"];
-
- NSLog(@"Show Datepicker");
-
- datePickerSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
-
- [datePickerSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
-
- CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
-
- self.datePicker = [[UIDatePicker alloc] initWithFrame:pickerFrame];
- bool allowOldDates = ([[options objectForKey:@"allowOldDates"] intValue] == 1)?YES:NO;
- if (!allowOldDates) {
- self.datePicker.minimumDate = [NSDate date];
+ if (isVisible) {
+ return;
}
- if ([mode isEqualToString:@"date"]) {
- self.datePicker.datePickerMode = UIDatePickerModeDate;
- NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
- [dateFormatter setTimeZone:[NSTimeZone defaultTimeZone]];
- [dateFormatter setDateFormat:@"MM/dd/yyyy"];
- NSDate *date = [dateFormatter dateFromString:dateString];
- [dateFormatter release];
- self.datePicker.date = date;
+ [self configureDatePicker:options];
+ [self.datePickerSheet showInView:[[super webView] superview]];
+ [self.datePickerSheet setBounds:CGRectMake(0, 0, 320, 485)];
+
+ isVisible = YES;
+}
+
+- (void)dismissActionSheet:(id)sender {
+ [self.datePickerSheet dismissWithClickedButtonIndex:0 animated:YES];
+}
+
+- (void)onMemoryWarning
+{
+ // It could be better to close the datepicker before the system
+ // clears memory. But in reality, other non-visible plugins should
+ // be tidying themselves at this point. This could cause a fatal
+ // at runtime.
+ if (isVisible) {
+ return;
}
- else if ([mode isEqualToString:@"time"])
- self.datePicker.datePickerMode = UIDatePickerModeTime;
-
- [datePickerSheet addSubview:self.datePicker];
-
- UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:@"Close"]];
+
+ [self release];
+}
+
+- (void)dealloc
+{
+ [_datePicker release];
+ [_datePickerSheet release];
+ [_isoDateFormatter release];
+
+ [super dealloc];
+}
+
+#pragma mark - UIActionSheetDelegate methods
+
+- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex
+{
+ NSString* jsCallback = [NSString stringWithFormat:@"window.plugins.datePicker._dateSelected(\"%i\");", (int)[self.datePicker.date timeIntervalSince1970]];
+ [super writeJavascript:jsCallback];
+}
+
+- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
+{
+ isVisible = NO;
+}
+
+#pragma mark - Private Methods
+
+- (void)initActionSheet:(id <UIActionSheetDelegate>)delegateOrNil datePicker:(UIDatePicker *)datePicker closeButton:(UISegmentedControl *)closeButton
+{
+ UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
+ delegate:delegateOrNil
+ cancelButtonTitle:nil
+ destructiveButtonTitle:nil
+ otherButtonTitles:nil];
+
+ [actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
+
+ [actionSheet addSubview:datePicker];
+ [actionSheet addSubview:closeButton];
+
+ self.datePickerSheet = actionSheet;
+
+ [actionSheet release];
+}
+
+- (UIDatePicker *)createDatePicker:(CGRect)pickerFrame
+{
+ UIDatePicker *datePickerControl = [[UIDatePicker alloc] initWithFrame:pickerFrame];
+ return [datePickerControl autorelease];
+}
+
+- (NSDateFormatter *)createISODateFormatter:(NSString *)format timezone:(NSTimeZone *)timezone;
+{
+ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
+ [dateFormatter setTimeZone:timezone];
+ [dateFormatter setDateFormat:format];
+
+ return [dateFormatter autorelease];
+}
+
+- (UISegmentedControl *)createActionSheetCloseButton:(NSString *)title target:(id)target action:(SEL)action
+{
+ UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:title]];
+
closeButton.momentary = YES;
closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle = UISegmentedControlStyleBar;
closeButton.tintColor = [UIColor blackColor];
- [closeButton addTarget:self action:@selector(dismissActionSheet:) forControlEvents:UIControlEventValueChanged];
- [datePickerSheet addSubview:closeButton];
- [closeButton release];
-
- [datePickerSheet showInView:[[super webView] superview]];
-
- [datePickerSheet setBounds:CGRectMake(0, 0, 320, 485)];
- isVisible = YES;
+ [closeButton addTarget:target action:action forControlEvents:UIControlEventValueChanged];
+
+ return [closeButton autorelease];
}
-- (void) dismissActionSheet:(id)sender {
- [datePickerSheet dismissWithClickedButtonIndex:0 animated:YES];
- [datePickerSheet release];
- [datePicker release];
- NSString* jsCallback = [NSString stringWithFormat:@"window.plugins.datePicker._dateSelected(\"%i\");", (int)[self.datePicker.date timeIntervalSince1970]];
- [super writeJavascript:jsCallback];
- isVisible = NO;
+- (void)configureDatePicker:(NSMutableDictionary *)optionsOrNil;
+{
+ NSString *mode = [optionsOrNil objectForKey:@"mode"];
+ NSString *dateString = [optionsOrNil objectForKey:@"date"];
+ BOOL allowOldDates = NO;
+
+ if ([[optionsOrNil objectForKey:@"allowOldDates"] intValue] == 1) {
+ allowOldDates = YES;
+ }
+
+ if ( ! allowOldDates) {
+ self.datePicker.minimumDate = [NSDate date];
+ }
+
+ self.datePicker.date = [self.isoDateFormatter dateFromString:dateString];
+
+ if ([mode isEqualToString:@"date"]) {
+ self.datePicker.datePickerMode = UIDatePickerModeDate;
+ }
+ else if ([mode isEqualToString:@"time"])
+ {
+ self.datePicker.datePickerMode = UIDatePickerModeTime;
+ }
+ else
+ {
+ self.datePicker.datePickerMode = UIDatePickerModeDateAndTime;
+ }
}
@end

0 comments on commit d07bc00

Please sign in to comment.