Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add date picker event onValueChanged and use it to update cell value when column type is date #5535

Merged
merged 12 commits into from
Aug 5, 2019
Merged
Show file tree
Hide file tree
Changes from 10 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
18 changes: 12 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes for each version of this project will be documented in this file.

## 8.1.2

### New Features
- `IgxDatePicker`
- `valueChange` event is added.

## 8.1.0

### New Features
Expand All @@ -15,7 +21,7 @@ All notable changes for each version of this project will be documented in this
- **Behavioral Change** - paging now includes the group rows in the page size. You may find more information about the change in the [GroupBy Specification](https://github.com/IgniteUI/igniteui-angular/wiki/Group-By-Specification)
- `IgxColumnGroup`
- Re-templating the column group header is now possible using the `headerTemplate` input property or the `igxHeader` directive.
- `igx-grid-footer`
- `igx-grid-footer`
- You can use this to insert a custom footer in the grids.
```html
<igx-grid>
Expand All @@ -41,21 +47,21 @@ All notable changes for each version of this project will be documented in this

## 8.0.2
- `igx-list-theme` now have some new parameters for styling.
- $item-background-hover - Change The list item hover background
- $item-background-hover - Change The list item hover background
- $item-text-color-hover - Change The list item hover text color.

- $item-subtitle-color - Change The list item subtitle color.
- $item-subtitle-color-hover - Change The list item hover subtitle color.
- $item-subtitle-color-active - Change The active list item subtitle color.

- $item-action-color - Change The list item actions color.
- $item-action-color-hover - Change The list item hover actions color.
- $item-action-color-active - Change The active list item actions color.

- $item-thumbnail-color - Change The list item thumbnail color.
- $item-thumbnail-color-hover - Change The list item hover thumbnail color.
- $item-thumbnail-color-active - Change The active list item thumbnail color.

- **Behavioral Change** default min column width is changed according the grid display density property:
- for `DisplayDensity.comfortable` defaultMinWidth is `80px`;
- for `DisplayDensity.cosy` defaultMinWidth is `64px`;
Expand Down
8 changes: 5 additions & 3 deletions projects/igniteui-angular/src/lib/date-picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ In order to re-template a date picker in `dropdown` mode, you should pass the dr
```html
<igx-date-picker>
<ng-template igxDatePickerTemplate let-openDialog="openDialog" let-value="value" let-displayData="displayData">
<igx-input-group (click)="openDialog(dropDownTarget)" #dropDownTarget>
<igx-input-group (click)="openDialog(dropDownTarget)" #dropDownTarget>
<label igxLabel>Date</label>
<input igxInput [value]="displayData"/>
</igx-input-group>
Expand Down Expand Up @@ -133,10 +133,12 @@ The DatePicker action buttons could be retemplated.
| Name | Return Type | Description |
|:--:|:---|:---|
| `onSelection` | `Date` | Fired when selection is made in the calendar. The event contains the selected value(s) based on the type of selection the component is set to |
| `onOpen` | `datePicker` | Emitted when a datePicker calendar is being opened. |
| `onClose` | `datePicker` | Emitted when a datePicker calendar is being closed. |
| `onOpened` | `datePicker` | Emitted when a datePicker calendar is opened. |
| `onClosed` | `datePicker` | Emitted when a datePicker calendar is closed. |
| `onClosing` | `CancelableBrowserEventArgs` | Emitted when a datePicker calendar is being closed. |
| `onDisabledDate` | `IDatePickerDisabledDateEventArgs` | Emitted when a disabled date is entered in `dropdown` mode. |
| `onValidationFailed` | `IDatePickerValidationFailedEventArgs` | Emitted when an invalid date is entered in `dropdown` mode. |
| `valueChange` | `Date` | Fired when date picker value is changed |

### Methods
| Name | Arguments | Return Type | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ describe('IgxDatePicker', () => {
const dom = fixture.debugElement;
const target = dom.query(By.css('.igx-date-picker__input-date'));

spyOn(datePicker.onOpen, 'emit');
spyOn(datePicker.onClose, 'emit');
spyOn(datePicker.onOpened, 'emit');
spyOn(datePicker.onClosed, 'emit');

UIInteractions.clickElement(target);
fixture.detectChanges();
await wait();

expect(datePicker.onOpen.emit).toHaveBeenCalled();
expect(datePicker.onOpen.emit).toHaveBeenCalledWith(datePicker);
expect(datePicker.onOpened.emit).toHaveBeenCalled();
expect(datePicker.onOpened.emit).toHaveBeenCalledWith(datePicker);

const overlayDiv = document.getElementsByClassName('igx-overlay__wrapper--modal')[0];
expect(overlayDiv).toBeDefined();
Expand All @@ -92,17 +92,20 @@ describe('IgxDatePicker', () => {
fixture.detectChanges();
await wait();

expect(datePicker.onClose.emit).toHaveBeenCalled();
expect(datePicker.onClose.emit).toHaveBeenCalledWith(datePicker);
expect(datePicker.onClosed.emit).toHaveBeenCalled();
expect(datePicker.onClosed.emit).toHaveBeenCalledWith(datePicker);
});

it('Datepicker onSelection event and selectDate method propagation', () => {
it('Datepicker onSelection and valueChange events and selectDate method propagation', () => {
spyOn(datePicker.onSelection, 'emit');
spyOn(datePicker.valueChange, 'emit');
const newDate: Date = new Date(2016, 4, 6);
datePicker.selectDate(newDate);
datePicker.selectDate(newDate);
fixture.detectChanges();

expect(datePicker.onSelection.emit).toHaveBeenCalled();
expect(datePicker.valueChange.emit).toHaveBeenCalled();
expect(datePicker.valueChange.emit).toHaveBeenCalledWith(newDate);
expect(datePicker.value).toBe(newDate);
});

Expand Down Expand Up @@ -611,15 +614,15 @@ describe('IgxDatePicker', () => {
const iconDate = dom.query(By.css('.igx-icon'));
expect(iconDate).not.toBeNull();

spyOn(datePicker.onOpen, 'emit');
spyOn(datePicker.onClose, 'emit');
spyOn(datePicker.onOpened, 'emit');
spyOn(datePicker.onClosed, 'emit');

UIInteractions.clickElement(iconDate);
fixture.detectChanges();
await wait();

expect(datePicker.onOpen.emit).toHaveBeenCalled();
expect(datePicker.onOpen.emit).toHaveBeenCalledWith(datePicker);
expect(datePicker.onOpened.emit).toHaveBeenCalled();
expect(datePicker.onOpened.emit).toHaveBeenCalledWith(datePicker);

const dropDown = document.getElementsByClassName('igx-date-picker--dropdown');
expect(dropDown.length).toBe(1);
Expand All @@ -630,8 +633,8 @@ describe('IgxDatePicker', () => {
fixture.detectChanges();
await wait();

expect(datePicker.onClose.emit).toHaveBeenCalled();
expect(datePicker.onClose.emit).toHaveBeenCalledWith(datePicker);
expect(datePicker.onClosed.emit).toHaveBeenCalled();
expect(datePicker.onClosed.emit).toHaveBeenCalledWith(datePicker);
});

it('Handling keyboard navigation with `space`(open) and `esc`(close) buttons - dropdown mode', fakeAsync(() => {
Expand Down Expand Up @@ -677,13 +680,16 @@ describe('IgxDatePicker', () => {
expect(overlays.length).toEqual(0);
}));

it('Datepicker onSelection event and selectDate method propagation - dropdown mode', () => {
it('Datepicker onSelection and valueChange events and selectDate method propagation - dropdown mode', () => {
spyOn(datePicker.onSelection, 'emit');
spyOn(datePicker.valueChange, 'emit');
const newDate: Date = new Date(2016, 4, 6);
datePicker.selectDate(newDate);
fixture.detectChanges();

expect(datePicker.onSelection.emit).toHaveBeenCalled();
expect(datePicker.valueChange.emit).toHaveBeenCalled();
expect(datePicker.valueChange.emit).toHaveBeenCalledWith(newDate);
expect(datePicker.value).toBe(newDate);

const input = fixture.debugElement.query(By.directive(IgxInputDirective));
Expand Down Expand Up @@ -923,12 +929,15 @@ describe('IgxDatePicker', () => {
}));

it('should reset value on clear button click - dropdown mode', () => {
const input = fixture.debugElement.query(By.directive(IgxInputDirective));
spyOn(datePicker.valueChange, 'emit');
const input = fixture.debugElement.query(By.directive(IgxInputDirective));
const dom = fixture.debugElement;
const clear = dom.queryAll(By.css('.igx-icon'))[1];
UIInteractions.clickElement(clear);
fixture.detectChanges();

expect(datePicker.valueChange.emit).toHaveBeenCalled();
expect(datePicker.valueChange.emit).toHaveBeenCalledWith(null);
expect(datePicker.value).toEqual(null);
expect(input.nativeElement.innerText).toEqual('');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
} from './date-picker.utils';
import { DatePickerDisplayValuePipe, DatePickerInputValuePipe } from './date-picker.pipes';
import { IDatePicker } from './date-picker.common';
import { KEYS, CancelableBrowserEventArgs, isIE } from '../core/utils';
import { KEYS, CancelableBrowserEventArgs, isIE, isEqual } from '../core/utils';
import { IgxDatePickerTemplateDirective, IgxDatePickerActionsDirective } from './date-picker.directives';
import { IgxCalendarContainerComponent } from './calendar-container.component';
import { InteractionMode } from '../core/enums';
Expand Down Expand Up @@ -623,6 +623,20 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
@Output()
public onSelection = new EventEmitter<Date>();

/**
*An @Output property that is fired when date picker value is changed.
*```typescript
*public valueChanged(event){
* alert("Date picker value is changed");
*}
*```
*```html
*<igx-date-picker (valueChange)="valueChanged($event)" mode="dropdown"></igx-date-picker>
*```
*/
@Output()
public valueChange = new EventEmitter<Date>();

/**
*An @Output property that fires when the user types/spins to a disabled date in the date-picker editor.
*```typescript
Expand Down Expand Up @@ -907,7 +921,10 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
* @memberOf {@link IgxDatePickerComponent}
*/
public selectDate(date: Date): void {
const oldValue = this.value;
this.value = date;

this.emitValueChangeEvent(oldValue, this.value );
this.onSelection.emit(date);
this._onChangeCallback(date);
}
Expand All @@ -924,7 +941,9 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
* @memberOf {@link IgxDatePickerComponent}
*/
public deselectDate(): void {
const oldValue = this.value;
this.value = null;
this.emitValueChangeEvent(oldValue, this.value );
if (this.calendar) {
this.calendar.deselectDate();
}
Expand Down Expand Up @@ -1009,8 +1028,10 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
date.setSeconds(this.value.getSeconds());
date.setMilliseconds(this.value.getMilliseconds());
}

const oldValue = this.value;
this.value = date;

this.emitValueChangeEvent(oldValue, this.value );
this.calendar.viewDate = date;
this._onChangeCallback(date);
this.closeCalendar();
Expand Down Expand Up @@ -1128,6 +1149,12 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
}
}

private emitValueChangeEvent(oldValue: Date, newValue: Date) {
if (!isEqual(oldValue, newValue)) {
this.valueChange.emit(newValue);
}
}

private calculateDate(dateString: string, invokedByEvent: string): void {
if (dateString !== '') {
const prevDateValue = this.value;
Expand All @@ -1146,9 +1173,12 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor

if (this.disabledDates === null
|| (this.disabledDates !== null && !isDateInRanges(newValue, this.disabledDates))) {
this.value = newValue;
this.invalidDate = '';
this._onChangeCallback(newValue);
const oldValue = this.value;
this.value = newValue;

this.emitValueChangeEvent(oldValue, this.value );
this.invalidDate = '';
this._onChangeCallback(newValue);
} else {
const args: IDatePickerDisabledDateEventArgs = {
datePicker: this,
Expand Down
4 changes: 2 additions & 2 deletions projects/igniteui-angular/src/lib/grids/cell.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
[igxFocus]="focused" [disableRipple]="true"></igx-checkbox>
</ng-container>
<ng-container *ngIf="column.dataType === 'date'">
<igx-date-picker [style.width.%]="100" [outlet]="grid.outletDirective" mode="dropdown" (onSelection)="editValue = $event"
[locale]="grid.locale" [value]="editValue" [igxFocus]="focused" [labelVisibility]="false">
<igx-date-picker [style.width.%]="100" [outlet]="grid.outletDirective" mode="dropdown"
[locale]="grid.locale" [(value)]="editValue" [igxFocus]="focused" [labelVisibility]="false">
</igx-date-picker>
</ng-container>
</ng-template>
Expand Down
47 changes: 47 additions & 0 deletions projects/igniteui-angular/src/lib/grids/grid/cell.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,53 @@ describe('IgxGrid - Cell component', () => {
expect(cell.value.getTime()).toBe(selectedDate.getTime());
});

it('should be able to change value form date picker input-- date', () => {
const cell = grid.getCellByColumn(0, 'birthday');
const cellDomDate = fixture.debugElement.queryAll(By.css(CELL_CSS_CLASS))[3];
const selectedDate = new Date('04/12/2017');
const editValue = '04/12/2017';

cellDomDate.triggerEventHandler('dblclick', {});
fixture.detectChanges();

expect(cell.editMode).toBe(true);
const datePicker = cellDomDate.query(By.css('igx-date-picker')).componentInstance;
expect(datePicker).toBeDefined();

const editTemplate = cellDomDate.query(By.css('.igx-date-picker__input-date'));
UIInteractions.sendInput(editTemplate, editValue);
fixture.detectChanges();

expect(datePicker.value).toEqual(selectedDate);
UIInteractions.triggerKeyDownEvtUponElem('enter', cellDomDate.nativeElement, true);
fixture.detectChanges();

expect(cell.editMode).toBe(false);
expect(cell.value.getTime()).toEqual(selectedDate.getTime());
});

it('should be able to clear value -- date', () => {
const cell = grid.getCellByColumn(0, 'birthday');
const cellDomDate = fixture.debugElement.queryAll(By.css(CELL_CSS_CLASS))[3];

cellDomDate.triggerEventHandler('dblclick', {});
fixture.detectChanges();

expect(cell.editMode).toBe(true);
const datePicker = cellDomDate.query(By.css('igx-date-picker')).componentInstance;
expect(datePicker).toBeDefined();

const clear = cellDomDate.queryAll(By.css('.igx-icon'))[1];
UIInteractions.clickElement(clear);

expect(datePicker.value).toBeNull();
UIInteractions.triggerKeyDownEvtUponElem('enter', cellDomDate.nativeElement, true);
fixture.detectChanges();

expect(cell.editMode).toBe(false);
expect(cell.value).toBeNull();
});

it('should exit edit mode on filtering', () => {
let cell = grid.getCellByColumn(0, 'fullName');
const cellDom = fixture.debugElement.queryAll(By.css(CELL_CSS_CLASS))[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<igx-checkbox (change)="editValue = $event.checked" [value]="editValue" [checked]="editValue" [disableRipple]="true"></igx-checkbox>
</ng-container>
<ng-container *ngIf="column.dataType === 'date'">
<igx-date-picker [style.width.%]="100" [outlet]="grid.outletDirective" mode="dropdown" (onSelection)="editValue = $event"
[locale]="grid.locale" [value]="editValue" [igxFocus]="focused" [labelVisibility]="false">
<igx-date-picker [style.width.%]="100" [outlet]="grid.outletDirective" mode="dropdown"
[locale]="grid.locale" [(value)]="editValue" [igxFocus]="focused" [labelVisibility]="false">
</igx-date-picker>
</ng-container>
</ng-template>
Expand Down