Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Feat input timeformat #16584

Merged
merged 6 commits into from
Jun 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ var inputType = {
* The timezone to be used to read/write the `Date` instance in the model can be defined using
* {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
*
* The format of the displayed time can be adjusted with the
* {@link ng.directive:ngModelOptions#ngModelOptions-arguments ngModelOptions} `timeSecondsFormat`
* and `timeStripZeroSeconds`.
*
* @param {string} ngModel Assignable AngularJS expression to data-bind to.
* @param {string=} name Property name of the form under which the control is published.
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
Expand Down Expand Up @@ -356,7 +360,12 @@ var inputType = {
* Invalid `Date` objects (dates whose `getTime()` is `NaN`) will be rendered as an empty string.
*
* The timezone to be used to read/write the `Date` instance in the model can be defined using
* {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
* {@link ng.directive:ngModelOptions#ngModelOptions-arguments ngModelOptions}. By default,
* this is the timezone of the browser.
*
* The format of the displayed time can be adjusted with the
* {@link ng.directive:ngModelOptions#ngModelOptions-arguments ngModelOptions} `timeSecondsFormat`
* and `timeStripZeroSeconds`.
*
* @param {string} ngModel Assignable AngularJS expression to data-bind to.
* @param {string=} name Property name of the form under which the control is published.
Expand Down Expand Up @@ -1491,6 +1500,8 @@ function createDateInputType(type, regexp, parseDate, format) {
return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {
badInputChecker(scope, element, attr, ctrl, type);
baseInputType(scope, element, attr, ctrl, $sniffer, $browser);

var isTimeType = type === 'time' || type === 'datetimelocal';
var previousDate;
var previousTimezone;

Expand All @@ -1514,11 +1525,13 @@ function createDateInputType(type, regexp, parseDate, format) {
if (isValidDate(value)) {
previousDate = value;
var timezone = ctrl.$options.getOption('timezone');

if (timezone) {
previousTimezone = timezone;
previousDate = convertTimezoneToLocal(previousDate, timezone, true);
}
return $filter('date')(value, format, timezone);

return formatter(value, timezone);
} else {
previousDate = null;
previousTimezone = null;
Expand Down Expand Up @@ -1573,6 +1586,24 @@ function createDateInputType(type, regexp, parseDate, format) {
}
return parsedDate;
}

function formatter(value, timezone) {
var targetFormat = format;

if (isTimeType && isString(ctrl.$options.getOption('timeSecondsFormat'))) {
targetFormat = format
.replace('ss.sss', ctrl.$options.getOption('timeSecondsFormat'))
.replace(/:$/, '');
}

var formatted = $filter('date')(value, targetFormat, timezone);

if (isTimeType && ctrl.$options.getOption('timeStripZeroSeconds')) {
formatted = formatted.replace(/(?::00)?(?:\.000)?$/, '');
}

return formatted;
}
};
}

Expand Down
92 changes: 85 additions & 7 deletions src/ng/directive/ngModelOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,12 +406,6 @@ defaultModelOptions = new ModelOptions({
* </example>
*
*
* ## Specifying timezones
*
* You can specify the timezone that date/time input directives expect by providing its name in the
* `timezone` property.
*
*
* ## Programmatically changing options
*
* The `ngModelOptions` expression is only evaluated once when the directive is linked; it is not
Expand All @@ -423,8 +417,70 @@ defaultModelOptions = new ModelOptions({
* Default events, extra triggers, and catch-all debounce values}.
*
*
* ## Specifying timezones
*
* You can specify the timezone that date/time input directives expect by providing its name in the
* `timezone` property.
*
*
* ## Formatting the value of `time` and `datetime-local`
*
* With the options `timeSecondsFormat` and `timeStripZeroSeconds` it is possible to adjust the value
* that is displayed in the control. Note that browsers may apply their own formatting
* in the user interface.
*
<example name="ngModelOptions-time-format" module="timeExample">
<file name="index.html">
<time-example></time-example>
</file>
<file name="script.js">
angular.module('timeExample', [])
.component('timeExample', {
templateUrl: 'timeExample.html',
controller: function() {
this.time = new Date(1970, 0, 1, 14, 57, 0);

this.options = {
timeSecondsFormat: 'ss',
timeStripZeroSeconds: true
};

this.optionChange = function() {
this.timeForm.timeFormatted.$overrideModelOptions(this.options);
this.time = new Date(this.time);
};
}
});
</file>
<file name="timeExample.html">
<form name="$ctrl.timeForm">
<strong>Default</strong>:
<input type="time" ng-model="$ctrl.time" step="any" /><br>
<strong>With options</strong>:
<input type="time" name="timeFormatted" ng-model="$ctrl.time" step="any" ng-model-options="$ctrl.options" />
<br>

Options:<br>
<code>timeSecondsFormat</code>:
<input
type="text"
ng-model="$ctrl.options.timeSecondsFormat"
ng-change="$ctrl.optionChange()">
<br>
<code>timeStripZeroSeconds</code>:
<input
type="checkbox"
ng-model="$ctrl.options.timeStripZeroSeconds"
ng-change="$ctrl.optionChange()">
</form>
</file>
* </example>
*
* @param {Object} ngModelOptions options to apply to {@link ngModel} directives on this element and
* and its descendents. Valid keys are:
* and its descendents.
*
* **General options**:
*
* - `updateOn`: string specifying which event should the input be bound to. You can set several
* events using an space delimited list. There is a special event called `default` that
* matches the default events belonging to the control. These are the events that are bound to
Expand Down Expand Up @@ -457,6 +513,10 @@ defaultModelOptions = new ModelOptions({
* not validate correctly instead of the default behavior of setting the model to undefined.
* - `getterSetter`: boolean value which determines whether or not to treat functions bound to
* `ngModel` as getters/setters.
*
*
* **Input-type specific options**:
*
* - `timezone`: Defines the timezone to be used to read/write the `Date` instance in the model for
* `<input type="date" />`, `<input type="time" />`, ... . It understands UTC/GMT and the
* continental US time zone abbreviations, but for general use, use a time zone offset, for
Expand All @@ -465,6 +525,24 @@ defaultModelOptions = new ModelOptions({
* Note that changing the timezone will have no effect on the current date, and is only applied after
* the next input / model change.
*
* - `timeSecondsFormat`: Defines if the `time` and `datetime-local` types should show seconds and
* milliseconds. The option follows the format string of {@link date date filter}.
* By default, the options is `undefined` which is equal to `'ss.sss'` (seconds and milliseconds).
* The other options are `'ss'` (strips milliseconds), and `''` (empty string), which strips both
* seconds and milliseconds.
* Note that browsers that support `time` and `datetime-local` require the hour and minutes
* part of the time string, and may show the value differently in the user interface.
* {@link ngModelOptions#formatting-the-value-of-time-and-datetime-local- See the example}.
*
* - `timeStripZeroSeconds`: Defines if the `time` and `datetime-local` types should strip the
* seconds and milliseconds from the formatted value if they are zero. This option is applied
* after `timeSecondsFormat`.
* This option can be used to make the formatting consistent over different browsers, as some
* browsers with support for `time` will natively hide the milliseconds and
* seconds if they are zero, but others won't, and browsers that don't implement these input
* types will always show the full string.
* {@link ngModelOptions#formatting-the-value-of-time-and-datetime-local- See the example}.
*
*/
var ngModelOptionsDirective = function() {
NgModelOptionsController.$inject = ['$attrs', '$scope'];
Expand Down
Loading