Skip to content

Commit 7774f3d

Browse files
ddariboChronosSF
andauthored
feat(grid): expose editorOptions for the default editors and improve built-in editing for date/time cols (input formats) (#14465)
* feat(date-time-util): logic to identify numeric formats for editing * chore(date-time-util): formatting fixes * fix(esf-styles): small margin fix for time picker * feat(grid-interface): add editorOptions property on the ColumnType and FieldType * feat(grid-column): get/set editorOptions and dateTimeFormat * feat(grid-cells): use editorOptions.dateTimeFormat; add locale where missing * feat(grid-filters): use editorOptions.dateTimeFormat and locale on filter inputs * feat(docs): add defaultFormatType info to Changelog --------- Co-authored-by: Stamen Stoychev <[email protected]>
1 parent 2347c54 commit 7774f3d

32 files changed

+1340
-154
lines changed

CHANGELOG.md

+23
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,29 @@ All notable changes for each version of this project will be documented in this
1212
- `IgxCarousel`
1313
- Added support for vertical alignment. Can be configured via the `vertical` property. Defaults to `false`.
1414
- Added support for showing/hiding the indicator controls (dots). Can be configured via the `indicators` property. Defaults to `true`.
15+
- `ColumnType`, `IgxColumn`
16+
- The built-in editors for columns of type `date`, `dateTime` and `time` now use a default input format as per the `IgxGrid`'s `locale`. This is valid both for cell editors and the ones in the filtering UI for all modes - `quickFilter`, `excelStyle` and the Advanced filtering.
17+
- In case the `pipeArgs.displayFormat` property of a date-time column is set and contains only numeric date-time parts or such that can be handled by the editors, the built-in editors input format is inferred from it.
18+
- To configure the built-in editors, a new `editorOptions` property is added that allows to pass optional parameters. Accepts an `IColumnEditorOptions` object with the `dateTimeFormat` property, that is used as input format for the editors of
19+
`date`, `dateTime` and `time` column data types:
20+
```ts
21+
const editorOptions: IColumnEditorOptions = { Field?
22+
dateTimeFormat: 'MM/dd/YYYY',
23+
}
24+
```
25+
```html
26+
<igx-column field="sampleDate" dataType="date" [editorOptions]="editorOptions"></igx-column>
27+
```
28+
- `FieldType` (`IgxQueryBuilder`)
29+
- Similar to the above, the fields now accept an `editorOptions` object of type `IFieldEditorOptions`. Its `dateTimeFormat` property is used as input format for the query editors of date-time fields.
30+
- `IgxDateTimeEditor`, `IgxDatePicker`, `IgxTimePicker`, `IgxDateRangePicker`
31+
- In case the `inputFormat` property is not set, the input format is inferred from
32+
`displayFormat` if set and if it contains only numeric date-time parts.
33+
- `IgxTimePicker`
34+
- The input and display formats are now adjusted based on the locale. For instance, day period time part (AM/PM or a/p) would not be displayed for locales that do not require it.
35+
- `IgxDateTimeEditor`
36+
- Added a new `defaultFormatType` property (`date` | `time` | `dateTime`) which configures the date-time parts
37+
according to the target type that the editor mask includes. Defaults to `date`.
1538

1639
### Themes
1740
- `Palettes`

projects/igniteui-angular/src/lib/core/styles/components/grid/_excel-filtering-theme.scss

+2-1
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,8 @@
678678
margin: rem(16px) 0;
679679

680680
~ igx-input-group,
681-
~ igx-date-picker {
681+
~ igx-date-picker,
682+
~ igx-time-picker {
682683
margin-inline-start: rem(16px);
683684
}
684685
}

projects/igniteui-angular/src/lib/date-common/picker-base.directive.ts

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ export abstract class PickerBaseDirective implements IToggleView, EditorProvider
2929
*
3030
* @remarks
3131
* Also used as a placeholder when none is provided.
32-
* Default is `"'MM/dd/yyyy'"`
3332
*
3433
* @example
3534
* ```html

projects/igniteui-angular/src/lib/date-common/util/date-time.util.spec.ts

+78
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { DateTimeUtil } from './date-time.util';
22
import { DatePart, DatePartInfo } from '../../directives/date-time-editor/date-time-editor.common';
3+
import { DataType } from '../../data-operations/data-util';
34

45
const reduceToDictionary = (parts: DatePartInfo[]) => parts.reduce((obj, x) => {
56
obj[x.type] = x;
@@ -233,6 +234,28 @@ describe(`DateTimeUtil Unit tests`, () => {
233234
expect(result).toEqual('MM/dd/yyyy');
234235
});
235236

237+
it('should properly build input formats based on locale for dateTime data type ', () => {
238+
let result = DateTimeUtil.getDefaultInputFormat('en-US', DataType.DateTime);
239+
expect(result.normalize('NFKC')).toEqual('MM/dd/yyyy, hh:mm:ss tt');
240+
241+
result = DateTimeUtil.getDefaultInputFormat('bg-BG', DataType.DateTime);
242+
expect(result.normalize('NFKC')).toEqual('dd.MM.yyyy г., HH:mm:ss');
243+
244+
result = DateTimeUtil.getDefaultInputFormat('fr-FR', DataType.DateTime);
245+
expect(result).toEqual('dd/MM/yyyy HH:mm:ss');
246+
});
247+
248+
it('should properly build input formats based on locale for time data type ', () => {
249+
let result = DateTimeUtil.getDefaultInputFormat('en-US', DataType.Time);
250+
expect(result.normalize('NFKC')).toEqual('hh:mm tt');
251+
252+
result = DateTimeUtil.getDefaultInputFormat('bg-BG', DataType.Time);
253+
expect(result.normalize('NFKC')).toEqual('HH:mm');
254+
255+
result = DateTimeUtil.getDefaultInputFormat('fr-FR', DataType.Time);
256+
expect(result).toEqual('HH:mm');
257+
});
258+
236259
it('should correctly distinguish date from time characters', () => {
237260
expect(DateTimeUtil.isDateOrTimeChar('d')).toBeTrue();
238261
expect(DateTimeUtil.isDateOrTimeChar('M')).toBeTrue();
@@ -628,4 +651,59 @@ describe(`DateTimeUtil Unit tests`, () => {
628651
expect(DateTimeUtil.isValidDate(false)).toBeFalse();
629652
expect(DateTimeUtil.isValidDate(true)).toBeFalse();
630653
});
654+
655+
it('should correctly identify formats that would resolve to only numeric parts (and period) for the date/time parts', () => {
656+
// test with locale covering non-ASCII characters as well
657+
const locale = 'bg';
658+
659+
const numericFormats = ['y', 'yy', 'yyy', 'yyyy', 'M', 'MM', 'd', 'dd', 'h', 'hh',
660+
'H', 'HH', 'm', 'mm', 's', 'ss', 'S', 'SS', 'SSS',
661+
'dd-MM-yyyy', 'dd/M/yyyy HH:mm:ss tt', 'dd/M/yyyy HH:mm:ss:SS a',
662+
// literals are allowed in the format
663+
'dd/MM/yyyy test hh:mm'
664+
];
665+
numericFormats.forEach(format => {
666+
expect(DateTimeUtil.isFormatNumeric(locale, format)).withContext(`Format: ${format}`).toBeTrue();
667+
});
668+
669+
const nonNumericFormats = ['MMM', 'MMMM', 'MMMMM', 'medium', 'long', 'full', 'mediumDate',
670+
'longDate', 'fullDate', 'longTime', 'fullTime', 'dd-MMM-yyyy', 'E', 'EE'];
671+
672+
nonNumericFormats.forEach(format => {
673+
expect(DateTimeUtil.isFormatNumeric(locale, format)).withContext(`Format: ${format}`).toBeFalse();
674+
});
675+
});
676+
677+
it('getNumericInputFormat should return formats with date parts that the date-time editors can handle', () => {
678+
let locale = 'en-US';
679+
680+
// returns the equivalent of the predefined numeric formats as date parts
681+
// should be transformed as inputFormats for editing (numeric year, 2-digit parts for the rest)
682+
expect(DateTimeUtil.getNumericInputFormat(locale, 'short')).toBe('MM/dd/yyyy, hh:mm tt');
683+
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortDate')).toBe('MM/dd/yyyy');
684+
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortTime').normalize('NFKD')).toBe('hh:mm tt');
685+
expect(DateTimeUtil.getNumericInputFormat(locale, 'mediumTime').normalize('NFKD')).toBe('hh:mm:ss tt');
686+
687+
// handle the predefined formats for different locales
688+
locale = 'bg-BG';
689+
expect(DateTimeUtil.getNumericInputFormat(locale, 'short').normalize('NFKD')).toBe('dd.MM.yyyy г., HH:mm');
690+
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortDate').normalize('NFKD')).toBe('dd.MM.yyyy г.');
691+
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortTime').normalize('NFKD')).toBe('HH:mm');
692+
expect(DateTimeUtil.getNumericInputFormat(locale, 'mediumTime').normalize('NFKD')).toBe('HH:mm:ss');
693+
694+
locale = 'ja-JP';
695+
expect(DateTimeUtil.getNumericInputFormat(locale, 'short')).toBe('yyyy/MM/dd HH:mm');
696+
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortDate')).toBe('yyyy/MM/dd');
697+
expect(DateTimeUtil.getNumericInputFormat(locale, 'shortTime').normalize('NFKD')).toBe('HH:mm');
698+
expect(DateTimeUtil.getNumericInputFormat(locale, 'mediumTime').normalize('NFKD')).toBe('HH:mm:ss');
699+
700+
// returns the same format if it is custom and numeric
701+
expect(DateTimeUtil.getNumericInputFormat(locale, 'dd-MM-yyyy')).toBe('dd-MM-yyyy');
702+
expect(DateTimeUtil.getNumericInputFormat(locale, 'dd/M/yyyy hh:mm:ss:SS aa')).toBe('dd/M/yyyy hh:mm:ss:SS aa');
703+
704+
// returns empty string if predefined and not among the numeric ones
705+
expect(DateTimeUtil.getNumericInputFormat(locale, 'medium')).toBe('');
706+
expect(DateTimeUtil.getNumericInputFormat(locale, 'mediumDate')).toBe('');
707+
expect(DateTimeUtil.getNumericInputFormat(locale, 'longTime')).toBe('');
708+
});
631709
});

0 commit comments

Comments
 (0)