Skip to content

Commit f2059a2

Browse files
authored
feat(editors): add Clear Date button to Date Editor (#580)
1 parent 0675b31 commit f2059a2

File tree

6 files changed

+392
-312
lines changed

6 files changed

+392
-312
lines changed

src/app/modules/angular-slickgrid/editors/__tests__/dateEditor.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ describe('DateEditor', () => {
205205
editor = new DateEditor(editorArguments);
206206
editor.loadValue(mockItemData);
207207
editor.focus();
208-
const editorInputElm = divContainer.querySelector<HTMLInputElement>('input.flatpickr');
208+
const editorInputElm = divContainer.querySelector<HTMLInputElement>('.flatpickr input');
209209
editorInputElm.value = '2024-04-02T16:02:02.239Z';
210210
editorInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keydown', { keyCode: 13, bubbles: true, cancelable: true }));
211211

@@ -396,7 +396,7 @@ describe('DateEditor', () => {
396396
editor = new DateEditor(editorArguments);
397397
editor.loadValue(mockItemData);
398398
editor.flatInstance.toggle();
399-
const editorInputElm = divContainer.querySelector<HTMLInputElement>('input.flatpickr');
399+
const editorInputElm = divContainer.querySelector<HTMLInputElement>('.flatpickr input');
400400

401401
expect(editor.pickerOptions).toBeTruthy();
402402
expect(editorInputElm.value).toBe('');

src/app/modules/angular-slickgrid/editors/dateEditor.ts

+35-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
import { TranslateService } from '@ngx-translate/core';
2+
import * as moment_ from 'moment-mini';
3+
import { BaseOptions as FlatpickrBaseOptions } from 'flatpickr/dist/types/options';
4+
import * as _flatpickr from 'flatpickr';
5+
import { FlatpickrFn } from 'flatpickr/dist/types/instance';
6+
const flatpickr: FlatpickrFn = _flatpickr as any; // patch for rollup
7+
const moment = moment_; // patch to fix rollup "moment has no default export" issue, document here https://github.com/rollup/rollup/issues/670
8+
29
import { Constants } from './../constants';
310
import { mapFlatpickrDateFormatWithFieldType, mapMomentDateFormatWithFieldType, setDeepValue, getDescendantProperty } from './../services/utilities';
411
import {
@@ -12,8 +19,6 @@ import {
1219
FlatpickrOption,
1320
GridOption,
1421
} from './../models/index';
15-
import * as moment_ from 'moment-mini';
16-
const moment = moment_; // patch to fix rollup "moment has no default export" issue, document here https://github.com/rollup/rollup/issues/670
1722

1823
declare function require(name: string);
1924
require('flatpickr');
@@ -28,6 +33,8 @@ declare const $: any;
2833
export class DateEditor implements Editor {
2934
private _$inputWithData: any;
3035
private _$input: any;
36+
private _$editorInputElm: any;
37+
private _originalDate: string;
3138
private _pickerMergedOptions: FlatpickrOption;
3239

3340
/** The translate library */
@@ -109,6 +116,7 @@ export class DateEditor implements Editor {
109116
altFormat: outputFormat,
110117
dateFormat: inputFormat,
111118
closeOnSelect: true,
119+
wrap: true,
112120
locale: (currentLocale !== 'en') ? this.loadFlatpickrLocale(currentLocale) : 'en',
113121
onChange: () => this.save(),
114122
errorHandler: () => {
@@ -118,14 +126,26 @@ export class DateEditor implements Editor {
118126

119127
// merge options with optional user's custom options
120128
this._pickerMergedOptions = { ...pickerOptions, ...(this.editorOptions as FlatpickrOption) };
121-
const inputCssClasses = `.editor-text.editor-${columnId}.flatpickr`;
129+
const inputCssClasses = `.editor-text.editor-${columnId}.form-control`;
122130
if (this._pickerMergedOptions.altInput) {
123-
this._pickerMergedOptions.altInputClass = 'flatpickr-alt-input editor-text';
131+
this._pickerMergedOptions.altInputClass = 'flatpickr-alt-input form-control';
132+
}
133+
134+
this._$editorInputElm = $(`<div class="flatpickr input-group"></div>`);
135+
const closeButtonElm = $(`<span class="input-group-btn" data-clear>
136+
<button class="btn btn-default icon-close" type="button"></button>
137+
</span>`);
138+
this._$input = $(`<input type="text" data-input data-defaultDate="${this.defaultDate}" class="${inputCssClasses.replace(/\./g, ' ')}" placeholder="${placeholder}" title="${title}" />`);
139+
this._$input.appendTo(this._$editorInputElm);
140+
141+
// show clear date button (unless user specifically doesn't want it)
142+
const isCloseButtonHidden = this.columnEditor && this.columnEditor.params && this.columnEditor.params.hideClearButton || false;
143+
if (!isCloseButtonHidden) {
144+
closeButtonElm.appendTo(this._$editorInputElm);
124145
}
125146

126-
this._$input = $(`<input type="text" data-defaultDate="${this.defaultDate}" class="${inputCssClasses.replace(/\./g, ' ')}" placeholder="${placeholder}" title="${title}" />`);
127-
this._$input.appendTo(this.args.container);
128-
this.flatInstance = (this._$input[0] && typeof this._$input[0].flatpickr === 'function') ? this._$input[0].flatpickr(this._pickerMergedOptions) : null;
147+
this._$editorInputElm.appendTo(this.args.container);
148+
this.flatInstance = (flatpickr && this._$editorInputElm[0] && typeof this._$editorInputElm[0].flatpickr === 'function') ? this._$editorInputElm[0].flatpickr(this._pickerMergedOptions) : flatpickr(this._$editorInputElm, this._pickerMergedOptions as unknown as Partial<FlatpickrBaseOptions>);
129149

130150
// when we're using an alternate input to display data, we'll consider this input as the one to do the focus later on
131151
// else just use the top one
@@ -141,6 +161,9 @@ export class DateEditor implements Editor {
141161
destroy() {
142162
this.hide();
143163
this._$input.remove();
164+
if (this._$editorInputElm && this._$editorInputElm.remove) {
165+
this._$editorInputElm.remove();
166+
}
144167
if (this._$inputWithData && typeof this._$inputWithData.remove === 'function') {
145168
this._$inputWithData.remove();
146169
}
@@ -196,17 +219,18 @@ export class DateEditor implements Editor {
196219
}
197220
}
198221

199-
isValueChanged() {
222+
isValueChanged(): boolean {
200223
const elmValue = this._$input.val();
201224
const inputFormat = mapMomentDateFormatWithFieldType(this.columnEditor.type || (this.columnDef && this.columnDef.type) || FieldType.dateIso);
202225
const outputTypeFormat = mapMomentDateFormatWithFieldType((this.columnDef && (this.columnDef.outputType || this.columnEditor.type || this.columnDef.type)) || FieldType.dateUtc);
203226
const elmDateStr = elmValue ? moment(elmValue, inputFormat, false).format(outputTypeFormat) : '';
204-
const orgDateStr = this.originalDate ? moment(this.originalDate, inputFormat, false).format(outputTypeFormat) : '';
227+
const orgDateStr = this._originalDate ? moment(this._originalDate, inputFormat, false).format(outputTypeFormat) : '';
205228
if (elmDateStr === 'Invalid date' || orgDateStr === 'Invalid date') {
206229
return false;
207230
}
208231

209-
return (!(elmDateStr === '' && orgDateStr === '')) && (elmDateStr !== orgDateStr);
232+
const isChanged = (!(elmDateStr === '' && orgDateStr === '')) && (elmDateStr !== orgDateStr);
233+
return isChanged;
210234
}
211235

212236
loadValue(item: any) {
@@ -217,10 +241,8 @@ export class DateEditor implements Editor {
217241
const isComplexObject = fieldName && fieldName.indexOf('.') > 0;
218242
const value = (isComplexObject) ? getDescendantProperty(item, fieldName) : item[fieldName];
219243

220-
this.originalDate = value;
244+
this._originalDate = value;
221245
this.flatInstance.setDate(value);
222-
this.show();
223-
this.focus();
224246
}
225247
}
226248

0 commit comments

Comments
 (0)