diff --git a/README.md b/README.md
index 8404294..15a2699 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
[](https://www.npmjs.com/package/nativescript-datetimepicker)
[](https://travis-ci.org/NativeScript/nativescript-datetimepicker)
-A [NativeScript](https://www.nativescript.org) plugin that provides ui elements for picking date and time. The plugin provides two fields - `DatePickerField` and `TimePickerField` - both are NativeScript Views that show selected date or time and allow picking another after being tapped. There is also a `DateTimePicker` class which provides static methods `pickDate` and `pickTime` that can be called to show the same dialog picker as the fields.
+A [NativeScript](https://www.nativescript.org) plugin that provides ui elements for picking date and time. The plugin provides UI elements for picking date and time - `DatePickerField`, `TimePickerField` and `DateTimePickerFields` - they are all NativeScript Views that show selected date and/or time and allow picking another after being tapped. There is also a `DateTimePicker` class which provides static methods `pickDate` and `pickTime` that can be called to show the same dialog picker as the fields.
- [Installation](#installation)
@@ -12,6 +12,7 @@ A [NativeScript](https://www.nativescript.org) plugin that provides ui elements
- [Usage](#usage)
- [Features](#features)
- [DatePickerField and TimePickerField](#datepickerfield-and-timepickerfield)
+ - [DateTimePickerFields](#datetimepickerfields)
- [DateTimePicker](#datetimepicker)
- [API](#api)
- [Contribute](#contribute)
@@ -32,7 +33,7 @@ tns plugin add nativescript-datetimepicker
No additional configuration required!
## Usage
-To use the `DatePickerField` and `TimePickerField` in markup you need to:
+To use one of the UI elements `DatePickerField`, `TimePickerField` or `DateTimePickerFields` in markup you need to:
- If you are developing a NativeScript Core app, you need to register the plugin namespace in the xml:
```xml
+
...
```
- If you are developing a NativeScript Angular app, you need to import the plugin module in the module of your component:
@@ -58,6 +60,7 @@ import { NativeScriptDateTimePickerModule } from "nativescript-datetimepicker/an
```html
+
```
- If you are developing a NativeScript Vue app, you need to install the plugin in you app.js file:
```js
@@ -69,6 +72,7 @@ Then you will be able to decrare the fields in the template of your component:
```html
+
```
## Features
@@ -78,23 +82,23 @@ The `DatePickerField` and the `TimePickerField` are NativeScript Views that exte
- Getting/Setting Date and Time
-The `DatePickerField` has a `date` property and the `TimePickerField` has a `time` property which can be used to get their current value. You can also set their value through markup. `DatePickerField`'s `date` property will just pass the string you provide as a parameter to the [Date constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date), while the `TimePickerField`'s `time` property can parse values in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Times) format. Here's an example in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L18), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L13) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L15) applications.
+The `DatePickerField` has a `date` property and the `TimePickerField` has a `time` property which can be used to get their current value. You can also set their value through markup. `DatePickerField`'s `date` property will just pass the string you provide as a parameter to the [Date constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date), while the `TimePickerField`'s `time` property can parse values in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Times) format. Here's an example in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L19), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L14) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L16) applications.
- TextField Features
-Both `DatePickerField` and `TimePickerField` extend `TextField`, so each `TextField` feature like the `hint` property, is also available for these fields. Here's an example in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L13), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L8) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L10) applications.
+Both `DatePickerField` and `TimePickerField` extend `TextField`, so each `TextField` feature like the `hint` property, is also available for these fields. Here's an example in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L15), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L10) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L12) applications.
- Picker Texts
-When one of the fields is tapped, a popup is opened. The popup has an OK and Cancel buttons and an optional title. Their text values are controlled respectively by the properties `pickerOkText`, `pickerCancelText` and `pickerTitle`. By default, the texts of the buttons OK and Cancel are `OK` and `Cancel` on iOS, and a localized version of OK and Cancel, dependent on the current setting of the device on Android. The `pickerTitle` is undefined. Changing these values is demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L35), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L32) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L32) applications.
+When one of the fields is tapped, a popup is opened. The popup has an OK and Cancel buttons and an optional title. Their text values are controlled respectively by the properties `pickerOkText`, `pickerCancelText` and `pickerTitle`. By default, the texts of the buttons OK and Cancel are `OK` and `Cancel` on iOS, and a localized version of OK and Cancel, dependent on the current setting of the device on Android. The `pickerTitle` is undefined. Changing these values is demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L27), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L22) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L24) applications.
- Localization
-By default the `DatePickerField` and the `TimePickerField` will use the current language and region settings of the device to determine their locale. The locale is used for the names of the months, for the date picking spinners order (the month selector can be either the first or the second spinner) and whether the time is in 12h or 24h format. Both fields have a `locale` property that accepts values in the format specified [here](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html) as Locale ID. For example, using `en_UK` will result in month names spinner in the middle and values between 0 and 23 for the hours, while using `en_US` will result in month names spinner on the left and values between 1 and 12 for the hours. Changing the locale is demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L49), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L44) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L46) applications.
+By default the `DatePickerField` and the `TimePickerField` will use the current language and region settings of the device to determine their locale. The locale is used for the names of the months, for the date picking spinners order (the month selector can be either the first or the second spinner) and whether the time is in 12h or 24h format. Both fields have a `locale` property that accepts values in the format specified [here](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html) as Locale ID. For example, using `en_GB` will result in month names spinner in the middle and values between 0 and 23 for the hours, while using `en_US` will result in month names spinner on the left and values between 1 and 12 for the hours. Changing the locale is demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L37), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L32) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L34) applications.
- Formats
-Aside from the default formats that are dependent on the value of the `locale` property, you can add your custom format that can include ordering of the date/time values and also custom text. The property controlling the format in the `DatePickerField` is called `dateFormat` and the property controlling the format in the `TimePickerField` is `timeFormat`. Changing the default formats is demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L56), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L51) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L53) applications.
+Aside from the default formats that are dependent on the value of the `locale` property, you can add your custom format that can include ordering of the date/time values and also custom text. The property controlling the format in the `DatePickerField` is called `dateFormat` and the property controlling the format in the `TimePickerField` is `timeFormat`. Changing the default formats is demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L42), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L37) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L39) applications.
- Minimum and Maximum Dates
@@ -102,7 +106,7 @@ The `DatePickerField` has a `minDate` and `maxDate` properties that allow limiti
- Using 12 h and 24 h Time Formats
-The `TimePickerField` will determine whether to use 12 or 24 hour format (for formatting of the selected time in the field and for the values of the hour spinner) based on the selected region in the settings of the iOS device and based on the Use 24-Hour Format settings of the Android device. To change the default setting on Android, you need to use the `timeFormat` property and to change the setting on iOS, you need to use the `locale` property. Here's an example in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L27), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L22) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L24) applications.
+The `TimePickerField` will determine whether to use 12 or 24 hour format (for formatting of the selected time in the field and for the values of the hour spinner) based on the selected region in the settings of the iOS device and based on the Use 24-Hour Format settings of the Android device. To change the default setting on Android, you need to use the `timeFormat` property and to change the setting on iOS, you need to use the `locale` property. Here's an example in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L66), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L61) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L63) applications.
- CSS
@@ -110,11 +114,50 @@ You can use css to style the `DatePickerField` and the `TimePickerField`. The fi
-Here's the css used to achieve the above result, as used in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.css#L9), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.css#L9) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L164) applications.
+Here's the css used to achieve the above result, as used in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.css#L22), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.css#L22) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L350) applications.
+
+### DateTimePickerFields
+The `DateTimePickerFields` extends `GridLayout` that contains instances of `DatePickerField` and `TimePickerField`, when tapped, they open a picker dialog that allows date/time selection.
+
+- Getting/Setting Date and Time
+
+The `DateTimePickerFields` has a `date` property which can be used to get its current value. You can also set its value through markup. `DateTimePickerFields`' `date` property will just pass the string you provide as a parameter to the [Date constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date). Here's an example in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L109), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L104) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L106) applications.
+
+- Orientation
+
+The `DateTimePickerFields` have an `orientation` property which allows changing the way the fields are laid out. If the orientation is `horizontal` (the default), the fields are on the same row, if the orienation is `vertical`, the fields will be on separate rows. Here's an example in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L160), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L155) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L157) applications.
+
+- Auto Pick Time
+
+When a date is picked with the date component of the `DateTimePickerFields`, the value of the `date` property is updated with the value that is picked. Since the time component also controls the same property, it may be meaningful to display or not to display this value. The `autoPickTime` property controls whether the time component should display the time of the `date` property as soon as it is assigned (when date is picked). Default is `false`, which means that when the user selects a date, the time component will keep displaying its hint text until time is explicitly selected through the time spinners. Here's an example in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L126), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L121) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L123) applications.
+
+- Picker Texts
+
+When one of the fields is tapped, a popup is opened. The popup has an OK and Cancel buttons and an optional title. Their text values are controlled respectively by the properties `pickerOkText`, `pickerCancelText`, `pickerTitleDate` and `pickerTitleTime`. By default, the texts of the buttons OK and Cancel are `OK` and `Cancel` on iOS, and a localized version of OK and Cancel, dependent on the current setting of the device on Android. The `pickerTitleDate` and `pickerTitleTime` are undefined. Changing these values is demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L126), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L121) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L123) applications.
+
+- Localization
+
+By default the `DateTimePickerFields` will use the current language and region settings of the device to determine their locale. The locale is used for the names of the months, for the date picking spinners order (the month selector can be either the first or the second spinner) and whether the time is in 12h or 24h format. Both fields have a `locale` property that accepts values in the format specified [here](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html) as Locale ID. For example, using `en_GB` will result in month names spinner in the middle and values between 0 and 23 for the hours, while using `en_US` will result in month names spinner on the left and values between 1 and 12 for the hours. Changing the locale is demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L139), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L134) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L136) applications.
+
+- Formats
+
+Aside from the default formats that are dependent on the value of the `locale` property, you can add your custom format that can include ordering of the date/time values and also custom text. The property controlling the format for the date component is called `dateFormat` and the property controlling the format in the time component is `timeFormat`. Changing the default formats is demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L145), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L140) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L142) applications.
+
+- Minimum and Maximum Dates
+
+The `DateTimePickerFields` has a `minDate` and `maxDate` properties that allow limiting the values that can be selected. Note that the values of these properties have effect only on the date component, while the time component can not be limited - it will always allow any hour for any given date. This is demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L113), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L108) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L110) applications.
+
+- Using 12 h and 24 h Time Formats
+
+The time component will determine whether to use 12 or 24 hour format (for formatting of the selected time in the field and for the values of the hour spinner) based on the selected region in the settings of the iOS device and based on the Use 24-Hour Format settings of the Android device. To change the default setting on Android, you need to use the `timeFormat` property and to change the setting on iOS, you need to use the `locale` property. Here's an example in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-page.xml#L118), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.html#L113) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L115) applications.
+
+- CSS
+
+You can use css to style the `DateTimePickerFields`. The element can be styled like any other layout, additionally the `DatePickerField` and the `TimePickerField` that it contains can be styled as explained in their documentation section.
### DateTimePicker
-Internally `DatePickerField` and `TimePickerField` call `DateTimePicker`'s `pickDate` and `pickTime` methods which are public, so they can also be manually called in case a more customized picker is desired. The `pickDate` method accepts `DatePickerOptions`, while the `pickTime` method accepts `TimePickerOptions`. These options allow having the same features as in the fields. These methods are demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-view-model.ts#L19), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.ts#L32) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L101) applications.
+Internally `DatePickerField` and `TimePickerField` call `DateTimePicker`'s `pickDate` and `pickTime` methods which are public, so they can also be manually called in case a more customized picker is desired. The `pickDate` method accepts `DatePickerOptions`, while the `pickTime` method accepts `TimePickerOptions`. These options allow having the same features as in the fields. These methods are demonstrated in the [demo](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo/app/home/home-view-model.ts#L25), [demo-angular](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-angular/src/app/home/home.component.ts#L44) and [demo-vue](https://github.com/NativeScript/nativescript-datetimepicker/blob/master/demo-vue/app/components/Home.vue#L219) applications.
## API
@@ -125,7 +168,7 @@ Internally `DatePickerField` and `TimePickerField` call `DateTimePicker`'s `pick
| `date` | The date the picker field is currently displaying. |
| `minDate` | The minimum date the picker field can select. |
| `maxDate` | The maximum date the picker field can select. |
-| `locale` | Identifier of a locale that will be used to localize the names of the month names and also the order of the spinners (with `en_UK` first spinner is day, with `en_US` first spinner is month) (default is based on the device’s locale settings). |
+| `locale` | Identifier of a locale that will be used to localize the names of the month names and also the order of the spinners (with `en_GB` first spinner is day, with `en_US` first spinner is month) (default is based on the device’s locale settings). |
| `dateFormat` | Format used for the text in the picker field (on android used as a pattern for a [SimpleDateFormat](https://developer.android.com/reference/java/text/SimpleDateFormat), on iOS used as a dateFormat for [NSDateFormatter](https://developer.apple.com/documentation/foundation/nsdateformatter), default is generated by the current value of the `locale` property). |
| `pickerDefaultDate` | The date that will be displayed in the picker, if it is opened while date is undefined (if `pickerDefaultDate` is undefined, the picker will display today) |
| `pickerTitle` | Text that will be displayed as title of the picker, default is undefined. |
@@ -144,6 +187,26 @@ Internally `DatePickerField` and `TimePickerField` call `DateTimePicker`'s `pick
| `pickerOkText` | Text for the confirmation button of the picker (default is OK on iOS, localized version of OK on android (based on the devices locale settings)). |
| `pickerCancelText` | Text for the cancel button of the picker (default is Cancel on iOS, localized version of Cancel on android (based on the devices locale settings)). |
+### DateTimePickerFields API
+
+| Property | Description |
+| --- | --- |
+| `date` | The date the picker fields are currently displaying. |
+| `minDate` | The minimum date the date component can select. |
+| `maxDate` | The maximum date the time component can select. |
+| `locale` | Identifier of a locale that will be used to localize the names of the month names, the order of the date spinners (with `en_GB` first spinner is day, with `en_US` first spinner is month), and to create locale-specific time formatter of the time (if the format is 12-Hour, with de_DE locale “vorm.”/”nachm.” will be used to show whether time is before/after noon, with en_US locale “am”/”pm” will be used) (default is based on the device’s locale settings). The locale will also be used on iOS to determine whether the picker will be in 12 or 24 hour format. |
+| `dateFormat` | Format used for the text in the picker field (on android used as a pattern for a [SimpleDateFormat](https://developer.android.com/reference/java/text/SimpleDateFormat), on iOS used as a dateFormat for [NSDateFormatter](https://developer.apple.com/documentation/foundation/nsdateformatter), default is generated by the current value of the `locale` property). |
+| `timeFormat` | Format used for the text in the picker field (on android used as a pattern for a [SimpleDateFormat](https://developer.android.com/reference/java/text/SimpleDateFormat), on iOS used as a dateFormat for [NSDateFormatter](https://developer.apple.com/documentation/foundation/nsdateformatter), default is generated by the current value of the locale property), the format will also be used on Android to determine whether the picker will be in 12 or 24 hour format. |
+| `pickerDefaultTime` | The time that will be displayed in the picker, if it is opened while time is undefined (if defaultTime is undefined, the picker will display now). |
+| `pickerTitleDate` | Text that will be displayed as title of the picker, when the date component is tapped, default is undefined. |
+| `pickerTitleTime` | Text that will be displayed as title of the picker, when the time component is tapped, default is undefined. |
+| `pickerOkText` | Text for the confirmation button of the picker (default is OK on iOS, localized version of OK on android (based on the devices locale settings)). |
+| `pickerCancelText` | Text for the cancel button of the picker (default is Cancel on iOS, localized version of Cancel on android (based on the devices locale settings)). |
+| `autoPickTime` | Value that indicates whether the time component should be assigned a value as soon as a date is picked by the date component, default is false. |
+| `orientation` | Value that indicates how the date and time components will be arranged, default is "horizontal", which means that they will be on the same row. |
+| `hintDate` | Text displayed in the date component when `date` is `null`. |
+| `hintTime` | Text displayed in the time component when `date` is `null`. |
+
### DateTimePicker API
**DateTimePicker**:
@@ -161,7 +224,7 @@ Internally `DatePickerField` and `TimePickerField` call `DateTimePicker`'s `pick
| `date` | The date that will be displayed in the picker, (if not provided, the picker will display today). |
| `minDate` | The minimum date that can be selected. |
| `maxDate` | The maximum date that can be selected. |
-| `locale` | Identifier of a locale that will be used to localize the names of the month names and also the order of the spinners (with `en_UK` first spinner is day, with `en_US` first spinner is month, default is based on the device’s locale settings). |
+| `locale` | Identifier of a locale that will be used to localize the names of the month names and also the order of the spinners (with `en_GB` first spinner is day, with `en_US` first spinner is month, default is based on the device’s locale settings). |
| `title` | Text that will be displayed as title of the picker, default is undefined. |
| `okButtonText` | Text for the confirmation button of the picker (default is OK on iOS, localized version of OK on android (based on the devices locale settings)). |
| `cancelButtonText` | Text for the cancel button of the picker (default is Cancel on iOS, localized version of Cancel on android (based on the devices locale settings)). |
diff --git a/demo-angular/e2e/resources/images/datetimepicker-ng-android/Android GoogleAPI Emulator/cssDatePicker.png b/demo-angular/e2e/resources/images/datetimepicker-ng-android/Android GoogleAPI Emulator/cssDatePicker.png
index eec1d1e..fbd4bef 100644
Binary files a/demo-angular/e2e/resources/images/datetimepicker-ng-android/Android GoogleAPI Emulator/cssDatePicker.png and b/demo-angular/e2e/resources/images/datetimepicker-ng-android/Android GoogleAPI Emulator/cssDatePicker.png differ
diff --git a/demo-angular/e2e/resources/images/datetimepicker-ng-android/Android GoogleAPI Emulator/cssTimePicker.png b/demo-angular/e2e/resources/images/datetimepicker-ng-android/Android GoogleAPI Emulator/cssTimePicker.png
index eaebbec..8252547 100644
Binary files a/demo-angular/e2e/resources/images/datetimepicker-ng-android/Android GoogleAPI Emulator/cssTimePicker.png and b/demo-angular/e2e/resources/images/datetimepicker-ng-android/Android GoogleAPI Emulator/cssTimePicker.png differ
diff --git a/demo-angular/e2e/resources/images/datetimepicker-ng-ios/iPhone X/cssDatePicker.png b/demo-angular/e2e/resources/images/datetimepicker-ng-ios/iPhone X/cssDatePicker.png
index 3a5c87f..2c2e8ef 100644
Binary files a/demo-angular/e2e/resources/images/datetimepicker-ng-ios/iPhone X/cssDatePicker.png and b/demo-angular/e2e/resources/images/datetimepicker-ng-ios/iPhone X/cssDatePicker.png differ
diff --git a/demo-angular/e2e/resources/images/datetimepicker-ng-ios/iPhone X/cssTimePicker.png b/demo-angular/e2e/resources/images/datetimepicker-ng-ios/iPhone X/cssTimePicker.png
index 8eba30d..900abe4 100644
Binary files a/demo-angular/e2e/resources/images/datetimepicker-ng-ios/iPhone X/cssTimePicker.png and b/demo-angular/e2e/resources/images/datetimepicker-ng-ios/iPhone X/cssTimePicker.png differ
diff --git a/demo-angular/e2e/tests.e2e.ts b/demo-angular/e2e/tests.e2e.ts
index 7acbc59..8bd225e 100644
--- a/demo-angular/e2e/tests.e2e.ts
+++ b/demo-angular/e2e/tests.e2e.ts
@@ -65,6 +65,12 @@ describe("DateTimePicker", () => {
expect(title).to.exist;
});
+ it("Should expand date picker field examples", async () => {
+ const dateFieldTitle = await driver.findElementByText("DatePickerField", SearchOptions.contains);
+ expect(dateFieldTitle).to.exist;
+ await dateFieldTitle.click();
+ });
+
it("Should select date and verify value of picker field", async () => {
const selectDateField = await driver.findElementByText("select date", SearchOptions.contains);
await selectDateField.click();
@@ -74,15 +80,6 @@ describe("DateTimePicker", () => {
expect(dateSelected).to.exist;
});
- it("Should select time and verify value of picker field", async () => {
- const selectTimeField = await driver.findElementByText("select time", SearchOptions.contains);
- await selectTimeField.click();
- const timeString = await getPickerTime(driver, 12);
- await clickOkBtn(driver);
- const timeSelected = await driver.findElementByText(timeString, SearchOptions.contains);
- expect(timeSelected).to.exist;
- });
-
it("Should select date from min/max limited field", async () => {
const minMaxDatePicker = await driver.findElementByText("tap to select", SearchOptions.contains);
await minMaxDatePicker.click();
@@ -93,22 +90,6 @@ describe("DateTimePicker", () => {
expect(dateSelected).to.exist;
});
- it("Should open 12h time format and verify wheelers values", async () => {
- const twelveHourFormat = await driver.findElementByText("4:00 PM", SearchOptions.contains);
- await twelveHourFormat.click();
- const timeString = await getPickerTime(driver, 12);
- await clickOkBtn(driver);
- expect(timeString).to.equal("4:00 PM");
- });
-
- it("Should open 24h format and verify wheeler value", async () => {
- const twentyFourFormat = await scrollToElement(driver, "16:00", Direction.down);
- await twentyFourFormat.click();
- const timeString = await getPickerTime(driver, 24);
- await clickOkBtn(driver);
- expect(timeString).to.equal("16:00");
- });
-
it("Should verify modified texts field for date picker", async () => {
await scrollToElement(driver, "preferred locale: en_US", Direction.down);
const pickers = await driver.findElementsByText("tap to choose");
@@ -126,23 +107,8 @@ describe("DateTimePicker", () => {
expect(dateString).to.exist;
});
- it("Should verify modified texts field for time picker", async () => {
- const datePicker = await driver.findElementByText("tap to choose");
- await datePicker.click();
- const time = await getPickerTime(driver, 12);
- const approveBtn = await driver.findElementByText("Approve", SearchOptions.contains);
- const rejectBtn = await driver.findElementByText("Reject", SearchOptions.contains);
- const title = await driver.findElementByText("Confirm predefined time selection", SearchOptions.contains);
- expect(approveBtn).to.exist;
- expect(rejectBtn).to.exist;
- expect(title).to.exist;
- await approveBtn.click();
- const dateString = await driver.findElementByText(time);
- expect(dateString).to.exist;
- });
-
it("Should select date from de_De locale picker and verify format", async () => {
- await scrollToElement(driver, "zeit wählen", Direction.down);
+ await scrollToElement(driver, "datum auswählen", Direction.down);
const deLocale = await driver.findElementByText("preferred locale: de_DE");
expect(deLocale).to.exist;
const datePicker = await driver.findElementByText("datum auswählen", SearchOptions.contains);
@@ -181,56 +147,35 @@ describe("DateTimePicker", () => {
expect(dateString).to.exist;
});
- it("Should select time from de_DE locale picker and verify format", async () => {
- const timePicker = await driver.findElementByText("zeit wählen", SearchOptions.contains);
- await timePicker.click();
- const time = await getPickerTime(driver, 24);
- let acceptBtn;
- let rejectBtn;
- if(driver.isAndroid){
- let buttons = await driver.findElementsByClassName("android.widget.Button");
- acceptBtn = buttons[5];
- rejectBtn = buttons[4];
- }
- else{
- acceptBtn = await driver.findElementByText("Bestätigen", SearchOptions.exact);
- rejectBtn = await driver.findElementByText("Stornieren", SearchOptions.exact);
- }
- const title = await driver.findElementByText("Zeit wählen", SearchOptions.exact);
- expect(acceptBtn).to.exist;
- expect(rejectBtn).to.exist;
- expect(title).to.exist;
- await acceptBtn.click();
- const dateField = await driver.findElementByText(time);
- expect(time).to.exist;
- });
-
it("Should scroll to custom format and verify values", async () => {
await scrollToElement(driver, "binding", Direction.down);
const customFromatLabel = await driver.findElementByText("custom format");
expect(customFromatLabel).to.exist;
const customFormatDate = await driver.findElementByText("date: 24 February 2019", SearchOptions.exact);
expect(customFormatDate).to.exist;
- const customFormatTime = await driver.findElementByText("time: 01:00", SearchOptions.exact);
- expect(customFormatTime).to.exist;
+ });
+
+ it("Should scroll to css styled DatePicker and verify picker style", async () => {
+ let cssPickers = await driver.findElementsByText("Feb 24, 2019", SearchOptions.exact);
+ await cssPickers[cssPickers.length - 1].click();
+ await getPickerDate(driver);
+ await driver.compareScreen("cssDatePicker");
+ await clickOkBtn(driver);
});
it("Should scroll to binding example and verify picker and label values", async () => {
- await scrollToElement(driver, "css applied", Direction.down);
+ await scrollToElement(driver, "TimePickerField", Direction.down);
const bindingLabel = await driver.findElementByText("binding", SearchOptions.exact);
expect(bindingLabel).to.exist;
let selector = driver.isAndroid ? "android.widget.EditText" : "XCUIElementTypeTextField"
let fields = await driver.findElementsByClassName(selector);
- let timeField;
let dateField;
if(driver.isAndroid){
- timeField = fields[2];
- dateField = fields[1];
+ dateField = fields[3];
}
else{
- let index = fields.length - 3;
+ let index = fields.length;
console.log("index: " + index);
- timeField = fields[index];
dateField = fields[index - 1];
}
await dateField.click();
@@ -243,13 +188,84 @@ describe("DateTimePicker", () => {
let bindingDate = await driver.findElementByText(dateLabel, SearchOptions.contains);
});
- it("Should scroll to css styled DatePicker and verify picker style", async () => {
- await scrollToElement(driver, "tap to select time", Direction.down);
- let cssPickers = await driver.findElementsByText("Feb 24, 2019", SearchOptions.exact);
- await cssPickers[cssPickers.length - 1].click();
- await getPickerDate(driver);
- await driver.compareScreen("cssDatePicker");
+ it("Should expand time picker field examples", async () => {
+ const timeFieldTitle = await driver.findElementByText("TimePickerField", SearchOptions.contains);
+ expect(timeFieldTitle).to.exist;
+ await timeFieldTitle.click();
+ });
+
+ it("Should select time and verify value of picker field", async () => {
+ const selectTimeField = await driver.findElementByText("select time", SearchOptions.contains);
+ await selectTimeField.click();
+ const timeString = await getPickerTime(driver, 12);
await clickOkBtn(driver);
+ const timeSelected = await driver.findElementByText(timeString, SearchOptions.contains);
+ expect(timeSelected).to.exist;
+ });
+
+ it("Should open 12h time format and verify wheelers values", async () => {
+ const twelveHourFormat = await driver.findElementByText("4:00 PM", SearchOptions.contains);
+ await twelveHourFormat.click();
+ const timeString = await getPickerTime(driver, 12);
+ await clickOkBtn(driver);
+ expect(timeString).to.equal("4:00 PM");
+ });
+
+ it("Should open 24h format and verify wheeler value", async () => {
+ const twentyFourFormat = await scrollToElement(driver, "16:00", Direction.down);
+ await twentyFourFormat.click();
+ const timeString = await getPickerTime(driver, 24);
+ await clickOkBtn(driver);
+ expect(timeString).to.equal("16:00");
+ });
+
+ it("Should verify modified texts field for time picker", async () => {
+ await scrollToElement(driver, "tap to choose", Direction.down);
+ const datePicker = await driver.findElementByText("tap to choose");
+ await datePicker.click();
+ const time = await getPickerTime(driver, 12);
+ const approveBtn = await driver.findElementByText("Approve", SearchOptions.contains);
+ const rejectBtn = await driver.findElementByText("Reject", SearchOptions.contains);
+ const title = await driver.findElementByText("Confirm predefined time selection", SearchOptions.contains);
+ expect(approveBtn).to.exist;
+ expect(rejectBtn).to.exist;
+ expect(title).to.exist;
+ await approveBtn.click();
+ const dateString = await driver.findElementByText(time);
+ expect(dateString).to.exist;
+ });
+
+ it("Should select time from de_DE locale picker and verify format", async () => {
+ await scrollToElement(driver, "zeit wählen", Direction.down);
+ const timePicker = await driver.findElementByText("zeit wählen", SearchOptions.contains);
+ await timePicker.click();
+ const time = await getPickerTime(driver, 24);
+ let acceptBtn;
+ let rejectBtn;
+ if(driver.isAndroid){
+ let buttons = await driver.findElementsByClassName("android.widget.Button");
+ acceptBtn = buttons[5];
+ rejectBtn = buttons[4];
+ }
+ else{
+ acceptBtn = await driver.findElementByText("Bestätigen", SearchOptions.exact);
+ rejectBtn = await driver.findElementByText("Stornieren", SearchOptions.exact);
+ }
+ const title = await driver.findElementByText("Zeit wählen", SearchOptions.exact);
+ expect(acceptBtn).to.exist;
+ expect(rejectBtn).to.exist;
+ expect(title).to.exist;
+ await acceptBtn.click();
+ const dateField = await driver.findElementByText(time);
+ expect(time).to.exist;
+ });
+
+ it("Should scroll to custom format and verify values", async () => {
+ await scrollToElement(driver, "binding", Direction.down);
+ const customFromatLabel = await driver.findElementByText("custom format");
+ expect(customFromatLabel).to.exist;
+ const customFormatTime = await driver.findElementByText("time: 01:00", SearchOptions.exact);
+ expect(customFormatTime).to.exist;
});
it("Should scroll to css styled TimePicker and verify picker style", async () => {
@@ -260,7 +276,15 @@ describe("DateTimePicker", () => {
await clickOkBtn(driver);
});
+ it("Should expand custom buttons examples", async () => {
+ await scrollToElement(driver, "Custom Buttons", Direction.down);
+ const customButtonsTitle = await driver.findElementByText("Custom Buttons", SearchOptions.contains);
+ expect(customButtonsTitle).to.exist;
+ await customButtonsTitle.click();
+ });
+
it("Should tap button to select date and verify button text", async () => {
+ await scrollToElement(driver, "tap to select date and time", Direction.down);
let dateButton = await driver.findElementByText("tap to select date", SearchOptions.contains);
await dateButton.click();
const date = await getPickerDate(driver);
diff --git a/demo-angular/src/app/home/home.component.css b/demo-angular/src/app/home/home.component.css
index 2483bd2..c33ffc6 100644
--- a/demo-angular/src/app/home/home.component.css
+++ b/demo-angular/src/app/home/home.component.css
@@ -6,6 +6,15 @@
color: #303F9F;
}
+.header {
+ font-size: 16;
+ margin-top: 12;
+ margin-bottom: 6;
+ color: white;
+ background-color: #2196F3;
+ text-align: center;
+}
+
label {
padding: 6 4;
}
diff --git a/demo-angular/src/app/home/home.component.html b/demo-angular/src/app/home/home.component.html
index a2f8da3..5bd5be4 100644
--- a/demo-angular/src/app/home/home.component.html
+++ b/demo-angular/src/app/home/home.component.html
@@ -2,69 +2,167 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo-angular/src/app/home/home.component.ts b/demo-angular/src/app/home/home.component.ts
index 60b464f..55f8206 100644
--- a/demo-angular/src/app/home/home.component.ts
+++ b/demo-angular/src/app/home/home.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from "@angular/core";
+import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
import { DateTimePicker } from "nativescript-datetimepicker";
import { EventData } from "tns-core-modules/data/observable";
import { Button } from "tns-core-modules/ui/button";
@@ -10,19 +10,31 @@ import { Button } from "tns-core-modules/ui/button";
styleUrls: ['home.component.css']
})
export class HomeComponent implements OnInit {
- private _dateText: string;
- private _timeText: string;
- private _dateTime: Date;
+ public dateText: string = "tap to select date";
+ public timeText: string = "tap to select time";
+ public dateTimeText: string = "tap to select date and time";
+ public dateTime1: Date = new Date();
+ public dateTime2: Date = new Date();
+ public dateTime3: Date = new Date();
+ public dateOpacity: number;
+ public timeOpacity: number;
+ public dateTimeOpacity: number;
+ public customOpacity: number;
+ public dateVisibility: string;
+ public timeVisibility: string;
+ public dateTimeVisibility: string;
+ public customVisibility: string;
+ private _expandedId: string;
+
+ @ViewChild("scrollView") scrollView: ElementRef;
constructor() {
// Use the component constructor to inject providers.
+ this.expandCollapse(null);
}
ngOnInit(): void {
// Init your component properties here.
- this._dateText = "tap to select date";
- this._timeText = "tap to select time";
- this._dateTime = new Date();
}
onPickDateTap(args: EventData): void {
@@ -37,14 +49,10 @@ export class HomeComponent implements OnInit {
okButtonText: "OK",
cancelButtonText: "Cancel",
title: "choose date",
- locale: "en_UK"
- }).then((selected: Date) => {
- if (selected) {
- const d = selected.getDate();
- const m = selected.getMonth() + 1;
- const y = selected.getFullYear();
- const dateText = (d < 10 ? '0' : '') + d + '.' + (m < 10 ? '0' : '') + m + '.' + y;
- this._dateText = dateText;
+ locale: "en_GB"
+ }).then((selectedDate: Date) => {
+ if (selectedDate) {
+ this.dateText = this.getFormattedDate(selectedDate);
}
});
}
@@ -60,31 +68,75 @@ export class HomeComponent implements OnInit {
okButtonText: "OK",
cancelButtonText: "Cancel",
title: "choose time",
- locale: "en_UK",
+ locale: "en_GB",
is24Hours: true
- }).then((selected: Date) => {
- if (selected) {
- const h = selected.getHours();
- const m = selected.getMinutes();
- const timeText = (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m;
- this._timeText = timeText;
+ }).then((selectedTime: Date) => {
+ if (selectedTime) {
+ this.timeText = this.getFormattedTime(selectedTime);
}
});
}
- get dateText() {
- return this._dateText;
+ onPickDateTimeTap(args: EventData): void {
+ const dateToday = new Date();
+ DateTimePicker.pickDate({
+ context: (
@@ -87,12 +184,30 @@
return {
dateText: "tap to select date",
timeText: "tap to select time",
- dateTime: new Date()
+ dateTimeText: "tap to select date and time",
+ dateTime1: new Date(),
+ dateTime2: new Date(),
+ dateTime3: new Date(),
+ dateOpacity: 1,
+ timeOpacity: 1,
+ dateTimeOpacity: 1,
+ customOpacity: 1,
+ dateVisibility: 'collapse',
+ timeVisibility: 'collapse',
+ dateTimeVisibility: 'collapse',
+ customVisibility: 'collapse',
+ _expandedId: null
}
},
methods: {
- onDateTimeChange: function(args) {
- this.dateTime = args.value;
+ onDateTimeChange1: function(args) {
+ this.dateTime1 = args.value;
+ },
+ onDateTimeChange2: function(args) {
+ this.dateTime2 = args.value;
+ },
+ onDateTimeChange3: function(args) {
+ this.dateTime3 = args.value;
},
onPickDateTap: function(args) {
const dateToday = new Date();
@@ -107,15 +222,11 @@
okButtonText: "OK",
cancelButtonText: "Cancel",
title: "choose date",
- locale: "en_UK"
+ locale: "en_GB"
})
- .then(selected => {
- if (selected) {
- const d = selected.getDate();
- const m = selected.getMonth() + 1;
- const y = selected.getFullYear();
- const dateText = (d < 10 ? '0' : '') + d + '.' + (m < 10 ? '0' : '') + m + '.' + y;
- this.dateText = dateText;
+ .then(selectedDate => {
+ if (selectedDate) {
+ this.dateText = this.getFormattedDate(selectedDate);
}
});
},
@@ -131,17 +242,76 @@
okButtonText: "OK",
cancelButtonText: "Cancel",
title: "choose time",
- locale: "en_UK",
+ locale: "en_GB",
is24Hours: true
})
- .then(selected => {
- if (selected) {
- const h = selected.getHours();
- const m = selected.getMinutes();
- const timeText = (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m;
- this.timeText = timeText;
+ .then(selectedTime => {
+ if (selectedTime) {
+ this.timeText = this.getFormattedTime(selectedTime);
+ }
+ });
+ },
+ onPickDateTimeTap: function(args) {
+ const dateToday = new Date();
+ DateTimePicker
+ .pickDate({
+ context: args.object._context,
+ date: dateToday,
+ title: "choose date",
+ locale: "en_GB"
+ })
+ .then(selectedDate => {
+ if (selectedDate) {
+ DateTimePicker
+ .pickTime({
+ context: args.object._context,
+ time: selectedDate,
+ title: "choose time",
+ locale: "en_GB"
+ })
+ .then(selectedDateTime => {
+ if (selectedDateTime) {
+ this.dateTimeText = this.getFormattedDate(selectedDateTime) + ' ' + this.getFormattedTime(selectedDateTime);
+ }
+ });
}
});
+ },
+ onHeaderTap: function(args) {
+ const buttonId = args.object.id;
+ const isCurrentlyExpanded = buttonId === this._expandedId;
+ if (isCurrentlyExpanded) {
+ this.expandCollapse(null);
+ } else {
+ this.expandCollapse(buttonId);
+ }
+ this.$refs.scrollView.nativeView.scrollToVerticalOffset(0, false);
+ },
+ expandCollapse: function(expandId) {
+ this.dateOpacity = expandId === 'date' ? 0.7 : 1;
+ this.dateVisibility = expandId === 'date' ? 'visible' : 'collapse';
+
+ this.timeOpacity = expandId === 'time' ? 0.7 : 1;
+ this.timeVisibility = expandId === 'time' ? 'visible' : 'collapse';
+
+ this.dateTimeOpacity = expandId === 'dateTime' ? 0.7 : 1;
+ this.dateTimeVisibility = expandId === 'dateTime' ? 'visible' : 'collapse';
+
+ this.customOpacity = expandId === 'custom' ? 0.7 : 1;
+ this.customVisibility = expandId === 'custom' ? 'visible' : 'collapse';
+
+ this._expandedId = expandId;
+ },
+ getFormattedDate: function(date) {
+ const d = date.getDate();
+ const m = date.getMonth() + 1;
+ const y = date.getFullYear();
+ return (d < 10 ? '0' : '') + d + '.' + (m < 10 ? '0' : '') + m + '.' + y;
+ },
+ getFormattedTime: function(date) {
+ const h = date.getHours();
+ const m = date.getMinutes();
+ return (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m;
}
}
};
@@ -161,6 +331,15 @@
color: #303F9F;
}
+ .header {
+ font-size: 16;
+ margin-top: 12;
+ margin-bottom: 6;
+ color: white;
+ background-color: #2196F3;
+ text-align: center;
+ }
+
label {
padding: 6 4;
}
diff --git a/demo/app/home/home-page.css b/demo/app/home/home-page.css
index 1df44eb..aee7c01 100644
--- a/demo/app/home/home-page.css
+++ b/demo/app/home/home-page.css
@@ -6,6 +6,15 @@
color: #303F9F;
}
+.header {
+ font-size: 16;
+ margin-top: 12;
+ margin-bottom: 6;
+ color: white;
+ background-color: #2196F3;
+ text-align: center;
+}
+
label {
padding: 6 4;
}
diff --git a/demo/app/home/home-page.xml b/demo/app/home/home-page.xml
index 9ec3c43..31ef9d9 100644
--- a/demo/app/home/home-page.xml
+++ b/demo/app/home/home-page.xml
@@ -7,70 +7,167 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/app/home/home-view-model.ts b/demo/app/home/home-view-model.ts
index e30cb86..a1ee075 100644
--- a/demo/app/home/home-view-model.ts
+++ b/demo/app/home/home-view-model.ts
@@ -2,14 +2,20 @@ import { Observable } from "tns-core-modules/data/observable";
import { DateTimePicker } from "nativescript-datetimepicker";
import { EventData } from "tns-core-modules/data/observable";
import { Button } from "tns-core-modules/ui/button";
+import { ScrollView } from "tns-core-modules/ui/scroll-view";
export class HomeViewModel extends Observable {
+ private scrollView: ScrollView;
constructor() {
super();
this.set('dateText', "tap to select date");
this.set('timeText', "tap to select time");
- this.set('dateTime', new Date());
+ this.set('dateTimeText', "tap to select date and time");
+ this.set('dateTime1', new Date());
+ this.set('dateTime2', new Date());
+ this.set('dateTime3', new Date());
+ this.expandCollapse(null);
}
onPickDateTap(args: EventData): void {
@@ -24,14 +30,10 @@ export class HomeViewModel extends Observable {
okButtonText: "OK",
cancelButtonText: "Cancel",
title: "choose date",
- locale: "en_UK"
- }).then((selected: Date) => {
- if (selected) {
- const d = selected.getDate();
- const m = selected.getMonth() + 1;
- const y = selected.getFullYear();
- const dateText = (d < 10 ? '0' : '') + d + '.' + (m < 10 ? '0' : '') + m + '.' + y;
- this.set('dateText', dateText);
+ locale: "en_GB"
+ }).then((selectedDate: Date) => {
+ if (selectedDate) {
+ this.set('dateText', this.getFormattedDate(selectedDate));
}
});
}
@@ -47,15 +49,77 @@ export class HomeViewModel extends Observable {
okButtonText: "OK",
cancelButtonText: "Cancel",
title: "choose time",
- locale: "en_UK",
+ locale: "en_GB",
is24Hours: true
- }).then((selected: Date) => {
- if (selected) {
- const h = selected.getHours();
- const m = selected.getMinutes();
- const timeText = (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m;
- this.set('timeText', timeText);
+ }).then((selectedTime: Date) => {
+ if (selectedTime) {
+ this.set('timeText', this.getFormattedTime(selectedTime));
}
});
}
+
+ onPickDateTimeTap(args: EventData): void {
+ const dateToday = new Date();
+ DateTimePicker.pickDate({
+ context: (args.object)._context,
+ date: dateToday,
+ title: "choose date",
+ locale: "en_GB",
+ }).then((selectedDate: Date) => {
+ if (selectedDate) {
+ DateTimePicker.pickTime({
+ context: (args.object)._context,
+ time: selectedDate,
+ title: "choose time",
+ locale: "en_GB",
+ }).then((selectedDateTime: Date) => {
+ if (selectedDateTime) {
+ this.set('dateTimeText', this.getFormattedDate(selectedDateTime) + ' ' + this.getFormattedTime(selectedDateTime));
+ }
+ });
+ }
+ });
+ }
+
+ scrollViewLoaded(args: EventData): void {
+ this.scrollView = args.object;
+ }
+
+ onHeaderTap(args: EventData): void {
+ const buttonId = (args.object).id;
+ const isCurrentlyExpanded = this.get(buttonId + "Visibility") === 'visible';
+ if (isCurrentlyExpanded) {
+ this.expandCollapse(null);
+ } else {
+ this.expandCollapse(buttonId);
+ }
+ this.scrollView.scrollToVerticalOffset(0, false);
+ }
+
+ expandCollapse(expandId: string): void {
+ this.set('dateOpacity', expandId === 'date' ? 0.7 : 1);
+ this.set('dateVisibility', expandId === 'date' ? 'visible' : 'collapse');
+
+ this.set('timeOpacity', expandId === 'time' ? 0.7 : 1);
+ this.set('timeVisibility', expandId === 'time' ? 'visible' : 'collapse');
+
+ this.set('dateTimeOpacity', expandId === 'dateTime' ? 0.7 : 1);
+ this.set('dateTimeVisibility', expandId === 'dateTime' ? 'visible' : 'collapse');
+
+ this.set('customOpacity', expandId === 'custom' ? 0.7 : 1);
+ this.set('customVisibility', expandId === 'custom' ? 'visible' : 'collapse');
+ }
+
+ getFormattedDate(date: Date): string {
+ const d = date.getDate();
+ const m = date.getMonth() + 1;
+ const y = date.getFullYear();
+ return (d < 10 ? '0' : '') + d + '.' + (m < 10 ? '0' : '') + m + '.' + y;
+ }
+
+ getFormattedTime(date: Date): string {
+ const h = date.getHours();
+ const m = date.getMinutes();
+ return (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m;
+ }
}
diff --git a/src/angular/nativescript-datetimepicker.accessors.ts b/src/angular/nativescript-datetimepicker.accessors.ts
index 20a8d03..66566c2 100644
--- a/src/angular/nativescript-datetimepicker.accessors.ts
+++ b/src/angular/nativescript-datetimepicker.accessors.ts
@@ -3,6 +3,7 @@ import { NG_VALUE_ACCESSOR } from "@angular/forms";
import { BaseValueAccessor } from "nativescript-angular/forms/value-accessors";
import { DatePickerField } from "../ui/date-picker-field";
import { TimePickerField } from "../ui/time-picker-field";
+import { DateTimePickerFields } from "../ui/date-time-picker-fields";
const DATE_PICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
@@ -16,6 +17,12 @@ const TIME_PICKER_VALUE_ACCESSOR = {
multi: true,
};
+const DATE_TIME_PICKERS_VALUE_ACCESSOR = {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => DateTimePickersValueAccessor),
+ multi: true,
+};
+
/**
* The accessor for setting a date and listening to changes that is used by the
* {@link NgModel} directives.
@@ -74,4 +81,34 @@ export class TimePickerValueAccessor extends BaseValueAccessor
const normalized = super.normalizeValue(value);
this.view.time = normalized;
}
+}
+
+/**
+ * The accessor for setting a date and listening to changes that is used by the
+ * {@link NgModel} directives.
+ *
+ * ### Example
+ * ```
+ *
+ * ```
+ */
+@Directive({
+ selector: "DateTimePickerFields[ngModel],DateTimePickerFields[formControlName],DateTimePickerFields[formControl]," +
+ "datetimepickerfields[ngModel],datetimepickerfields[formControlName],datetimepickerfields[formControl]," +
+ "dateTimePickerFields[ngModel],dateTimePickerFields[formControlName],dateTimePickerFields[formControl]," +
+ "date-time-picker-fields[ngModel],date-time-picker-fields[formControlName],date-time-picker-fields[formControl]",
+ providers: [DATE_TIME_PICKERS_VALUE_ACCESSOR],
+ host: {
+ "(dateChange)": "onChange($event.value)",
+ },
+})
+export class DateTimePickersValueAccessor extends BaseValueAccessor {
+ constructor(elementRef: ElementRef) {
+ super(elementRef.nativeElement);
+ }
+
+ writeValue(value: any): void {
+ const normalized = super.normalizeValue(value);
+ this.view.date = normalized;
+ }
}
\ No newline at end of file
diff --git a/src/angular/nativescript-datetimepicker.directives.ts b/src/angular/nativescript-datetimepicker.directives.ts
index a57883b..5c8bb4f 100644
--- a/src/angular/nativescript-datetimepicker.directives.ts
+++ b/src/angular/nativescript-datetimepicker.directives.ts
@@ -1,5 +1,7 @@
import { Directive } from "@angular/core";
-import { DatePickerValueAccessor, TimePickerValueAccessor } from "./nativescript-datetimepicker.accessors";
+import {
+ DatePickerValueAccessor, TimePickerValueAccessor, DateTimePickersValueAccessor
+} from "./nativescript-datetimepicker.accessors";
@Directive({
selector: "DatePickerField"
@@ -11,5 +13,10 @@ export class DatePickerFieldDirective { }
})
export class TimePickerFieldDirective { }
-export const DIRECTIVES = [DatePickerFieldDirective, TimePickerFieldDirective,
- DatePickerValueAccessor, TimePickerValueAccessor];
\ No newline at end of file
+@Directive({
+ selector: "DateTimePickerFields"
+})
+export class DateTimePickerFieldsDirective { }
+
+export const DIRECTIVES = [DatePickerFieldDirective, TimePickerFieldDirective, DateTimePickerFieldsDirective,
+ DatePickerValueAccessor, TimePickerValueAccessor, DateTimePickersValueAccessor];
\ No newline at end of file
diff --git a/src/angular/nativescript-datetimepicker.module.ts b/src/angular/nativescript-datetimepicker.module.ts
index 2a9785b..3dfad8c 100644
--- a/src/angular/nativescript-datetimepicker.module.ts
+++ b/src/angular/nativescript-datetimepicker.module.ts
@@ -2,6 +2,7 @@ import { NgModule } from "@angular/core";
import { registerElement } from "nativescript-angular/element-registry";
import { DatePickerField } from "../ui/date-picker-field";
import { TimePickerField } from "../ui/time-picker-field";
+import { DateTimePickerFields } from "../ui/date-time-picker-fields";
import { DIRECTIVES } from "./nativescript-datetimepicker.directives";
@@ -12,4 +13,5 @@ import { DIRECTIVES } from "./nativescript-datetimepicker.directives";
export class NativeScriptDateTimePickerModule { }
registerElement("DatePickerField", () => DatePickerField);
-registerElement("TimePickerField", () => TimePickerField);
\ No newline at end of file
+registerElement("TimePickerField", () => TimePickerField);
+registerElement("DateTimePickerFields", () => DateTimePickerFields);
\ No newline at end of file
diff --git a/src/datetimepicker.android.ts b/src/datetimepicker.android.ts
index 54616a3..fe5ad6b 100644
--- a/src/datetimepicker.android.ts
+++ b/src/datetimepicker.android.ts
@@ -1,7 +1,8 @@
import { Color } from "tns-core-modules/color";
import { LocalizationUtils } from "./utils/localization-utils";
+import { getDateNow, getDateToday } from "./utils/date-utils";
import {
- DateTimePickerBase, DateTimePickerStyleBase, getDateNow, getDateToday,
+ DateTimePickerBase, DateTimePickerStyleBase,
DatePickerOptions, TimePickerOptions, PickerOptions
} from "./datetimepicker.common";
@@ -16,7 +17,7 @@ interface DialogDismissListener {
let DialogClickListener: DialogClickListener;
let DialogDismissListener: DialogDismissListener;
let AppCompatNamespace: any;
-declare let androidx: any;
+export declare let androidx: any;
function initializeAppCompatNamespace(): void {
if (AppCompatNamespace) {
diff --git a/src/datetimepicker.common.ts b/src/datetimepicker.common.ts
index edc4cd5..058dd35 100644
--- a/src/datetimepicker.common.ts
+++ b/src/datetimepicker.common.ts
@@ -75,20 +75,6 @@ export class DateTimePickerStyleBase implements DateTimePickerStyleDefinition {
}
}
-export function getDateNow(): Date {
- const date = new Date();
- date.setSeconds(0);
- date.setMilliseconds(0);
- return date;
-}
-
-export function getDateToday(): Date {
- const date = getDateNow();
- date.setMinutes(0);
- date.setHours(0);
- return date;
-}
-
export function getCurrentPage(): Page {
let topmostFrame = frameModule.topmost();
if (topmostFrame) {
diff --git a/src/datetimepicker.ios.ts b/src/datetimepicker.ios.ts
index f1a1446..c1ef977 100644
--- a/src/datetimepicker.ios.ts
+++ b/src/datetimepicker.ios.ts
@@ -1,10 +1,11 @@
import { Color } from "tns-core-modules/color";
import { View, ios as iosView } from "tns-core-modules/ui/core/view";
import {
- DateTimePickerBase, DateTimePickerStyleBase, getDateNow, getDateToday, getCurrentPage,
+ DateTimePickerBase, DateTimePickerStyleBase, getCurrentPage,
DatePickerOptions, TimePickerOptions, PickerOptions
} from "./datetimepicker.common";
import { LocalizationUtils } from "./utils/localization-utils";
+import { getDateNow, getDateToday } from "./utils/date-utils";
export class DateTimePickerStyle extends DateTimePickerStyleBase {
}
diff --git a/src/index.d.ts b/src/index.d.ts
index e986427..38410b0 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -1,3 +1,4 @@
export * from "./datetimepicker";
export * from "./ui/date-picker-field";
export * from "./ui/time-picker-field";
+export * from "./ui/date-time-picker-fields";
diff --git a/src/index.ts b/src/index.ts
index 7b57192..4eb037f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,4 @@
export * from "./datetimepicker";
export * from "./ui/date-picker-field";
-export * from "./ui/time-picker-field";
\ No newline at end of file
+export * from "./ui/time-picker-field";
+export * from "./ui/date-time-picker-fields";
\ No newline at end of file
diff --git a/src/ui/date-picker-field.common.ts b/src/ui/date-picker-field.common.ts
index 094cedd..1d84a6b 100644
--- a/src/ui/date-picker-field.common.ts
+++ b/src/ui/date-picker-field.common.ts
@@ -2,6 +2,7 @@ import { Property, CSSType } from "tns-core-modules/ui/core/view";
import { DateTimePicker, DateTimePickerStyle } from "../datetimepicker";
import { DatePickerField as DatePickerFieldDefinition } from "./date-picker-field";
import { LocalizationUtils } from "../utils/localization-utils";
+import { getDateToday } from "../utils/date-utils";
import { PickerFieldBase } from "./picker-field-base";
@CSSType("DatePickerField")
@@ -41,6 +42,7 @@ export class DatePickerFieldBase extends PickerFieldBase implements DatePickerFi
public static pickerDefaultDateProperty = new Property({
name: "pickerDefaultDate",
+ defaultValue: getDateToday(),
equalityComparer: dateComparer,
valueConverter: dateValueConverter,
});
diff --git a/src/ui/date-time-picker-fields.d.ts b/src/ui/date-time-picker-fields.d.ts
new file mode 100644
index 0000000..db32b9a
--- /dev/null
+++ b/src/ui/date-time-picker-fields.d.ts
@@ -0,0 +1,194 @@
+/**
+ * Contains the DatePickerField class.
+ */
+import { Property, View } from "tns-core-modules/ui/core/view";
+import { GridLayout } from "tns-core-modules/ui/layouts/grid-layout";
+import { Orientation } from "tns-core-modules/ui/layouts/stack-layout";
+
+/**
+ * Represents a TextField that can be tapped to open a picker. The picker is a dialog with
+ * date picking spinners along with OK/Cancel buttons.
+ */
+export class DateTimePickerFields extends GridLayout {
+ /**
+ * Gets or sets the selected date.
+ */
+ date: Date;
+
+ /**
+ * Gets or sets the max date. Note that this property only affects the date component.
+ */
+ maxDate: Date;
+
+ /**
+ * Gets or sets the min date. Note that this property only affects the date component.
+ */
+ minDate: Date;
+
+ /**
+ * Gets or sets a format for displaying the date in the field.
+ * Default value is undefined, meaning that the format will be based on the current locale.
+ * Here are some examples with the way 1st of April, 2019 is displayed for each of the formats:
+ * MMM dd, yyyy - Apr 01, 2019
+ * d.M.yy - 1.4.19
+ * EEE, d MMMM yyyy - Mon, 1 April 2019
+ */
+ dateFormat: string;
+
+ /**
+ * Gets or sets a format for displaying the date in the field.
+ * Default value is undefined, meaning that the format will be based on the current locale.
+ * Here are some examples with the way 1st of April, 2019 is displayed for each of the formats:
+ * MMM dd, yyyy - Apr 01, 2019
+ * d.M.yy - 1.4.19
+ * EEE, d MMMM yyyy - Mon, 1 April 2019
+ */
+ timeFormat: string;
+
+ /**
+ * Gets or sets a locale for displaying the date in the field, and also for the picker.
+ * Default value is undefined, meaning that the format will be based on the device's settings.
+ * In order to fixate the date to English, you can use English-based locales like: en_US, en_UK, etc.
+ * If you want to provide localization for your app, you can supply different locales, depending
+ * on the selected setting.
+ * Note that changing the locale will not affect the {@link pickerOkText}, {@link pickerCancelText}
+ * and {@link pickerTitle} or {@link hint} properties.
+ */
+ locale: string;
+
+ /**
+ * Gets or sets the hint text for the date component. Hint is the text that is displayed in a field when {@link date} is null.
+ */
+ hintDate: string;
+
+ /**
+ * Gets or sets the hint text for the time component. Hint is the text that is displayed in a field when {@link date} is null.
+ */
+ hintTime: string;
+
+ /**
+ * Gets or sets the date that will be initially selected in the picker when {@link date} is null.
+ *
+ * @default now
+ */
+ pickerDefaultDate: Date;
+
+ /**
+ * Gets or sets the title for picker selecting date. The title is the text that is displayed in the picker
+ * above the date selecting spinners.
+ */
+ pickerTitleDate: string;
+
+ /**
+ * Gets or sets the title for picker selecting time. The title is the text that is displayed in the picker
+ * above the time selecting spinners.
+ */
+ pickerTitleTime: string;
+
+ /**
+ * Gets or sets the text of the button in the picker that is used to confirm the selection.
+ * By default, on iOS the text will be OK, while on android the text will be
+ * determined by the current device's localization settings. Please note, that the value
+ * is not related with the value {@link locale} property.
+ */
+ pickerOkText: string;
+
+ /**
+ * Gets or sets the text of the button in the picker that is used to dismiss the picker,
+ * and cancel the current date selection.
+ * By default, on iOS the text will be Cancel, while on android the text will be
+ * determined by the current device's localization settings. Please note, that the value
+ * is not related with the value {@link locale} property.
+ */
+ pickerCancelText: string;
+
+ /**
+ * Gets or sets a value that indicates whether the time should be assigned a value as soon as date is picked.
+ *
+ * @default false
+ */
+ autoPickTime: boolean;
+
+ /**
+ * Gets or sets a value that indicates whether the date and time components should be on the same row or not.
+ * Default value is horizontal, meaning that the two fields will be on the same row.
+ *
+ * @default horizontal
+ */
+ orientation: Orientation;
+
+ /**
+ * Identifies the {@link date} dependency property.
+ */
+ static dateProperty: Property;
+
+ /**
+ * Identifies the {@link maxDate} dependency property.
+ */
+ static maxDateProperty: Property;
+
+ /**
+ * Identifies the {@link minDate} dependency property.
+ */
+ static minDateProperty: Property;
+
+ /**
+ * Identifies the {@link dateFormat} dependency property.
+ */
+ static dateFormatProperty: Property;
+
+ /**
+ * Identifies the {@link timeFormat} dependency property.
+ */
+ static timeFormatProperty: Property;
+
+ /**
+ * Identifies the {@link locale} dependency property.
+ */
+ static localeProperty: Property;
+
+ /**
+ * Identifies the {@link hintDate} dependency property.
+ */
+ static hintDateProperty: Property;
+
+ /**
+ * Identifies the {@link hintTime} dependency property.
+ */
+ static hintTimeProperty: Property;
+
+ /**
+ * Identifies the {@link pickerDefaultDate} dependency property.
+ */
+ static pickerDefaultDateProperty: Property;
+
+ /**
+ * Identifies the {@link pickerTitleDate} dependency property.
+ */
+ static pickerTitleDateProperty: Property;
+
+ /**
+ * Identifies the {@link pickerTitleTime} dependency property.
+ */
+ static pickerTitleTimeProperty: Property;
+
+ /**
+ * Identifies the {@link pickerOkText} dependency property.
+ */
+ static pickerOkTextProperty: Property;
+
+ /**
+ * Identifies the {@link pickerCancelText} dependency property.
+ */
+ static pickerCancelTextProperty: Property;
+
+ /**
+ * Identifies the {@link autoPickTime} dependency property.
+ */
+ static autoPickTimeProperty: Property;
+
+ /**
+ * Identifies the {@link orientation} dependency property.
+ */
+ static orientationProperty: Property;
+}
\ No newline at end of file
diff --git a/src/ui/date-time-picker-fields.ts b/src/ui/date-time-picker-fields.ts
new file mode 100644
index 0000000..99f232b
--- /dev/null
+++ b/src/ui/date-time-picker-fields.ts
@@ -0,0 +1,324 @@
+import { Property, CSSType } from "tns-core-modules/ui/core/view";
+import { PropertyChangeData } from "tns-core-modules/data/observable";
+import { DateTimePickerFields as DateTimePickerFieldsDefinition } from "./date-time-picker-fields";
+import { GridLayout, ItemSpec } from "tns-core-modules/ui/layouts/grid-layout";
+import { Orientation } from "tns-core-modules/ui/layouts/stack-layout";
+import { DatePickerField } from "./date-picker-field";
+import { TimePickerField } from "./time-picker-field";
+import { getDateNow, clearTime } from "../utils/date-utils";
+
+@CSSType("DateTimePickerFields")
+export class DateTimePickerFields extends GridLayout implements DateTimePickerFieldsDefinition {
+ public dateField: DatePickerField;
+ public timeField: TimePickerField;
+
+ public date: Date;
+
+ public maxDate: Date;
+ public minDate: Date;
+
+ public dateFormat: string;
+ public timeFormat: string;
+ public locale: string;
+ public hintDate: string;
+ public hintTime: string;
+
+ public pickerDefaultDate: Date;
+ public pickerTitleDate: string;
+ public pickerTitleTime: string;
+ public pickerOkText: string;
+ public pickerCancelText: string;
+
+ public orientation: Orientation;
+ public autoPickTime: boolean;
+
+ _shouldSkipTimeAssignment: boolean;
+
+ private _dateChangeHandler: (args: PropertyChangeData) => void;
+ private _timeChangeHandler: (args: PropertyChangeData) => void;
+
+ constructor() {
+ super();
+ this.dateField = new DatePickerField();
+ this.timeField = new TimePickerField();
+
+ let row1Spec = new ItemSpec(1, "star");
+ let row2Spec = new ItemSpec(1, "star");
+ let column1Spec = new ItemSpec(1, "star");
+ let column2Spec = new ItemSpec(1, "star");
+
+ this.addRow(row1Spec);
+ this.addRow(row2Spec);
+ this.addColumn(column1Spec);
+ this.addColumn(column2Spec);
+
+ this.addChild(this.dateField);
+ this.addChild(this.timeField);
+
+ DateTimePickerFields._updateOrientation(this);
+ }
+
+ public static dateProperty = new Property({
+ name: "date",
+ equalityComparer: dateComparer,
+ valueConverter: dateValueConverter,
+ valueChanged: DateTimePickerFields.datePropertyChanged
+ });
+
+ public static maxDateProperty = new Property({
+ name: "maxDate",
+ equalityComparer: dateComparer,
+ valueConverter: dateValueConverter,
+ valueChanged: DateTimePickerFields.maxDatePropertyChanged
+ });
+
+ public static minDateProperty = new Property({
+ name: "minDate",
+ equalityComparer: dateComparer,
+ valueConverter: dateValueConverter,
+ valueChanged: DateTimePickerFields.minDatePropertyChanged
+ });
+
+ public static dateFormatProperty = new Property({
+ name: "dateFormat",
+ valueChanged: DateTimePickerFields.dateFormatPropertyChanged,
+ });
+
+ public static timeFormatProperty = new Property({
+ name: "timeFormat",
+ valueChanged: DateTimePickerFields.timeFormatPropertyChanged,
+ });
+
+ public static localeProperty = new Property({
+ name: "locale",
+ valueChanged: DateTimePickerFields.localePropertyChanged
+ });
+
+ public static hintDateProperty = new Property({
+ name: "hintDate",
+ valueChanged: DateTimePickerFields.hintDatePropertyChanged,
+ });
+
+ public static hintTimeProperty = new Property({
+ name: "hintTime",
+ valueChanged: DateTimePickerFields.hintTimePropertyChanged,
+ });
+
+ public static pickerDefaultDateProperty = new Property({
+ name: "pickerDefaultDate",
+ defaultValue: getDateNow(),
+ equalityComparer: dateComparer,
+ valueConverter: dateValueConverter,
+ valueChanged: DateTimePickerFields.pickerDefaultDatePropertyChanged
+ });
+
+ public static pickerTitleDateProperty = new Property({
+ name: "pickerTitleDate",
+ valueChanged: DateTimePickerFields.pickerTitleDatePropertyChanged
+ });
+
+ public static pickerTitleTimeProperty = new Property({
+ name: "pickerTitleTime",
+ valueChanged: DateTimePickerFields.pickerTitleTimePropertyChanged
+ });
+
+ public static pickerOkTextProperty = new Property({
+ name: "pickerOkText",
+ valueChanged: DateTimePickerFields.pickerOkTextPropertyChanged
+ });
+
+ public static pickerCancelTextProperty = new Property({
+ name: "pickerCancelText",
+ valueChanged: DateTimePickerFields.pickerCancelTextPropertyChanged
+ });
+
+ public static orientationProperty = new Property({
+ name: "orientation",
+ defaultValue: "horizontal",
+ valueChanged: DateTimePickerFields.orientationPropertyChanged
+ });
+
+ public static autoPickTimeProperty = new Property({
+ name: "autoPickTime",
+ defaultValue: false,
+ valueChanged: DateTimePickerFields.autoPickTimePropertyChanged
+ });
+
+ private static datePropertyChanged(field: DateTimePickerFields, oldValue: Date, newValue: Date) {
+ field.dateField.date = newValue;
+ if (!field._shouldSkipTimeAssignment) {
+ field.timeField.time = newValue;
+ }
+ field._shouldSkipTimeAssignment = false;
+ }
+
+ private static maxDatePropertyChanged(field: DateTimePickerFields, oldValue: Date, newValue: Date) {
+ field.dateField.maxDate = newValue;
+ }
+
+ private static minDatePropertyChanged(field: DateTimePickerFields, oldValue: Date, newValue: Date) {
+ field.dateField.minDate = newValue;
+ }
+
+ private static dateFormatPropertyChanged(field: DateTimePickerFields, oldValue: string, newValue: string) {
+ field.dateField.dateFormat = newValue;
+ }
+
+ private static timeFormatPropertyChanged(field: DateTimePickerFields, oldValue: string, newValue: string) {
+ field.timeField.timeFormat = newValue;
+ }
+
+ private static localePropertyChanged(field: DateTimePickerFields, oldValue: any, newValue: any) {
+ field.dateField.locale = newValue;
+ field.timeField.locale = newValue;
+ }
+
+ private static hintDatePropertyChanged(field: DateTimePickerFields, oldValue: string, newValue: string) {
+ field.dateField.hint = newValue;
+ }
+
+ private static hintTimePropertyChanged(field: DateTimePickerFields, oldValue: string, newValue: string) {
+ field.timeField.hint = newValue;
+ }
+
+ private static pickerDefaultDatePropertyChanged(field: DateTimePickerFields, oldValue: Date, newValue: Date) {
+ field.dateField.pickerDefaultDate = newValue;
+ field.timeField.pickerDefaultTime = newValue;
+ }
+
+ private static pickerTitleDatePropertyChanged(field: DateTimePickerFields, oldValue: string, newValue: string) {
+ field.dateField.pickerTitle = newValue;
+ }
+
+ private static pickerTitleTimePropertyChanged(field: DateTimePickerFields, oldValue: string, newValue: string) {
+ field.timeField.pickerTitle = newValue;
+ }
+
+ private static pickerOkTextPropertyChanged(field: DateTimePickerFields, oldValue: string, newValue: string) {
+ field.dateField.pickerOkText = newValue;
+ field.timeField.pickerOkText = newValue;
+ }
+
+ private static pickerCancelTextPropertyChanged(field: DateTimePickerFields, oldValue: string, newValue: string) {
+ field.dateField.pickerCancelText = newValue;
+ field.timeField.pickerCancelText = newValue;
+ }
+
+ private static orientationPropertyChanged(field: DateTimePickerFields, oldValue: Orientation, newValue: Orientation) {
+ DateTimePickerFields._updateOrientation(field);
+ }
+
+ private static autoPickTimePropertyChanged(field: DateTimePickerFields, oldValue: boolean, newValue: boolean) {
+ if (field.autoPickTime) {
+ field.dateField.pickerDefaultDate = field.pickerDefaultDate;
+ } else {
+ field.dateField.pickerDefaultDate = clearTime(field.pickerDefaultDate);
+ }
+ }
+
+ createNativeView() {
+ const nativeView = super.createNativeView();
+ const ngKey = Object.keys(this).find(key => key.startsWith('_ngcontent'));
+ const vueKey = Object.keys(this).find(key => key.startsWith('data-v'));
+ if (ngKey) {
+ this.dateField[ngKey] = this[ngKey];
+ this.timeField[ngKey] = this[ngKey];
+ }
+ if (vueKey) {
+ this.dateField[vueKey] = this[vueKey];
+ this.timeField[vueKey] = this[vueKey];
+ }
+ return nativeView;
+ }
+
+ initNativeView() {
+ super.initNativeView();
+ this._updateHandlers(true);
+ }
+
+ disposeNativeView() {
+ this._updateHandlers(false);
+ super.disposeNativeView();
+ }
+
+ private _updateHandlers(subscribe: boolean) {
+ if (subscribe) {
+ this._dateChangeHandler = this._dateChangeHandler || ((args: PropertyChangeData) => {
+ if (args.propertyName === "date") {
+ if (!this.autoPickTime && this.timeField.time === undefined) {
+ this._shouldSkipTimeAssignment = true;
+ }
+ this.date = args.value;
+ }
+ });
+ this.dateField.on("dateChange", this._dateChangeHandler);
+ this._timeChangeHandler = this._timeChangeHandler || ((args: PropertyChangeData) => {
+ if (args.propertyName === "time") {
+ this.date = args.value;
+ }
+ });
+ this.timeField.on("timeChange", this._timeChangeHandler);
+ if (this.className) {
+ this._handleClassNameChange();
+ }
+ this.on("classNameChange", this._handleClassNameChange, this);
+ } else {
+ this.dateField.off("dateChange", this._dateChangeHandler);
+ this.timeField.off("timeChange", this._timeChangeHandler);
+ this.off("classNameChange", this._handleClassNameChange);
+ }
+ }
+
+ private _handleClassNameChange() {
+ if (this.dateField && this.timeField) {
+ this.dateField.className = this.className;
+ this.timeField.className = this.className;
+ }
+ }
+
+ private static _updateOrientation(field: DateTimePickerFields) {
+ if (field.orientation === "horizontal") {
+ GridLayout.setRow(field.dateField, 0);
+ GridLayout.setRow(field.timeField, 0);
+ GridLayout.setColumn(field.dateField, 0);
+ GridLayout.setColumn(field.timeField, 1);
+ GridLayout.setRowSpan(field.dateField, 2);
+ GridLayout.setRowSpan(field.timeField, 2);
+ GridLayout.setColumnSpan(field.dateField, 1);
+ GridLayout.setColumnSpan(field.timeField, 1);
+ } else if (field.orientation === "vertical") {
+ GridLayout.setRow(field.dateField, 0);
+ GridLayout.setRow(field.timeField, 1);
+ GridLayout.setColumn(field.dateField, 0);
+ GridLayout.setColumn(field.timeField, 0);
+ GridLayout.setRowSpan(field.dateField, 1);
+ GridLayout.setRowSpan(field.timeField, 1);
+ GridLayout.setColumnSpan(field.dateField, 2);
+ GridLayout.setColumnSpan(field.timeField, 2);
+ }
+ }
+}
+
+export function dateComparer(x: Date, y: Date): boolean {
+ return x <= y && x >= y;
+}
+
+export function dateValueConverter(v: any): Date {
+ return new Date(v);
+}
+
+DateTimePickerFields.dateProperty.register(DateTimePickerFields);
+DateTimePickerFields.maxDateProperty.register(DateTimePickerFields);
+DateTimePickerFields.minDateProperty.register(DateTimePickerFields);
+DateTimePickerFields.dateFormatProperty.register(DateTimePickerFields);
+DateTimePickerFields.timeFormatProperty.register(DateTimePickerFields);
+DateTimePickerFields.localeProperty.register(DateTimePickerFields);
+DateTimePickerFields.hintDateProperty.register(DateTimePickerFields);
+DateTimePickerFields.hintTimeProperty.register(DateTimePickerFields);
+DateTimePickerFields.pickerDefaultDateProperty.register(DateTimePickerFields);
+DateTimePickerFields.pickerTitleDateProperty.register(DateTimePickerFields);
+DateTimePickerFields.pickerTitleTimeProperty.register(DateTimePickerFields);
+DateTimePickerFields.pickerOkTextProperty.register(DateTimePickerFields);
+DateTimePickerFields.pickerCancelTextProperty.register(DateTimePickerFields);
+DateTimePickerFields.orientationProperty.register(DateTimePickerFields);
+DateTimePickerFields.autoPickTimeProperty.register(DateTimePickerFields);
\ No newline at end of file
diff --git a/src/ui/time-picker-field.common.ts b/src/ui/time-picker-field.common.ts
index df1fb09..b7a5806 100644
--- a/src/ui/time-picker-field.common.ts
+++ b/src/ui/time-picker-field.common.ts
@@ -2,6 +2,7 @@ import { Property, CSSType } from "tns-core-modules/ui/core/view";
import { DateTimePicker, DateTimePickerStyle } from "../datetimepicker";
import { TimePickerField as TimePickerFieldDefinition } from "./time-picker-field";
import { LocalizationUtils } from "../utils/localization-utils";
+import { getDateNow } from "../utils/date-utils";
import { PickerFieldBase } from "./picker-field-base";
@CSSType("TimePickerField")
@@ -27,6 +28,7 @@ export class TimePickerFieldBase extends PickerFieldBase implements TimePickerFi
public static pickerDefaultTimeProperty = new Property({
name: "pickerDefaultTime",
+ defaultValue: getDateNow(),
equalityComparer: timeComparer,
valueConverter: timeValueConverter
});
diff --git a/src/utils/date-utils.ts b/src/utils/date-utils.ts
new file mode 100644
index 0000000..0bdbc4f
--- /dev/null
+++ b/src/utils/date-utils.ts
@@ -0,0 +1,24 @@
+export function getDateNow(): Date {
+ const date = new Date();
+ date.setSeconds(0);
+ date.setMilliseconds(0);
+ return date;
+}
+
+export function getDateToday(): Date {
+ const date = getDateNow();
+ date.setMinutes(0);
+ date.setHours(0);
+ return date;
+}
+
+export function clearTime(date: Date): Date {
+ if (!date) {
+ return date;
+ }
+ date.setHours(0);
+ date.setMinutes(0);
+ date.setSeconds(0);
+ date.setMilliseconds(0);
+ return date;
+}
\ No newline at end of file
diff --git a/src/vue/index.ts b/src/vue/index.ts
index 0cf844e..9a655f7 100644
--- a/src/vue/index.ts
+++ b/src/vue/index.ts
@@ -1,5 +1,6 @@
import { DatePickerField } from "../ui/date-picker-field";
import { TimePickerField } from "../ui/time-picker-field";
+import { DateTimePickerFields } from "../ui/date-time-picker-fields";
const DateTimePicker = {
install(Vue) {
@@ -24,6 +25,17 @@ const DateTimePicker = {
}
}
);
+
+ Vue.registerElement(
+ 'DateTimePickerFields',
+ () => DateTimePickerFields,
+ {
+ model: {
+ prop: 'date',
+ event: 'dateChange'
+ }
+ }
+ );
}
};
export default DateTimePicker;
\ No newline at end of file