Skip to content

Commit

Permalink
feat(timepicker): Add ability to set readonly/disabled state #3602 (#…
Browse files Browse the repository at this point in the history
…3611)

* feat(timepicker): add validation for timepicker

Add validation for timepicker based on ui-bootstrap validation.
Fix min-max validation issue.

close #3549 #3288

* feat(timepicker): Add ability to set readonly/disabled state #3602

Add ability to set readonly/disabled state
Add disabled demo
Fix bud related to highlight input in readonly mood
Extend test for timepicker

Close #3602 #3371
  • Loading branch information
IraErshova authored and valorkin committed Mar 1, 2018
1 parent 8182d92 commit 4e5f828
Show file tree
Hide file tree
Showing 16 changed files with 654 additions and 196 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
<timepicker [(ngModel)]="mytime" [showMeridian]="ismeridian" [readonlyInput]="!isEnabled"></timepicker>
<timepicker [(ngModel)]="myTime" [showMeridian]="isMeridian" [disabled]="!isDisabled"></timepicker>
<hr>

<button type="button" class="btn btn-info" (click)="isEnabled=!isEnabled">Enable / Disable input</button>

<button type="button" class="btn btn-info" (click)="isDisabled=!isDisabled">Enable / Disable input</button>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Component } from '@angular/core';
templateUrl: './disabled.html'
})
export class DemoTimepickerDisabledComponent {
ismeridian: boolean = false;
isEnabled: boolean = true;
mytime: Date = new Date();
isMeridian = true;
isDisabled = true;
myTime = new Date();
}
2 changes: 2 additions & 0 deletions demo/src/app/components/+timepicker/demos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { DemoTimepickerMousewheelComponent } from './mousewheel/mousewheel';
import { DemoTimepickerCustomValidationComponent } from './custom-validation/custom-validation';
import { DemoTimepickerIsValidComponent } from './isvalid/isvalid';
import { DemoTimepickerSpinnersComponent } from './spinners/spinners';
import { DemoTimepickerReadonlyComponent } from './readonly/readonly';

export const DEMO_COMPONENTS = [
DemoTimepickerBasicComponent,
Expand All @@ -20,6 +21,7 @@ export const DEMO_COMPONENTS = [
DemoTimepickerCustomMeridianComponent,
DemoTimepickerMinMaxComponent,
DemoTimepickerDisabledComponent,
DemoTimepickerReadonlyComponent,
DemoTimepickerCustomComponent,
DemoTimepickerDynamicComponent,
DemoTimepickerToggleMinutesSecondsComponent,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<timepicker [(ngModel)]="myTime" [showMeridian]="isMeridian" [readonlyInput]="!readonly"></timepicker>
<hr>
<button type="button" class="btn btn-info" (click)="readonly=!readonly">Editable / Readonly input</button>
11 changes: 11 additions & 0 deletions demo/src/app/components/+timepicker/demos/readonly/readonly.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Component } from '@angular/core';

@Component({
selector: 'demo-timepicker-readonly',
templateUrl: './readonly.html'
})
export class DemoTimepickerReadonlyComponent {
isMeridian = false;
readonly = true;
myTime = new Date();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { DemoTimepickerDynamicComponent } from './demos/dynamic/dynamic';
import { DemoTimepickerMousewheelComponent } from './demos/mousewheel/mousewheel';
import { DemoTimepickerArrowkeysComponent } from './demos/arrowkeys/arrowkeys';
import { DemoTimepickerConfigComponent } from './demos/config/config';
import { DemoTimepickerReadonlyComponent } from './demos/readonly/readonly';
import { DemoTimepickerSpinnersComponent } from './demos/spinners/spinners';

import { ContentSection } from '../../docs/models/content-section.model';
Expand Down Expand Up @@ -79,6 +80,13 @@ export const demoComponentContent: ContentSection[] = [
html: require('!!raw-loader?lang=markup!./demos/disabled/disabled.html'),
outlet: DemoTimepickerDisabledComponent
},
{
title: 'Readonly',
anchor: 'readonly',
component: require('!!raw-loader?lang=typescript!./demos/readonly/readonly'),
html: require('!!raw-loader?lang=markup!./demos/readonly/readonly.html'),
outlet: DemoTimepickerReadonlyComponent
},
{
title: 'Custom steps',
anchor: 'custom',
Expand Down
217 changes: 145 additions & 72 deletions src/spec/timepicker/timepicker-controls.util.spec.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import { TimeChangeEvent, TimepickerComponentState, TimepickerControls } from '../../timepicker/timepicker.models';
import {
canChangeValue,
canChangeHours,
canChangeMinutes,
canChangeSeconds,
canChangeValue,
getControlsValue,
timepickerControls
} from '../../timepicker/timepicker-controls.util';
import { TimeChangeEvent, TimepickerComponentState, TimepickerControls } from '../../timepicker/timepicker.models';

function testTime(hours?: number, minutes?: number, seconds?: number) {
const time = new Date();
time.setHours(hours || 0);
time.setMinutes(minutes || 0);
time.setSeconds(seconds || 0);

return time;
}

describe('Runtime coverage. Util: Timepicker-controls', () => {
describe('Util: Timepicker-controls', () => {
let state: TimepickerComponentState;
let controls: TimepickerControls;
let event: TimeChangeEvent;
Expand All @@ -29,6 +30,7 @@ describe('Runtime coverage. Util: Timepicker-controls', () => {
minuteStep: 5,
secondsStep: 10,
readonlyInput: false,
disabled: false,
mousewheel: true,
arrowkeys: true,
showSpinners: true,
Expand All @@ -38,12 +40,13 @@ describe('Runtime coverage. Util: Timepicker-controls', () => {
};

controls = {
canIncrementHours: false,
canIncrementMinutes: false,
canIncrementSeconds: false,
canDecrementHours: false,
canDecrementMinutes: false,
canDecrementSeconds: false
canIncrementHours: true,
canIncrementMinutes: true,
canIncrementSeconds: true,
canDecrementHours: true,
canDecrementMinutes: true,
canDecrementSeconds: true,
canToggleMeridian: true
};

event = {
Expand All @@ -52,123 +55,193 @@ describe('Runtime coverage. Util: Timepicker-controls', () => {
};
});

it('should can change value read only', () => {
canChangeValue(state, event);

it('canChangeValue method should return false if readonlyInput is true', () => {
state.readonlyInput = true;
canChangeValue(state, event);

const result = canChangeValue(state, event);

expect(result).toEqual(false);
});

it('should can change value event', () => {
canChangeValue(state);
canChangeValue(state, event);
it('canChangeValue method should return false if disabled is true', () => {
state.disabled = true;

const result = canChangeValue(state, event);

expect(result).toEqual(false);
});

it('should can change value event source and wheel', () => {
it('canChangeValue method should return false if source is wheel and no mousewheel', () => {
event.source = 'wheel';
state.mousewheel = false;

canChangeValue(state, event);
const result = canChangeValue(state, event);

expect(result).toEqual(false);
});

it('should can change value event source and key', () => {
it('canChangeValue method should return false if source is key and no arrowkeys', () => {
event.source = 'key';
state.arrowkeys = false;

canChangeValue(state, event);
const result = canChangeValue(state, event);

expect(result).toEqual(false);
});

it('canChangeValue method should return true if readonlyInput is false and event is empty', () => {
const result = canChangeValue(state, event);

expect(result).toEqual(true);
});

it('should change Hours', () => {
canChangeHours(event, controls);
it('canChangeValue method should return true if readonlyInput is false and no event', () => {
const result = canChangeValue(state);

expect(result).toEqual(true);
});

it('should change Hours no step', () => {
it('canChangeHours method should validate ability to change Hours and return true', () => {
const result = canChangeHours(event, controls);

expect(result).toEqual(true);
});

it('canChangeHours method should validate and return false if no step', () => {
event.step = null;
canChangeHours(event, controls);

const result = canChangeHours(event, controls);

expect(result).toEqual(false);
});

it('should change Hours step is -1', () => {
event.step = -1;
canChangeHours(event, controls);
it('canChangeHours method should validate and return false if canIncrementHours is false', () => {
controls.canIncrementHours = false;

const result = canChangeHours(event, controls);

expect(result).toEqual(false);
});

it('should change Hours can increment', () => {
controls.canIncrementHours = true;
canChangeHours(event, controls);
it('canChangeHours method should validate and return false if step < 0 and canDecrementHours is false', () => {
controls.canDecrementHours = false;
event.step = -2;

const result = canChangeHours(event, controls);

expect(result).toEqual(false);
});

it('should change Minutes', () => {
canChangeMinutes(event, controls);
it('canChangeMinutes method should validate ability to change Minutes and return true', () => {
const result = canChangeMinutes(event, controls);

expect(result).toEqual(true);
});

it('should change Minutes no step', () => {
it('canChangeMinutes method should validate and return false if no step', () => {
event.step = null;
canChangeMinutes(event, controls);

const result = canChangeMinutes(event, controls);

expect(result).toEqual(false);
});

it('should change Minutes step is -1', () => {
event.step = -1;
canChangeMinutes(event, controls);
it('canChangeMinutes method should validate and return false if canIncrementMinutes is false', () => {
controls.canIncrementMinutes = false;

const result = canChangeMinutes(event, controls);

expect(result).toEqual(false);
});

it('should change Minutes can increment', () => {
controls.canIncrementMinutes = true;
canChangeMinutes(event, controls);
it('canChangeMinutes method should validate and return false if step < 0 and canDecrementMinutes is false', () => {
controls.canDecrementMinutes = false;
event.step = -2;

const result = canChangeMinutes(event, controls);

expect(result).toEqual(false);
});

it('should change Seconds', () => {
canChangeSeconds(event, controls);
it('canChangeSeconds method should validate ability to change Seconds and return true', () => {
const result = canChangeSeconds(event, controls);

expect(result).toEqual(true);
});

it('should change Seconds no step', () => {
it('canChangeSeconds method should validate and return false if no step', () => {
event.step = null;
canChangeSeconds(event, controls);

const result = canChangeSeconds(event, controls);

expect(result).toEqual(false);
});

it('should change Seconds step is -1', () => {
event.step = -1;
canChangeSeconds(event, controls);
it('canChangeSeconds method should validate and return false if canIncrementSeconds is false', () => {
controls.canIncrementSeconds = false;

const result = canChangeSeconds(event, controls);

expect(result).toEqual(false);
});

it('should change Seconds can increment', () => {
controls.canIncrementSeconds = true;
canChangeSeconds(event, controls);
it('canChangeSeconds method should validate and return false if step < 0 and canDecrementSeconds is false', () => {
controls.canDecrementSeconds = false;
event.step = -2;

const result = canChangeSeconds(event, controls);

expect(result).toEqual(false);
});

it('should get controls value', () => {
getControlsValue(state);
it('getControlsValue method should return TimepickerComponentState', () => {
const result = getControlsValue(state);

expect(result).toEqual(state);
});

it('should set data in timepicker controls', () => {
timepickerControls(new Date(), state);
it('timepickerControls method should return default data if no value', () => {
const result = timepickerControls(null, state);

expect(result).toEqual(controls);
});

it('should set data in timepicker controls without date', () => {
// unreachable code
it('timepickerControls method should change canIncrementHours to true', () => {
state.max = testTime(14);

const result = timepickerControls(testTime(11), state);

expect(result.canIncrementHours).toEqual(true);
expect(result.canToggleMeridian).toEqual(false);
});

it('should set data in timepicker controls without showSeconds', () => {
it('timepickerControls method should change canIncrementHours to false', () => {
state.max = testTime(14);
state.showSeconds = true;
timepickerControls(new Date(), state);
});

it('should set data in timepicker controls with max', () => {
state.max = new Date();
timepickerControls(new Date(), state);
});
const result = timepickerControls(testTime(17), state);

it('should set data in timepicker controls with max greater to control time', () => {
state.max = testTime(1);
timepickerControls(testTime(), state);
expect(result.canIncrementHours).toEqual(false);
expect(result.canIncrementMinutes).toEqual(false);
});

it('should set data in timepicker controls with min', () => {
state.min = new Date();
timepickerControls(new Date(), state);
it('timepickerControls method should change canDecrementHours to true', () => {
state.min = testTime(10);

const result = timepickerControls(testTime(13), state);

expect(result.canDecrementHours).toEqual(true);
expect(result.canToggleMeridian).toEqual(false);
});

it('should set data in timepicker controls with min greater to control time', () => {
state.min = testTime(1);
timepickerControls(testTime(), state);
it('timepickerControls method should change canIncrementHours to false', () => {
state.min = testTime(10);
state.showSeconds = true;

const result = timepickerControls(testTime(9), state);

expect(result.canDecrementHours).toEqual(false);
expect(result.canDecrementMinutes).toEqual(false);

});
});
Loading

0 comments on commit 4e5f828

Please sign in to comment.